Backtest methodology
How Drogo simulates historical strategy performance, what assumptions are baked in, and which biases we explicitly control for.
Last reviewed:
Data sources & resolution
Drogo backtests are run against the same historical bar data that powers the live charts: end-of-day OHLCV from Polygon for US equities and ETFs, with intraday resolutions (1m, 5m, 15m, 60m) available for the same instruments. Crypto pairs use Binance spot data. Forex pairs use Polygon FX. All data is delivered through the Drogo data API's /history endpoint and cached at the edge for read consistency across a single backtest run.
Each instrument is keyed by its primary listing — corporate actions (splits, special cash dividends, ticker changes) are applied to the historical series so a 100-share AAPL position bought in 2014 is reflected as 700 shares at today's prices, with cost basis adjusted accordingly. Spin-offs are applied as cash-equivalent proceeds at the spin-off date when Polygon publishes the ratio; otherwise the position is closed at the day-before-spin-off close and a note is emitted in the run log.
Order model & slippage
By default, Drogo simulates market orders that execute at the next bar's open after a signal fires on bar close. This avoids look-ahead bias: a strategy that fires at 15:30 on the daily timeframe cannot trade at the same day's 16:00 close.
Slippage is modeled as a fixed fraction of bar range, defaulting to 5 bps for liquid US equities, 10 bps for less liquid stocks (ADV < $20M), 15 bps for crypto majors, and 30 bps for crypto altcoins. Slippage is applied symmetrically on entry and exit so round-trip costs are double the single-leg figure. Users can override these defaults per-run.
Limit and stop orders are simulated against the bar's high/low: a buy-stop at $101 fires only if the high is ≥ $101 on the bar in question, with fill price set to max(stop, open). Stop-losses on long positions fire if low ≤ stop, with fill at min(stop, open) to model gap-down losses honestly.
Worked example: AAPL signal fires on 2024-01-10 close at $185.92. Default slippage tier is 5 bps. Next bar opens at $186.40. Simulated fill = $186.40 × (1 + 0.0005) = $186.49. On exit five days later at open $192.10, simulated fill = $192.10 × (1 − 0.0005) = $192.00. Round-trip slippage cost = ($186.49 − $186.40) + ($192.10 − $192.00) = $0.19 per share, ≈ 10 bps round trip. Reported P&L = $192.00 − $186.49 = $5.51 per share, before SEC/FINRA fees on the sell leg.
Commissions & funding
US equities: $0 commission (matches modern retail brokers). SEC fee 0.00229% on sells and FINRA TAF $0.000119/share on sells are applied unless the user disables them. Crypto: 10 bps maker / 10 bps taker by default (Binance VIP-0). Forex: $0 commission, spread baked into the slippage model.
Margin and short-funding: the engine charges overnight financing on short positions at SOFR + 50 bps annualised, prorated daily. Long positions are unfunded by default (cash account). Users can switch to a margin account model that charges SOFR + 200 bps on borrowed cash above 100% equity utilisation.
Survivorship & lookahead bias controls
Drogo's historical universe includes delisted and bankrupt tickers wherever the data provider supplies them, so a strategy that backtests on "S&P 500 stocks 2015–2024" actually runs against the historical index membership of each year, not today's membership. Index reconstitution events are taken from Polygon's historical index files when available; otherwise we fall back to a curated CSV that we update quarterly.
Earnings dates, dividend dates, and other corporate events are taken from each event's announcement timestamp, not the report timestamp. A strategy keyed on "buy 2 days before earnings" therefore knows the earnings date only after it was publicly announced, not after the fact.
No fundamentals data younger than 75 days from quarter-end is used, since revisions to GAAP financials are common in the first 75 days post-filing. This is conservative; users can lower it.
Statistics reported
Every backtest run reports: total return, CAGR, max drawdown, Sharpe (rf = 1Y T-bill, daily returns), Sortino (downside semi-deviation), Calmar (CAGR / |max DD|), win rate, profit factor (gross profit / gross loss), average winner / loser, expectancy per trade, average holding period, exposure (% of time in market), and the full equity curve.
Sharpe and Sortino are annualised by √252 for daily strategies and √(365×24×60) for 1m crypto strategies. We do not compute "monthly Sharpe" by default because it inflates the number for high-frequency strategies; if you need it, opt in explicitly.
Drawdown is calculated on the equity curve including unrealized P&L, not just realized. This matches what a real account holder would see day-to-day.
What backtests cannot tell you
Backtests assume that the strategy you ran in code is the strategy you would have run in real time, with no behavioural override. In practice most retail traders override their strategy after 3–4 consecutive losses. The reported max drawdown is a lower bound on what a human would experience.
Backtests cannot model liquidity events that did not happen: a strategy that always traded $10k of AAPL would have moved markets if scaled to $100M. We do not auto-shrink position size based on average daily volume; that is the user's responsibility.
Backtests are not investment advice and do not establish that the strategy will work going forward. Drogo does not run portfolio-level risk reviews and does not act as a fiduciary.
Changelog
- — Initial publication.
- — Added survivorship-bias and look-ahead-bias control sections; clarified default slippage tiers.
References
Drogo Research — Quant editorial
נבדק לדיוק עובדתי; המתודולוגיה מקושרת למטה.