Why I built this instead of just watching charts
I have spent enough years staring at charts to know the actual failure mode is not lack of information, it is too much of it with no discipline attached. Every indicator agrees with you when you want it to. So FinSnap started from a narrow, almost boring goal: one question, answered the same way every single morning, with the evidence attached. Is today a good entry, for each of a fixed set of assets, according to rules that have actually been tested against just holding.
That "just holding" part matters more than it sounds. A strategy that beats a coin flip is not interesting. A strategy that beats buy-and-hold, after fees, after slippage, across multiple time windows, on an asset it was never tuned for, is a different thing entirely. That is the bar FinSnap holds every rule to, and it is stricter than what most retail tools bother with.
The shape of it
Under the hood it is 23 assets (the big indices, all eleven S&P sectors, a handful of macro instruments like gold, oil, the dollar index, long bonds, and BTC), 20 strategy configurations across five families (trend, momentum, breakout, mean reversion, and buy-and-hold as the benchmark), backtested across ten lookback windows from one month out to full history. Every signal computed at today's close only gets filled at tomorrow's open, with fees and slippage baked in by default, because a backtest that lets you trade on the same bar it saw is not a backtest, it is a fantasy.
Two separate scores come out of that, and keeping them separate is the actual design decision I am proud of. edgeScore asks does this rule have a durable edge on this asset, blending excess return, a Sharpe difference, and drawdown improvement over every window, then shrinking back toward neutral if the result only shows up in one window or came from a handful of trades. opportunityScore asks a completely different question: given that edge, is today actually a good moment to act on it. A strategy with a real edge that is currently telling you to stay flat is evidence against buying, not neutral information, and the scoring treats it that way. Conflating "this rule works" with "you should act on it right now" is, in my experience, the single most common way a backtest quietly turns into bad advice, so the two live as separate numbers all the way through the pipeline.
The options chain as a window into who is actually positioned
The daily backtest report is the part that gets acted on, but the live snapshot carries something the backtest cannot: options positioning for the liquid tickers. And this is the part I think is genuinely underrated by people who only look at price.
Price tells you what happened. An option chain tells you what large players are currently willing to pay real money to be positioned for, at specific strikes, for specific expiries, right now. A put/call volume ratio skewed heavily toward puts at a strike well below spot is not a prediction, but it is a fact about where size is sitting. A volume-weighted mean strike tells you where the crowd's actual center of gravity is, not where price last printed. And a cluster of heavy open interest at a round strike above spot behaves like a wall, because market makers hedging that exposure have a real, mechanical reason to lean against price moving through it. None of that shows up in a candlestick. All of it shows up in the chain.
FinSnap turns that into a small set of readable labels per expiry rather than a screen full of raw open interest, things like put_stack or call_stack for a strong directional skew, soft_put or soft_call for a mild lean, balanced, and thin when liquidity is too low to trust. I am careful to treat this as context, not a signal on its own, because options positioning tells you where the pressure is, not which direction price resolves. But context that tells you where large, informed money has already put real capital down is worth more than another moving average crossover, and it is the piece most retail-facing tools skip entirely because it is more annoying to compute correctly than to ignore.
Wide Bollinger bands, quietly, kept winning
Going in, I expected the trend-following family to dominate the leaderboard, since trend following on liquid macro assets is about as close to a free lunch as backtesting ever gets. What actually stood out once the strategies ran across the full universe and every window was how consistently the wider Bollinger Band configurations, both the breakout version and the mean-reversion version at 2 and 3 standard deviations, held up compared to the tighter, more "sensitive" settings people usually reach for first.
The intuition, once I sat with it, made sense. A band set at 2 or 3 sigma only fires when price has moved somewhere genuinely unusual for that asset's own recent volatility, not just noisy. That filters out a huge amount of the false-signal churn that a tighter band or a shorter RSI window produces constantly, at the cost of trading less often. Fewer signals, but each one is standing on a real statistical outlier rather than a bar-to-bar wiggle, and that trade-off is exactly what the edge score is built to reward: consistency across windows beats a high signal count. I do not have a single number I want to hang this on publicly yet, since the leaderboard keeps moving as more history and more assets get folded in, but the pattern has been stable enough, across enough of the universe, that it changed how I read the live technicals tab. A 2 sigma or 3 sigma band touch now gets my attention in a way a plain RSI dip does not.
The bug that taught me to trust nothing about "annualized"
The most useful thing that ever happened to this project was a bug, and I would rather write it up than pretend it did not happen. Yahoo Finance silently downgrades bar granularity on certain long-range requests. A request for daily SPY data over its full history could, without warning, come back as monthly candles instead, 403 bars covering 33 years. If you take "bars per year" on faith to annualize a return, that silent substitution turns a real 12% CAGR into a reported 924%. Nothing in the response says it lied to you. The numbers just look spectacular right up until you plot the equity curve and it looks nothing like 33 years of monthly compounding should.
The fix was to stop trusting the label entirely: annualization now comes from the actual elapsed wall-clock time between the first and last bar timestamp, never from an assumed bars-per-year constant, and a granularity substitution gets logged loudly the moment it happens instead of silently corrupting a number three layers downstream. I bring this up not to flex a bug fix but because it is the whole argument for why I do not fully trust any backtest tool I have not personally opened up, including my own before I found this. A 924% headline is exactly the kind of number that gets screenshotted and believed.
Where it is headed
It is not deployed publicly yet, on purpose. The backend, the Postgres storage, the Telegram delivery, and both CI pipelines are all in place, but the actual hosting decision (a small always-on container for the live snaps and the bot, a scheduled job for the pre-market batch) is still open, and Yahoo Finance getting noticeably stingier with datacenter IPs is the real risk to sort out before anything goes live for other people. What I do want to build next, more than any new strategy, is a public forward log: what the report actually said, timestamped, before the outcome was known, on something nobody can quietly edit afterward. A backtest is only as trustworthy as the person who ran it, and the only way past that is to let the calls speak for themselves in real time instead of asking anyone to take my word for the historical numbers.