![]() |
![]() |
TL;DR: I built a small, open-source Telegram bot that tracks major ETFs (CSPX, QQQM), calculates Trend/Momentum scores, and shows historical win rates for current market structures — using only free serverless tools.
The problem: "Is now a good time?"
If you’ve ever dollar-cost averaged into ETFs, you’ve probably asked yourself this question at some point.
The market is up — should I wait for a pullback?
The market is down — is this a buying opportunity or a falling knife?
I couldn’t find a tool that gave me a data-backed answer without requiring a Bloomberg terminal or a PhD in finance. So I built one.
The solution: A bot that shows historical probabilities
Instead of telling me what might happen, the bot tells me what historically happened when the market looked like this.
Here’s what a daily update looks like:
📜 Historical Match: 138 occurrences
• Next 90d: Win 84.1% | Avg +5.9% | MaxDD -18.4%
• Next 180d: Win 76.1% | Avg +9.1% | MaxDD -18.0%
That’s not a prediction. That’s data.
How it works (the 30-second version)
Every trading day, the bot fetches 15 years of historical data for CSPX and QQQM.
It calculates MA50, MA200, and RSI (14).
It combines those into two composite scores:
Trend Score (0–100) – measures structural health
Momentum Score (0–100) – measures short-term strength
It scans the entire 15-year history for structurally similar periods (within ±8 points on both scores).
It calculates forward returns for those matched periods — 90 days and 180 days out.
The tech stack (all free, all serverless)
Component | Tool
Data source | Yahoo Finance (via yfinance)
Calculation engine | Python (pandas, matplotlib)
Scheduling & execution | GitHub Actions (cron + on-demand)
API gateway | Cloudflare Workers
Delivery | Telegram Bot API
Source code | GitHub (MIT license)
The entire pipeline costs $0/month to run. GitHub Actions provides free compute, Cloudflare Workers provides free API routing, and Telegram provides free delivery.
The core logic: Trend Score explained
I wanted a scoring system that was simple enough to explain but robust enough to be useful.
The Trend Score is calculated as follows:
Start at 50 (neutral)
If price > MA200 → +20 points, plus bonus for distance above
If price > MA50 → +10 points
If MA50 > MA200 (golden cross) → +5 points
Vice versa for bearish conditions
This gives a score from 0 to 100 that reflects how “bullish” or “bearish” the current structure is.
The historical backtest: how the probability is calculated
This is the part that took the most thought.
For every trading day in the last 15 years, I calculate the Trend and Momentum scores. I then find all days where both scores are within ±8 points of today’s values.
Those days become the historical match set. For each matched day, I calculate:
The price 90 days later
The price 180 days later
The return percentage
The max drawdown during that period
The results are aggregated and displayed as:
Win rate (% of positive returns)
Average return
Maximum drawdown
This is not a backtest of a trading strategy — it’s a structural similarity analysis.
One design decision I’m proud of
I didn’t optimize the parameters.
The tolerance (±8 points) and the indicator set (MA50, MA200, RSI) were chosen before running the backtest. I didn’t tweak them to make the numbers look better.
This means the results are honest. They might not be perfect, but they’re not fabricated either.
What’s next
More assets — I’m planning to add more ETFs, and eventually individual stocks.
More indicators — I may add volatility (ATR) and participation (volume) to the scoring.
Public dashboard — a simple web view of the daily analysis.
Try it yourself
The bot is free and open source.
🔗 GitHub repo: github.com/kzyxx11/quant_trade_bot
📱 Daily updates: @ETF_Trend_Monitor on Telegram
If you’re a developer, you can fork the repo and adapt it to your own assets. If you’re an investor, just join the channel and check the daily update.
Feedback welcome
If you have thoughts on:
The scoring methodology
What assets to add next
How to improve the historical backtest
I’d genuinely appreciate hearing from you.
Built by Eric Khoo. Not financial advice — just data.


Top comments (0)