Strategies
ETH OKX vn.py AtrRsiStrategy — Frozen Source-Default Translation
Outcome: Abandoned
EthOkxFrozenAtrRsiStrategy
Outcome Summary
EthOkxFrozenAtrRsiStrategy attempted a frozen translation of vn.py’s ATR/RSI strategy with capital-relative sizing. Its five-day verification smoke test produced -0.139% per trade over 38 closed positions and a profit factor of 0.626. After three iterations, QA still found entry and trailing-stop execution inconsistent with the source, leading to abandonment before full backtesting or optimization.
Hypothesis
The submission supplies executable entry and exit rules. The user's faithful-reproduction requirement takes precedence over inventing a different mechanism to meet diversity quotas. OKX is underrepresented at 2.3% versus its 5% target, and the strategy allows both directions against a portfolio that is 82.6% long-only. Corpus concentration is empty, so instrument-level novelty cannot be established. ETH keeps the literal five-price-unit order offset more proportionate than a low-priced altcoin. This tests volatility-expansion momentum, rather than the failed BTC Connors-RSI reversion. Economic viability remains unverified; the source defaults must be allowed to fail without post-hoc rescue.
Implementation
Frozen translation of vn.py AtrRsiStrategy on ETHUSDT.OKX 1-minute bars. When ATR(22) is above its 10-bar mean and RSI(5) is above 66 (or below 34), it enters with a limit order at close +/- $5 (or the mirror for shorts). It exits only through a 0.8% trailing stop that is renewed every bar. Each entry is sized at 10% of equity in notional.
Iteration 3 fixes QA's critical defect. The venue rejects a renewed trailing stop that is already through the bar close (reject_stop_orders=True), which left the position with no exit. Now, when the stop level is already crossed (stop >= close for longs, stop <= close for shorts), the strategy closes with a reduce-only market order on the next bar. This matches vn.py, where such a stop triggers on the next bar at about the open. Otherwise the renewed STOP_MARKET rests at the venue as before. As a safety net, on_order_rejected flattens the position if any STOP_MARKET is rejected. Entry logic, indicators, sizing and every frozen parameter are unchanged. QA also raised an edge concern: 1-minute bars, taker on both legs, and up to 0.8% given back per trade. That is a property of the frozen source defaults, which the hypothesis says must be allowed to fail without rescue. No tuning was done.
Verification Results
Implement pending source-style stops evaluated against subsequent market data, preserving conditional triggering and gap-price execution. Add an engine execution hook if necessary; do not substitute an immediate market close. Verify ordinary crossing, gap-through, and gap-away cases for both directions.
The crossed-stop fallback does not preserve source execution. _submit_exit() immediately calls close_position(); OKX has zero configured latency, so Nautilus executes against the current market at the decision bar's close, rather than the next bar's open. Furthermore, vn.py checks the renewed stop against the next bar's range: a gap back above a long stop can leave it untriggered. An unconditional market exit changes both timing and trigger conditions. Source: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py
Provide subsequent-bar activation for the original limit price and entry-sized quantity. Validate that no entry fills on the signal bar and that a next-bar gap beyond the limit prevents an opening fill unless the subsequent range reaches the limit.
BUY limits at close+$5 and SELL limits at close-$5 are marketable when submitted to Nautilus's current close-price book. With post_only=False and zero OKX latency, they can fill on the signal bar. The source backtester matches existing orders before invoking on_bar, so newly generated limits first become eligible on the subsequent bar, with their price constraint still enforced. This changes entries, gap handling, and subsequent trailing-stop state. Source: https://raw.githubusercontent.com/vnpy/vnpy_ctastrategy/6ef76981624bf55b2ea978f8587f74d633aafc72/vnpy_ctastrategy/backtesting.py
Iteration History
Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - optimization_plan fixes leverage at 1.0
Before calling _submit_stop_market, test whether the stop is already crossed. For a long, check stop >= current_close; for a short, check stop <= current_close. If it is, call self._submit_exit(position) (a reduce-only market close), which matches vn.py's next-bar stop trigger. Otherwise submit the resting stop as you do now. As a safety net, also track rejected stop orders, e.g. in on_order_rejected, and flatten the position.
No change needed; recorded for the analyst.
entry_price_offset is a fixed $5. That is about 0.13-0.33% of ETH's price across its history, so the entry limit always crosses and fills as taker at the next bar. This is faithful to the source and is not a defect. Note that vn.py fills at min(limit, next open), and Nautilus behaves similarly.
Outcome Summary
A faithful translation must preserve subsequent-bar order eligibility, conditional stop triggering and gap execution, as well as indicator calculations.
After three iterations, Layer 4 QA rejected the translation for hypothesis mismatch: crossed-stop market exits changed source timing and trigger conditions, while marketable entry limits could fill on the signal bar. The smoke-test losses were an edge concern, not an independent blocker.
Translate vn.py’s source-default ATR/RSI strategy to ETHUSDT.OKX one-minute perpetual bars, preserving its signals and orders while sizing entries at 10% of equity with 1.0 leverage.
A five-day verification smoke test recorded -0.139% per trade across 38 closed positions, with a profit factor of 0.626. Full backtesting, optimization, analyst evaluation and risk review were not reached.
Abandon Reason
Analysis
AtrRsiStrategy
Backtest and paper results are hypothetical. Trading involves risk of loss.