Collect new trading signals from Telegram channels you’re subscribed to. Uses Pyrogram to receive channel messages, LangChain + OpenAI to classify/parse, and SQLAlchemy to persist to SQLite.
- No history scraping; only new messages as they arrive.
- LLM classification + structured parsing (Pydantic model).
- Minimal valid signal:
symbol,side. - JSON arrays for
take_profits/stop_loss. - API endpoints (FastAPI) + lightweight React viewer.
- Fill
.env(see.env.example) withAPI_IDandAPI_HASH. - Run:
Follow the interactive login. A session file is created at
python -m app.login
$.pyrogram/signals.session(by default).
Use Python 3.13.
python -m venv .venv
source .venv/bin/activate
poetry install # or: pip install -r requirements.txt if you keep one
uvicorn app.api.server:app --reload- On startup, the app initializes the DB, builds the LLM client, starts the Telegram listener, and immediately begins processing new channel messages inline.
cd web
npm i
npm run devThe dev server proxies /api to http://localhost:8000.
See .env.example. Key values:
- Telegram:
API_ID,API_HASH,TELEGRAM_SESSION_DIR,TELEGRAM_SESSION_NAME - LLM:
OPENAI_API_KEY,OPENAI_MODEL(default:gpt-4o-mini) - DB:
DB_URL(default:sqlite+aiosqlite:///./signals.db)
- Default SQLite DB:
signals.db - Tables:
channels,signals - Uniqueness:
(channel_id, message_id)prevents duplicates - UTC times
GET /api/healthGET /api/channelsGET /api/symbolsGET /api/channels/{channel_id}/signals?limit&offsetGET /api/symbols/{symbol}/signals?limit&offsetGET /api/stats/channelsGET /api/stats/symbols
- A small regex gate quickly filters obvious noise; LLM still makes final decision + structured parse.
- Handle message edits by wiring Pyrogram’s edit handler and updating by
(channel_id, message_id). - Swap
ChatOpenAIfor anotherBaseLanguageModelif needed.