summaryrefslogtreecommitdiff
path: root/shared/src
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 14:14:36 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2026-04-02 14:14:36 +0900
commit6909bc142912177d76b295c5d21507229ed6e2c0 (patch)
tree2fdc702befc8089540820e4059290c8be58c7282 /shared/src
parentfe909855ca125d289fab09ae611d23f2bf34ce21 (diff)
feat: add Telegram notification for stock selections
Diffstat (limited to 'shared/src')
-rw-r--r--shared/src/shared/notifier.py30
1 files changed, 30 insertions, 0 deletions
diff --git a/shared/src/shared/notifier.py b/shared/src/shared/notifier.py
index f03919c..9630a18 100644
--- a/shared/src/shared/notifier.py
+++ b/shared/src/shared/notifier.py
@@ -8,6 +8,7 @@ from typing import Optional, Sequence
import aiohttp
from shared.models import Signal, Order, Position
+from shared.sentiment_models import SelectedStock, MarketSentiment
logger = logging.getLogger(__name__)
@@ -123,6 +124,35 @@ class TelegramNotifier:
lines.append(" No open positions")
await self.send("\n".join(lines))
+ async def send_stock_selection(
+ self,
+ selections: list[SelectedStock],
+ market: MarketSentiment | None = None,
+ ) -> None:
+ """Format and send stock selection notification."""
+ lines = [f"<b>📊 Stock Selection ({len(selections)} picks)</b>", ""]
+
+ side_emoji = {"BUY": "🟢", "SELL": "🔴"}
+
+ for i, s in enumerate(selections, 1):
+ emoji = side_emoji.get(s.side.value, "⚪")
+ lines.append(
+ f"{i}. <b>{s.symbol}</b> {emoji} {s.side.value} "
+ f"(conviction: {s.conviction:.0%})"
+ )
+ lines.append(f" {s.reason}")
+ if s.key_news:
+ lines.append(f" News: {s.key_news[0]}")
+ lines.append("")
+
+ if market:
+ lines.append(
+ f"Market: F&amp;G {market.fear_greed} ({market.fear_greed_label})"
+ + (f" | VIX {market.vix:.1f}" if market.vix else "")
+ )
+
+ await self.send("\n".join(lines))
+
async def close(self) -> None:
"""Close the underlying aiohttp session."""
if self._session is not None: