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>
39 lines
965 B
Python
39 lines
965 B
Python
"""
|
|
scheduler.py — APScheduler configuration.
|
|
|
|
The scheduler is started in main.py's lifespan event.
|
|
"""
|
|
|
|
import asyncio
|
|
import logging
|
|
|
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
|
from apscheduler.triggers.interval import IntervalTrigger
|
|
|
|
from app.config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
scheduler = AsyncIOScheduler()
|
|
|
|
|
|
def start_scheduler():
|
|
from app.services.position_monitor import monitor_all_positions
|
|
|
|
scheduler.add_job(
|
|
monitor_all_positions,
|
|
trigger=IntervalTrigger(seconds=settings.monitor_interval_seconds),
|
|
id="position_monitor",
|
|
name="Position Monitor",
|
|
replace_existing=True,
|
|
misfire_grace_time=60,
|
|
)
|
|
scheduler.start()
|
|
logger.info(f"Scheduler started — monitor interval: {settings.monitor_interval_seconds}s")
|
|
|
|
|
|
def stop_scheduler():
|
|
if scheduler.running:
|
|
scheduler.shutdown(wait=False)
|
|
logger.info("Scheduler stopped")
|