Strategies
je-suis-tm Heikin-Ashi Backtest port: buy a growing no-upper-wick bearish Heikin-Ashi candle after a bearish one (pyramid up to 3 units), sell everything on a no-lower-wick bullish HA candle after a bullish one (NVDA.USEQ 1-DAY, long-only, next-session-open fills)
Outcome: Abandoned
NvdaHeikinAshiPyramid
Outcome Summary
NvdaHeikinAshiPyramid ported a published Heikin-Ashi pyramiding rule to NVDA daily bars, with sizing as a share of equity and fills at the next open. Over 4 iterations it got past an earlier problem where the strategy never entered a trade. The final backtest traded actively (338 trades) but lost 79.73% with a negative Sharpe and a drawdown near 95%. At the backtest review the analyst confirmed the code matched the contract and abandoned the strategy for negative expectancy, so it never reached optimization, analysis or risk review.
Hypothesis
Retry after a no_trades verification loop. Our measurement shows the source rule fires about 22-46 times a year on NVDA.USEQ daily (822 entries, 1999-2026), so the failure was in the implementation (exact-equality or rounded HA comparisons), not in the premise. We keep the user's market and rules, and rewrite the equality tests as float-safe inequalities that are mathematically identical. USEQ single-stock is not an over-represented bucket (USEQ 9.7%).
negative_expectancy: This NVDA daily HA port loses on an adequate development sample: 264 closed positions, -$88,900 realized PnL, PF 0.571, and average trade -0.2002% against the USEQ 0.05% floor. The code's growing bearish-body entry and bullish sell-all conditions match the contract; the ledger shows long pyramided positions rather than the former zero-entry defect. QA's economic concern is borne out as outright negative net expectancy. No specific implementation correction warrants an optimization cycle. This verdict covers this equity-relative, next-open port, not the author's same-close source results. Drawdown alone is not the rejection basis.
Implementation
Heikin-Ashi port of the source's NVDA rules, on NVDA.USEQ daily bars. The HA series is computed recursively in floats, starting from the first bar's open. Entry buys one unit (20% of equity, whole shares) when all of these hold: the HA candle is bearish; it has no upper wick (HA_open >= max(HA_close, High)); its body is larger than body_growth_ratio x the previous body; and the previous HA candle was bearish. Units add up to a cap of 3. Exit sells all units when a bullish HA candle has no lower wick (HA_open <= min(HA_close, Low)) and follows a bullish one. Long-only. Orders fill at the next session open.
Verification Results
When a position is open and units_held == 0, re-derive units_held from the position quantity (ceil(qty / approximate unit size)), or allow the exit whenever a position is open.
units_held is in-memory state. After a paper/live restart with a position open it restarts at 0, so should_exit (which requires units_held > 0) ignores exit triggers until the position is closed some other way. Pyramid counting is also lost. The backtest never restarts, so the backtest is not affected.
Optional: increment units_held only after a confirmed fill (on_order_filled) instead of at decision time.
should_enter increments units_held before the base class sizes the order. If position_size returned 0 or the order were dropped for min notional, the count would drift. The counter self-heals: it resets to 0 on the next flat bar, and a 20%-of-equity NVDA unit is far above $5. So the drift cannot happen in practice.
None required.
min_bars_required() returns 2, which overrides the base default of 20. This is deliberate and harmless. The first primary bar is skipped by the base class, so the HA recursion is seeded on the second bar's open. That matches the contract's 'seeded on the first bar the strategy sees' and only shifts the seed by one bar.
The strategy is a long-only NVDA book with up to 60% of equity invested. Much of any profit will be NVDA beta, not the HA timing rule. The analyst should compare it against a 60% NVDA buy-and-hold over the same window. Average trade return is above the USEQ spread floor (about 0.05%) on daily holds, so fees are unlikely to be the deciding factor.
Backtest Review
- Sharpe
- -0.15
- Total return
- -79.73%
- Max drawdown
- 94.85%
- Trades
- 338
- Win rate
- 58.6%
- Profit factor
- 0.63
264 closed positions, all long; trade timestamps and reported exposure are consistent with next-open execution and pyramiding.
Closed-trade PnL totals -$88,900, closely reconciling with the -88.85% account return.
Average trade return is -0.2002% versus the USEQ 0.05% floor; profit factor is 0.571 and Sharpe is -0.299.
Average losers ($1,607) exceed average winners ($877), despite a 51.1% win rate.
Drawdown is 94.85% against the registered 40% constraint.
Writing the required outbox file failed with PermissionError; this verdict was not saved.
Iteration History
Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - optimization_plan fixes leverage at 1.0
Verification failed (Layer 1 — static analysis): - Import outside the sandbox allowlist: from zoneinfo — strategies may import __future__, abc, bisect, calendar, collections, copy, dataclasses, datetime, decimal, enum, fractions, functools, heapq, itertools, json, math, nautilus_trader, numpy, operator, re, src, statistics, string, typing (line 7)
Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: NVDA.USEQ-1-DAY-LAST-EXTERNAL, Bars processed: 953 Diagnostics: should_enter() returned a side 0 times over 953 evaluated bars -> your ENTRY CONDITION never triggered. Loosen the entry logic / thresholds. Ensure your strategy produces trades with the given data and parameters.
Outcome Summary
Fixing the float-equality bug that had produced zero entries only showed that this Heikin-Ashi pyramid rule has negative net expectancy on NVDA daily bars with next-open fills. The signal-research check also found no forecasting information (IC 0.034, t=0.9), so a correct implementation does not mean an edge exists.
At the backtest review the analyst voted to abandon for negative expectancy before optimization. The review found that the code matched the contract and that the earlier zero-entry defect was fixed, but the strategy lost money net of costs, with average losses larger than average wins. The analyst saw no specific code fix worth an optimization cycle.
A port of je-suis-tm's Heikin-Ashi backtest on NVDA.USEQ daily bars (1999-2026). It bought one unit of 20% of equity when a growing bearish Heikin-Ashi candle with no upper wick followed another bearish candle, held up to 3 units, and sold everything on a bullish candle with no lower wick that followed a bullish one. It was long-only and filled at the next session's open.
The attached backtest made 338 long trades (339 entries submitted) and lost 79.73% in total, with a Sharpe of -0.146, a profit factor of 0.627, a 94.85% max drawdown and an expectancy of -$234.68 per trade, although avg_trade_return_pct was reported as +0.61%. The backtest-review analysis cites different figures from its own run: 264 closed positions, a -88.85% return, -$88,900 of realized PnL, a profit factor of 0.571, a Sharpe of -0.299 and an average trade of -0.2002%.
Analysis
Heikin-Ashi backtest
Analysis
Heikin-Ashi%20backtest.py
Omega ratio - Wikipedia
Sortino ratio - Wikipedia
Calmar ratio - Wikipedia
Backtest and paper results are hypothetical. Trading involves risk of loss.