"Nothing mortal travels so fast as these Persian messengers." — Herodotus
The Chapar was the ancient Persian postal relay system — riders delivering critical intelligence across the empire at incredible speed. This project carries the same idea: delivering market intelligence to Telegram users, fast and reliably.
Chapar (چاپار) is a self-hosted AI-powered Telegram bot for technical chart analysis, market news, and conversational assistance. It combines FastAPI, Celery, PostgreSQL, Redis, market-data integrations, and OpenRouter-compatible language models.
This codebase comes from a Telegram bot the maintainer has operated for about a year. Over that time it has been used by a good number of users and deployed for several Telegram channel operators. A live instance is available at t.me/AlphaChart_bot if you want to see it in action before self-hosting.
Project status: Alpha. The open-source release is the production core, cleaned and documented for public use. Public interfaces and the database schema may still change. Review the security and financial disclaimers before exposing it to users.
Most AI finance bot examples stop at a notebook or a single LLM request. Chapar shows the less glamorous parts required to run a real Telegram product: background jobs, caching, user plans, referrals, admin broadcasts, retries, rate limits, database persistence, health checks, and multiple third-party providers.
Use it as:
- a self-hosted Telegram market intelligence assistant;
- a reference architecture for an async FastAPI + Celery + Telegram product;
- a starting point for your own OpenRouter-powered analysis workflow; or
- a production-tested example of turning an AI prototype into an operated service.
- Technical chart analysis for crypto and other supported markets
- Per-user English/Persian menus, AI chat, chart analysis, and news analysis
- Image-aware and conversational analysis through any OpenAI-compatible provider
- Current-news retrieval through Brave Search with LLM summaries
- Telegram subscriptions, referrals, administration, and broadcast workflows
- Redis-backed caching and background processing
- Docker Compose deployment with health checks and separate internal API credentials
The image below was produced by the repository's chart pipeline from live public BTC/USDT candles; it is not a design mockup.
flowchart LR
User["Telegram users"] <--> Telegram["Telegram Bot API"]
Telegram <--> Bot["Async Telegram bot"]
Operator["API client / operator"] --> Nginx["Nginx"]
Bot --> API["FastAPI service"]
Nginx --> API
Bot --> PostgreSQL[(PostgreSQL)]
Bot --> Redis[(Redis)]
API --> PostgreSQL
API --> Redis
API --> Celery["Celery workers + scheduler"]
Celery --> Redis
API --> Market["Toobit / SourceArena"]
Celery --> LLM["OpenAI-compatible LLM"]
Celery --> Brave["Brave News Search"]
chartist/: FastAPI API, analysis code, news retrieval, and Celery tasksbot/: Telegram interface, administration workflows, and bot persistencenginx/: reverse proxy for the APIdocker-compose.yml: PostgreSQL, Redis, API, workers, bot, and proxy
- Docker with Compose (recommended), or Python 3.11+
- A Telegram bot token
- An OpenRouter or other OpenAI-compatible API key
- A Brave Search API key if news summaries are enabled
- Credentials for the market-data providers you intend to use
-
Copy the environment template:
cp .env.example .env
-
Fill in the required values. At minimum, configure:
POSTGRES_PASSWORD=replace-me DATABASE_URL=postgresql+asyncpg://chapar:replace-me@chart_postgres:5432/chapar BOT_TOKEN=replace-me LLM_API_KEY=replace-me CHARTIST_API_KEY=replace-with-a-random-token FASTAPI_ACCESS_TOKEN=replace-with-the-same-random-token CHARTIST_ADMIN_API_KEY=replace-with-a-different-random-token FASTAPI_ADMIN_ACCESS_TOKEN=replace-with-the-same-admin-token DOCS_USERNAME=replace-me DOCS_PASSWORD=replace-me
Generate strong tokens with
python -c "import secrets; print(secrets.token_urlsafe(32))". Add the relevant provider keys from.env.examplefor the features you enable. Never commit.env. -
Start the stack:
docker compose up --build
The API is exposed through nginx at http://localhost:8001. Its health endpoint is /health; authenticated interactive documentation is available at /docs. On the first start with a new PostgreSQL volume, the Compose initialization script creates both application databases.
After the stack is healthy, generate a chart without creating a Telegram user:
curl --fail --output btc-chart.jpeg \
-H "access_token: replace-with-your-CHARTIST_API_KEY" \
-H "Content-Type: application/json" \
--data '{"symbol":"BTCUSDT","period":"1m","interval":"1h","show_volume":true,"show_rsi":true}' \
http://localhost:8001/api/v1/stocks/chart/Open btc-chart.jpeg to inspect the generated result. Chart generation uses public market data; LLM analysis and news need the provider keys described below. Browse all request schemas and examples at /docs using DOCS_USERNAME and DOCS_PASSWORD.
python -m venv .venv
python -m pip install -r requirements.txt
cp .env.example .env
python -m pytest -q
python -m compileall -q bot chartistRun make help for the common commands. Local services still require valid environment variables and reachable PostgreSQL/Redis instances.
Database integration tests are opt-in so the default suite stays deterministic. Set TEST_DATABASE_URL to a disposable PostgreSQL database to run them.
The LLM client uses the official OpenAI Python library against an OpenAI-compatible endpoint. LLM_BASE_URL defaults to OpenRouter, while LLM_MODEL, LLM_ANALYSIS_MODEL, LLM_NEWS_MODEL, and LLM_CHAT_MODEL can each select a provider/model supported by that endpoint. OPENROUTER_API_KEY is accepted as a fallback for LLM_API_KEY.
News requests fetch current Brave News Search results and send a bounded, deduplicated set of titles, descriptions, URLs, and publication times to the configured news model. The grounded-generation prompt treats retrieval content as untrusted data, assigns stable source IDs, asks for inline citations, and returns a lightweight citation-validation report alongside the answer. Configure BRAVE_SEARCH_API_KEY (or BRAVE_API_KEY) and LLM_NEWS_MODEL to enable it.
Before operating the project for other people, review THIRD_PARTY_SERVICES.md. It explains which user or market data crosses each external boundary, what remains local, and which integrations are optional.
This software processes secrets, Telegram user data, and potentially sensitive market activity. Use separate long random API and admin tokens, restrict CORS_ORIGINS when browser clients are enabled, terminate TLS at a trusted reverse proxy, and keep PostgreSQL and Redis off the public internet. See SECURITY.md for vulnerability reporting and deployment guidance.
Chapar is research software, not financial advice. Model output and market data can be delayed, incomplete, or wrong. Do not make trading decisions solely from its output, and make the disclaimer clear to your own users.
See CONTRIBUTING.md for the code map and validation checklist. Changes are tracked in CHANGELOG.md.
Bug reports and focused feature proposals are welcome through the GitHub issue templates. Please read the Code of Conduct before participating.
Maintainers preparing a public release can use the launch checklist for repository settings, suggested topics, clean-clone verification, and honest English/Persian announcement copy.
Chapar is released under the MIT License.

