Initial implementation of Options Sidekick

Full-stack iOS options trading assistant:
- Python FastAPI backend with SQLite, APScheduler (15-min position monitor),
  APNs push notifications, and yfinance market data integration
- Signal engine: IV Rank (rolling HV proxy), SMA-50/200, swing-based
  support/resistance, earnings detection, signal strength scoring and
  noise-resistant SHA hash for change detection
- Recommendation engine: covered call and cash-secured put strike/expiry
  selection across 0DTE, 1DTE, weekly, and monthly horizons
- REST API: /devices, /portfolio, /recommendations, /positions, /signals, /alerts
- iOS SwiftUI app (iOS 17+): dashboard, recommendations, trades, portfolio,
  and alerts tabs with push notification deep-linking
- Unit + integration tests for signal engine and API layer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-09 14:38:25 -04:00
commit b7d4e900cc
61 changed files with 4953 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.db_models import Device
from app.models.schemas import DeviceRegister, DeviceResponse
router = APIRouter(prefix="/devices", tags=["devices"])
@router.post("/register", response_model=DeviceResponse)
def register_device(body: DeviceRegister, db: Session = Depends(get_db)):
"""Register or refresh an APNs device token."""
device = db.query(Device).filter(Device.apns_token == body.apns_token).first()
if device:
device.device_name = body.device_name or device.device_name
device.last_seen = datetime.utcnow()
else:
device = Device(
apns_token=body.apns_token,
device_name=body.device_name,
)
db.add(device)
db.commit()
db.refresh(device)
return device