Files
2026-05-26 11:04:27 -04:00

64 lines
2.5 KiB
Python

from __future__ import annotations
from PyQt6.QtCore import QThread, pyqtSignal
from core.market_data import get_quote
from utils.notifications import send_toast
class AlertWorker(QThread):
alert_triggered = pyqtSignal(str, str, str) # symbol, type, message
check_complete = pyqtSignal()
def __init__(self, interval_seconds: int = 300):
super().__init__()
self._interval = interval_seconds
self._running = False
def run(self):
self._running = True
while self._running:
self._check_alerts()
self.check_complete.emit()
for _ in range(self._interval * 10):
if not self._running:
return
self.msleep(100)
def stop(self):
self._running = False
def _check_alerts(self):
from db.database import get_session
from db.models import Alert
from datetime import datetime
with get_session() as session:
active = session.query(Alert).filter_by(is_active=True).all()
for alert in active:
try:
quote = get_quote(alert.symbol, force=True)
price = quote.get("price", 0.0)
volume = quote.get("volume", 0)
triggered = False
message = ""
if alert.alert_type == "price_above" and price >= alert.target_value:
triggered = True
message = f"{alert.symbol} hit ${price:.2f} (above ${alert.target_value:.2f})"
elif alert.alert_type == "price_below" and price <= alert.target_value:
triggered = True
message = f"{alert.symbol} hit ${price:.2f} (below ${alert.target_value:.2f})"
elif alert.alert_type == "volume_spike":
avg_vol = quote.get("avg_volume") or (volume / 1.5)
if avg_vol and volume >= avg_vol * alert.target_value:
triggered = True
message = f"{alert.symbol} volume spike: {volume:,} ({alert.target_value:.1f}x avg)"
if triggered:
alert.is_active = False
alert.triggered_at = datetime.utcnow()
session.commit()
send_toast("StockMind Alert", message)
self.alert_triggered.emit(alert.symbol, alert.alert_type, message)
except Exception:
continue