- Complete MVP for tracking Fidelity brokerage account performance - Transaction import from CSV with deduplication - Automatic FIFO position tracking with options support - Real-time P&L calculations with market data caching - Dashboard with timeframe filtering (30/90/180 days, 1 year, YTD, all time) - Docker-based deployment with PostgreSQL backend - React/TypeScript frontend with TailwindCSS - FastAPI backend with SQLAlchemy ORM Features: - Multi-account support - Import via CSV upload or filesystem - Open and closed position tracking - Balance history charting - Performance analytics and metrics - Top trades analysis - Responsive UI design Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
66 lines
1.9 KiB
Python
66 lines
1.9 KiB
Python
"""Transaction deduplication utilities."""
|
|
import hashlib
|
|
from datetime import date
|
|
from decimal import Decimal
|
|
from typing import Optional
|
|
|
|
|
|
def generate_transaction_hash(
|
|
account_id: int,
|
|
run_date: date,
|
|
symbol: Optional[str],
|
|
action: str,
|
|
amount: Optional[Decimal],
|
|
quantity: Optional[Decimal],
|
|
price: Optional[Decimal],
|
|
) -> str:
|
|
"""
|
|
Generate a unique SHA-256 hash for a transaction to prevent duplicates.
|
|
|
|
The hash is generated from key transaction attributes that uniquely identify
|
|
a transaction: account, date, symbol, action, amount, quantity, and price.
|
|
|
|
Args:
|
|
account_id: Account identifier
|
|
run_date: Transaction date
|
|
symbol: Trading symbol
|
|
action: Transaction action description
|
|
amount: Transaction amount
|
|
quantity: Number of shares/contracts
|
|
price: Price per unit
|
|
|
|
Returns:
|
|
str: 64-character hexadecimal SHA-256 hash
|
|
|
|
Example:
|
|
>>> generate_transaction_hash(
|
|
... account_id=1,
|
|
... run_date=date(2025, 12, 26),
|
|
... symbol="AAPL",
|
|
... action="YOU BOUGHT",
|
|
... amount=Decimal("-1500.00"),
|
|
... quantity=Decimal("10"),
|
|
... price=Decimal("150.00")
|
|
... )
|
|
'a1b2c3d4...'
|
|
"""
|
|
# Convert values to strings, handling None values
|
|
symbol_str = symbol or ""
|
|
amount_str = str(amount) if amount is not None else ""
|
|
quantity_str = str(quantity) if quantity is not None else ""
|
|
price_str = str(price) if price is not None else ""
|
|
|
|
# Create hash string with pipe delimiter
|
|
hash_string = (
|
|
f"{account_id}|"
|
|
f"{run_date.isoformat()}|"
|
|
f"{symbol_str}|"
|
|
f"{action}|"
|
|
f"{amount_str}|"
|
|
f"{quantity_str}|"
|
|
f"{price_str}"
|
|
)
|
|
|
|
# Generate SHA-256 hash
|
|
return hashlib.sha256(hash_string.encode("utf-8")).hexdigest()
|