Trader-analysts spend hours manually sending signals to Telegram chats. Subscribers get confused, miss signals, and result tracking is done in Excel. A subscription system automates everything: from signal publication to win rate statistics. Order development of such a system — and you will forget about the chaos.
Our client, a team of 5 analysts, once lost 30% of subscribers in a month due to signal delivery delays. We built a distributed system based on Telegram Bot + WebSocket, delivering each signal to all subscribers in < 500 ms. Their win rate is now 72%, and subscribers stay. The system handles up to 2000 requests per second, with downtime below 0.1%. Get a consultation — we'll show how it works on your project.
Unlike cryptocurrency trading copy trading, where signals are executed automatically, our system leaves the decision to the trader. Each signal is a recommendation with reasoning, chart, and levels. The subscriber decides whether to enter. But for this scheme to work, reliable infrastructure is needed: subscription management, multi-channel delivery, tracking of each signal, and honest provider statistics. Without it — chaos and user churn.
What Problems Does the Subscription System Solve?
Manual distribution via chats. Messages are lost in the stream, subscribers don't see TP/SL, history is hard to track. Automated delivery via channels (Telegram, email, WebSocket) ensures each subscriber receives the signal in a structured format.
Lack of provider statistics. Without tracking results, subscribers don't know how successful the analyst is. For each signal we collect: whether entry was reached, which TP/SL was hit, final P&L. These metrics (win rate, average R:R) are published on the provider's page.
Complex subscription management. Tariff changes, renewals, blocking — all must be automated. We build a backend with flexible rules (trial period, monthly discount, cancellation).
How We Build the Signal Delivery System
We use an asynchronous stack on Python (FastAPI + asyncio) for the signal distributor. Message brokers (Redis Pub/Sub) allow scaling to 10,000 subscribers with < 1 second latency. For latency-critical traders — a WebSocket channel: it's 10x faster than Telegram but requires a stable connection.
Channel comparison:
| Channel | Latency | Reliability | Cost |
|---|---|---|---|
| Telegram | < 1 sec | High | Free |
| 5-30 sec | Medium | Free | |
| WebSocket | < 100 ms | High | Requires server |
During development, we consider Telegram Bot API rate limits — we send batches of 30 messages with a 1-second pause. For email, we use a queue and retry with exponential backoff.
Why Is Honest Result Tracking Important?
A trading signal is not just a recommendation, but a promise of profit. Subscribers trust the provider, so win rate and R:R must be transparent. Without objective statistics, reputation collapses. We implement automatic outcome collection for each signal: whether entry was reached, which TP/SL hit, final P&L. These data cannot be falsified.
Signal metrics:
| Metric | Description |
|---|---|
| Win Rate | % of signals with positive P&L |
| Average R:R | Average risk to reward ratio |
| TP hit rate | % of signals where at least one TP was hit |
| Max drawdown | Maximum drawdown over the period |
System Components
Signal Providers — sources of signals: trader-analysts, algorithmic systems, on-chain analytics.
Signal Format — structured message: instrument, direction, entry price, take profit levels, stop loss, timeframe, reasoning.
Distribution Engine — delivers the signal to all subscribers via different channels.
Subscription Management — manages subscriptions, tariffs, payments.
Performance Tracking — tracks results of each signal to calculate provider's win rate.
Signal Data Model
from pydantic import BaseModel
from decimal import Decimal
from datetime import datetime
from typing import Optional
class TradingSignal(BaseModel):
id: str
provider_id: str
symbol: str # BTC/USDT
exchange: str # binance
direction: str # LONG / SHORT
entry_type: str # MARKET / LIMIT / ZONE
entry_price: Decimal # or None for market
entry_zone_low: Optional[Decimal]
entry_zone_high: Optional[Decimal]
take_profit_levels: list[Decimal] # [tp1, tp2, tp3]
stop_loss: Decimal
leverage: Optional[int] # for futures
risk_pct: Optional[float] # recommended % risk of capital
timeframe: str # 4h, 1d
rationale: str # text reasoning
chart_url: Optional[str] # annotated chart screenshot
expires_at: Optional[datetime]
created_at: datetime = datetime.utcnow()
Distribution Engine
class SignalDistributor:
def __init__(self, telegram_bot, email_service, push_service, websocket_hub):
self.channels = {
'telegram': telegram_bot,
'email': email_service,
'push': push_service,
'websocket': websocket_hub,
}
async def distribute(self, signal: TradingSignal):
# Get all subscribers of this provider
subscribers = await self.subscription_repo.get_active_subscribers(
provider_id=signal.provider_id
)
# Group by preferred notification channels
by_channel: dict[str, list] = {}
for sub in subscribers:
for channel in sub.notification_channels:
by_channel.setdefault(channel, []).append(sub.user_id)
# Distribute in parallel across channels
tasks = []
for channel, user_ids in by_channel.items():
handler = self.channels.get(channel)
if handler:
tasks.append(handler.send_signal(signal, user_ids))
await asyncio.gather(*tasks, return_exceptions=True)
# Log the dispatch
await self.signal_repo.mark_distributed(signal.id, len(subscribers))
Telegram Delivery
class TelegramSignalBot:
def format_signal(self, signal: TradingSignal) -> str:
tp_lines = '\n'.join(
f" TP{i+1}: ${tp:,.2f}"
for i, tp in enumerate(signal.take_profit_levels)
)
return f"""
📊 **{signal.symbol}** — {signal.direction}
**Entry:** {'market' if signal.entry_type == 'MARKET' else f'${signal.entry_price:,.2f}'}
**Stop Loss:** ${signal.stop_loss:,.2f}
**Take Profit:**
{tp_lines}
**Timeframe:** {signal.timeframe}
**Risk:** {signal.risk_pct or 1}% of deposit
📝 {signal.rationale}
""".strip()
async def send_signal(self, signal: TradingSignal, user_ids: list[str]):
text = self.format_signal(signal)
# Batches of 30 (Telegram rate limit)
for batch in chunks(user_ids, 30):
tasks = [
self.bot.send_message(user_id, text, parse_mode='Markdown')
for user_id in batch
]
await asyncio.gather(*tasks, return_exceptions=True)
await asyncio.sleep(1) # rate limit
Performance Tracking
class SignalPerformanceTracker:
async def track_signal_outcome(self, signal: TradingSignal):
"""Track signal outcome using market data"""
entry_time = signal.created_at
# Check if entry was reached
entry_price = await self.find_entry_price(signal)
if not entry_price:
await self.mark_signal_missed(signal.id)
return
# Monitor TP and SL
outcome = await self.monitor_until_close(
symbol=signal.symbol,
direction=signal.direction,
entry=entry_price,
tp_levels=signal.take_profit_levels,
sl=signal.stop_loss,
)
await self.signal_repo.save_outcome(
signal_id=signal.id,
entry_price=entry_price,
exit_price=outcome.exit_price,
exit_reason=outcome.reason, # 'TP1', 'TP2', 'SL', 'EXPIRED'
pnl_pct=outcome.pnl_pct,
)
Accumulated outcome statistics are the key indicator for new subscribers. Win rate, average R:R, P&L over time, percentage of hit TP1/TP2/TP3 vs SL — all should be visible on the signal provider's page.
Work Process
- Analytics — discuss business logic, signal format, channels, tariffs.
- Design — data model, distributor architecture, tech stack selection.
- Implementation — Python (FastAPI) backend, integration with Telegram Bot API, email, WebSocket.
- Testing — load testing (10,000 subscribers), rate limit verification, input fuzzing.
- Deployment — CI/CD, monitoring setup (Prometheus + Grafana), API documentation.
What's Included
- Backend development of the subscription system (Python, FastAPI, PostgreSQL, Redis).
- Integration with Telegram Bot API, SMTP, WebSocket.
- Provider dashboard (signal submission, statistics view).
- API for client application (signal retrieval, subscription management).
- Documentation and team training.
- Stability guarantee: monitoring and support for 1 month after launch.
Timeline and Cost
Timeline — 4 to 6 weeks depending on complexity (number of channels, tariff plans, dashboard requirements). Cost is calculated individually after analytics. We have 5+ years of experience in crypto development and certified engineers. Submit a request — we'll evaluate your project.
Typical Design Mistakes
- Not accounting for Telegram Bot API rate limits — leads to bot blocking.
- Missing email retry — emails get lost.
- Storing signals in MongoDB without indexes on provider_id and created_at — slow statistical queries.
- Not logging delivery of each signal — hard to debug missing deliveries.
Contact us to discuss details. Get a free consultation.







