Documentation
¶
Overview ¶
Package algorithms provides analytical and processing algorithms for LunchMoney transactions.
This package includes the following modules:
Anomaly Detection (anomaly.go) ¶
DetectAnomalies identifies unusual transactions using statistical methods:
- Z-score detection: Flags transactions > 2.5 standard deviations from mean
- IQR detection: Identifies outliers using Interquartile Range
- New merchant detection: First-time merchant transactions
- Duplicate detection: Similar transactions within a time window
- Large transactions: Amounts exceeding a threshold
Example:
options := algorithms.DefaultAnomalyOptions()
anomalies := algorithms.DetectAnomalies(transactions, options)
for _, anomaly := range anomalies {
fmt.Printf("Anomaly: %s - %s (confidence: %.2f)\n",
anomaly.Type, anomaly.Reason, anomaly.Confidence)
}
Merchant Normalization (normalize.go) ¶
NormalizeMerchant canonicalizes merchant names for consistent comparison:
- Strips common suffixes (Inc, LLC, Corp, store numbers)
- Maps known variations (AMZN→Amazon, WM→Walmart)
- Removes payment processor prefixes (TST*, SQ*, PP*)
- Uses Levenshtein distance for fuzzy matching
Example:
normalized := algorithms.NormalizeMerchant("TST* STARBUCKS #1234")
// Returns: "STARBUCKS"
similar := algorithms.FindSimilarMerchants("STARBUCKS", knownMerchants, 3)
// Returns merchants with edit distance ≤ 3
Category Suggestions (categorize.go) ¶
SuggestCategory recommends categories based on historical patterns:
- Exact merchant match (highest confidence)
- Normalized merchant match
- Fuzzy match with Levenshtein distance ≤ 3
- Partial text matching in payee
Example:
suggestion := algorithms.SuggestCategory(transaction, history, categories)
if suggestion.CategoryID != 0 {
fmt.Printf("Suggested: %s (confidence: %.2f)\n",
suggestion.CategoryName, suggestion.Confidence)
}
Spending Trends (trends.go) ¶
Analyzes spending patterns over time:
- MovingAverage: Smooths spending data
- CalculateBudgetPace: Tracks budget spending rate
- CompareSpending: Compares spending between periods
- Daily/Weekly/Monthly aggregations
Example:
result := algorithms.CalculateBudgetPace(spent, budget, daysElapsed, daysInMonth)
fmt.Printf("Status: %s, Projected: $%.2f\n",
result.Status, result.ProjectedEnd)
comparison := algorithms.CompareSpending(currentTxs, previousTxs)
fmt.Printf("Change: %.2f%%\n", comparison.PercentChange)
Duplicate Detection (dedup.go) ¶
Identifies potential duplicate transactions:
- Same normalized merchant
- Amount within ±$0.50 or ±1%
- Date within 3 days (configurable)
- Confidence scoring based on multiple factors
Example:
duplicates := algorithms.DetectPossibleDuplicates(transactions)
for _, dup := range duplicates {
fmt.Printf("Possible duplicate: %s - %s (confidence: %.2f)\n",
dup.Transaction1.Payee, dup.Reason, dup.Confidence)
}
groups := algorithms.FindDuplicateGroups(transactions)
// Returns groups of connected duplicates
Dependencies ¶
This package requires:
- gonum.org/v1/gonum/stat: Statistical calculations
- github.com/agnivade/levenshtein: String similarity
Index ¶
- func CalculateSpendingByCategory(transactions []api.Transaction) map[string]float64
- func CalculateSpendingByMerchant(transactions []api.Transaction) map[string]float64
- func DetectSpendingTrend(points []TrendPoint) string
- func ExtractMerchantCore(name string) string
- func FindDuplicateGroups(transactions []api.Transaction) [][]api.Transaction
- func FindSimilarMerchants(name string, known []string, threshold int) []string
- func GetCategoryStats(history []api.Transaction) map[int]CategoryStats
- func GetPercentile(amounts []float64, percentile float64) float64
- func GroupSimilarMerchants(merchants []string, threshold int) map[string][]string
- func MerchantSimilarity(name1, name2 string) float64
- func MovingAverage(amounts []float64, window int) []float64
- func NormalizeMerchant(name string) string
- func SuggestCategoryBatch(transactions []api.Transaction, history []api.Transaction, ...) map[int]CategorySuggestion
- type Anomaly
- type AnomalyOptions
- type AnomalyType
- type BudgetPaceResult
- type BudgetPaceStatus
- type CategoryStats
- type CategorySuggestion
- type ComparisonResult
- type DedupOptions
- type DuplicateCandidate
- type DuplicateStats
- type MatchType
- type TrendPoint
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CalculateSpendingByCategory ¶
func CalculateSpendingByCategory(transactions []api.Transaction) map[string]float64
CalculateSpendingByCategory calculates spending totals by category
func CalculateSpendingByMerchant ¶
func CalculateSpendingByMerchant(transactions []api.Transaction) map[string]float64
CalculateSpendingByMerchant calculates spending totals by merchant
func DetectSpendingTrend ¶
func DetectSpendingTrend(points []TrendPoint) string
DetectSpendingTrend analyzes if spending is increasing, decreasing, or stable
func ExtractMerchantCore ¶
ExtractMerchantCore attempts to extract the core merchant name by removing common noise words and patterns
func FindDuplicateGroups ¶
func FindDuplicateGroups(transactions []api.Transaction) [][]api.Transaction
FindDuplicateGroups groups transactions that are likely duplicates of each other
func FindSimilarMerchants ¶
FindSimilarMerchants finds merchants similar to the given name using Levenshtein distance threshold is the maximum edit distance to consider similar (recommended: 3)
func GetCategoryStats ¶
func GetCategoryStats(history []api.Transaction) map[int]CategoryStats
GetCategoryStats returns statistics about category usage in history
func GetPercentile ¶
GetPercentile calculates the percentile value from a set of amounts
func GroupSimilarMerchants ¶
GroupSimilarMerchants groups merchants by similarity Returns a map where keys are canonical names and values are lists of similar variants
func MerchantSimilarity ¶
MerchantSimilarity calculates similarity score between two merchant names Returns a score from 0.0 (completely different) to 1.0 (identical)
func MovingAverage ¶
MovingAverage calculates the moving average of a series of amounts
func NormalizeMerchant ¶
NormalizeMerchant canonicalizes a merchant name for comparison
func SuggestCategoryBatch ¶
func SuggestCategoryBatch(transactions []api.Transaction, history []api.Transaction, categories []api.Category) map[int]CategorySuggestion
SuggestCategoryBatch suggests categories for multiple transactions
Types ¶
type Anomaly ¶
type Anomaly struct {
Transaction api.Transaction
Type AnomalyType
Confidence float64 // 0.0 to 1.0
Reason string
}
Anomaly represents a detected anomaly in a transaction
func DetectAnomalies ¶
func DetectAnomalies(transactions []api.Transaction, options AnomalyOptions) []Anomaly
DetectAnomalies identifies anomalies in a set of transactions
type AnomalyOptions ¶
type AnomalyOptions struct {
ZScoreThreshold float64 // Default: 2.5
IQRMultiplier float64 // Default: 1.5
LargeTransactionMin float64 // Default: 500.0
DuplicateWindowDays int // Default: 3
DuplicateAmountDelta float64 // Default: 0.50
EnableZScore bool // Default: true
EnableIQR bool // Default: true
EnableNewMerchant bool // Default: true
EnableDuplicate bool // Default: true
EnableLargeTransaction bool // Default: true
}
AnomalyOptions configures anomaly detection parameters
func DefaultAnomalyOptions ¶
func DefaultAnomalyOptions() AnomalyOptions
DefaultAnomalyOptions returns default options for anomaly detection
type AnomalyType ¶
type AnomalyType string
AnomalyType represents the type of anomaly detected
const ( AnomalyUnusualAmount AnomalyType = "unusual_amount" AnomalyNewMerchant AnomalyType = "new_merchant" AnomalyDuplicatePossible AnomalyType = "duplicate_possible" AnomalyUnusualTiming AnomalyType = "unusual_timing" AnomalyLargeTransaction AnomalyType = "large_transaction" )
type BudgetPaceResult ¶
type BudgetPaceResult struct {
Status BudgetPaceStatus
ProjectedEnd float64 // Projected spending by end of month
DailyRate float64 // Current daily spending rate
DaysRemaining int
PercentSpent float64
PercentElapsed float64
OnTrackAmount float64 // Amount that should be spent by now if on track
}
BudgetPaceResult contains budget pacing analysis
func CalculateBudgetPace ¶
func CalculateBudgetPace(spent, budget float64, daysElapsed, daysInMonth int) BudgetPaceResult
CalculateBudgetPace analyzes budget pacing for the current month
type BudgetPaceStatus ¶
type BudgetPaceStatus string
BudgetPaceStatus represents the budget pacing status
const ( BudgetUnderBudget BudgetPaceStatus = "under_budget" BudgetOnTrack BudgetPaceStatus = "on_track" BudgetOverBudget BudgetPaceStatus = "over_budget" )
type CategoryStats ¶
CategoryStats holds statistics about a category
type CategorySuggestion ¶
type CategorySuggestion struct {
CategoryID int
CategoryName string
Confidence float64 // 0.0 to 1.0
Reason string
}
CategorySuggestion represents a suggested category for a transaction
func SuggestCategory ¶
func SuggestCategory(tx api.Transaction, history []api.Transaction, categories []api.Category) CategorySuggestion
SuggestCategory suggests a category for a transaction based on historical data
type ComparisonResult ¶
type ComparisonResult struct {
CurrentTotal float64
PreviousTotal float64
Difference float64
PercentChange float64
CurrentCount int
PreviousCount int
AverageCurrent float64
AveragePrevious float64
}
ComparisonResult contains spending comparison data
func CompareSpending ¶
func CompareSpending(current, previous []api.Transaction) ComparisonResult
CompareSpending compares spending between two time periods
type DedupOptions ¶
type DedupOptions struct {
MaxDaysDiff int // Maximum days between transactions (default: 3)
AmountDeltaAbsolute float64 // Absolute amount difference tolerance (default: 0.50)
AmountDeltaPercent float64 // Percentage amount difference tolerance (default: 0.01 = 1%)
RequireExactAmount bool // If true, amounts must match exactly (default: false)
RequireSameCategory bool // If true, categories must match (default: false)
MinConfidence float64 // Minimum confidence to report (default: 0.5)
}
DedupOptions configures duplicate detection parameters
func DefaultDedupOptions ¶
func DefaultDedupOptions() DedupOptions
DefaultDedupOptions returns default options for duplicate detection
type DuplicateCandidate ¶
type DuplicateCandidate struct {
Transaction1 api.Transaction
Transaction2 api.Transaction
Confidence float64 // 0.0 to 1.0
Reason string
}
DuplicateCandidate represents a pair of potentially duplicate transactions
func DetectPossibleDuplicates ¶
func DetectPossibleDuplicates(transactions []api.Transaction) []DuplicateCandidate
DetectPossibleDuplicates identifies potential duplicate transactions
func DetectPossibleDuplicatesWithOptions ¶
func DetectPossibleDuplicatesWithOptions(transactions []api.Transaction, options DedupOptions) []DuplicateCandidate
DetectPossibleDuplicatesWithOptions identifies duplicates with custom options
type DuplicateStats ¶
type DuplicateStats struct {
TotalCandidates int
HighConfidence int
MediumConfidence int
LowConfidence int
PotentialSavings float64
}
DuplicateStats holds statistics about duplicate detection
func GetDuplicateStats ¶
func GetDuplicateStats(candidates []DuplicateCandidate) DuplicateStats
GetDuplicateStats returns statistics about duplicates
type TrendPoint ¶
TrendPoint represents a point in a trend analysis
func CalculateDailySpending ¶
func CalculateDailySpending(transactions []api.Transaction) []TrendPoint
CalculateDailySpending calculates daily spending totals from transactions
func CalculateMonthlySpending ¶
func CalculateMonthlySpending(transactions []api.Transaction) []TrendPoint
CalculateMonthlySpending calculates monthly spending totals from transactions
func CalculateWeeklySpending ¶
func CalculateWeeklySpending(transactions []api.Transaction) []TrendPoint
CalculateWeeklySpending calculates weekly spending totals from transactions