Skip to content
All strategies

Strategies

Chaos TqSdk RSI(6) 35/65 Re-Cross Reversal, Completed-Bar Port on DOT Hyperliquid (DOTUSD.HYPERLIQUID 1-DAY, long-short, 1% close stop, RSI take-profit, 10-day time stop)

Outcome: Abandoned

ChaosDotCompletedBarRsi

Outcome Summary

This run ported Chaos's TqSdk RSI(6) 35/65 re-cross demo to DOT on Hyperliquid daily bars. It changed two literal bugs in the source, evaluation on the forming candle and a nanosecond-based time stop, so the rules could fire at all. After 3 iterations the code traded as intended, but it lost money after costs: an average trade of -0.249% of notional, Sharpe -0.21 and a 54% drawdown on the reviewed period, and -44% over the full backtest. The backtest review abandoned it before optimization, because the 1% close-checked stop was inside DOT's daily noise and was fixed by the contract. The verdict covers only this port, not RSI re-cross reversal in general.

Hypothesis

Port of "RSI" by Chaos (shinnytech/tqsdk-python demo, Apache-2.0, commit 78c9922), an RSI overbought/oversold re-cross reversal. The strategy and its parameters are the author's; no performance claim is verified. Platform adaptations: DCE.a2101 (soybean futures, a venue we cannot trade) is replaced with DOTUSD.HYPERLIQUID 1-DAY, the market this seed was already assigned to. The 500-contract fixed size becomes equity-relative sizing. Fills are market orders at the signal bar's close, which is the registry's……Show moreShow less

Port of "RSI" by Chaos (shinnytech/tqsdk-python demo, Apache-2.0, commit 78c9922), an RSI overbought/oversold re-cross reversal. The strategy and its parameters are the author's; no performance claim is verified. Platform adaptations: DCE.a2101 (soybean futures, a venue we cannot trade) is replaced with DOTUSD.HYPERLIQUID 1-DAY, the market this seed was already assigned to. The 500-contract fixed size becomes equity-relative sizing. Fills are market orders at the signal bar's close, which is the registry's equivalent of a next-bar-open fill on a 24/7 venue. TWO LABELLED CHANGES FROM THE LITERAL CODE, both needed so the rules can fire at all. (1) Evaluation timing: TqSdk runs its logic when a NEW daily candle appears. At that moment the last candle has only just opened, so 'current_rsi' is read off that forming candle and 'previous_rsi' off the candle that just completed. On a 24/7 market the forming candle's first price equals the previous close. A zero-change bar shrinks both the up and down averages of TqSdk's SMA(x,N,1) RSI by the same factor, so current_rsi always equals previous_rsi and neither cross can ever happen. The previous attempt reproduced this literally and recorded zero trades. This port evaluates on each COMPLETED daily bar instead: current_rsi = RSI at bar N's close, previous_rsi = RSI at bar N-1's close. That is the evident intent of the code (a cross from below 35 to above 35, or from above 65 to below 65, between consecutive daily RSIs). (2) Time stop: the source divides a nanosecond timestamp difference by 86,400. The result therefore passes 10 after about 0.9 ms, and the 'time stop' closes every trade at the next evaluation. The constant name and comment say 10 days, so this port measures holding time in days from position.ts_opened (time_stop_days = 10). The literal one-bar behaviour is still inside the tuning range (time_stop_days = 1). Every other rule is kept exactly as written: RSI period 6, thresholds 35/65, the was_oversold/was_overbought flags with their reset on entry, a 1% stop checked on the bar CLOSE (not intrabar, as in the source), the opposite-zone RSI take-profit, the exit-check order stop -> take-profit -> time, and no re-entry on the bar that exits. Risk-control route (b): signal/stop/time exits with capped sizing at 50% of equity notional, unlevered. DOT's ~4.5% daily std gives about 43% annualised position volatility. Because the stop is checked on the close, a 30% daily gap would cost about 15% of equity, which is the profile's trade-loss cap.

This is a retry after a no_trades run. The opening-update mapping made current RSI identical to previous RSI, so no entry could fire. The fix evaluates on completed bars and corrects the nanosecond time-stop bug. Both are labelled. The market (DOT Hyperliquid daily) is kept, as the retry instruction asks; Hyperliquid is under its quota (13.4% vs 20%) and the design is long-short.

Negative net expectancy after costs on an adequate sample. Over 221 trades on DOT Hyperliquid daily bars (2021-01 to 2025-08, development period only), the average trade return is -0.249% of notional against the 0.15% Hyperliquid floor. Profit factor is 0.88, Sharpe -0.21, total return -35% and max drawdown 54% (the contract limit is 30%). Fees are not the cause: commissions of $8.5k against a net loss of about $35k. QA's concern is borne out. The author's 1% stop, checked on the daily close, sits well inside DOT's roughly 4.5% daily range, so 105 trades ended after one bar. Losing trades averaged -4.2% of notional, and the 28% win rate cannot carry them. The stop fraction and the 50% position size are fixed by the research contract, so the optimizer cannot change the source of the loss. Tuning the RSI period, thresholds or time stop would only fit noise on a negative base. This verdict covers this completed-bar port of the TqSdk RSI(6) 35/65 re-cross demo on DOT daily bars, with the author's 1% close-checked stop. It does not cover RSI re-cross reversal in general.

Implementation

Stratmill translation of Chaos's TqSdk RSI demo on DOTUSD.HYPERLIQUID daily bars. It uses RSI(6) with TqSdk's SMA(x,N,1) formula (an EWM with alpha=1/N). It goes long when RSI re-crosses above 35 after being oversold, and short when it re-crosses below 65 after being overbought; the was_oversold/was_overbought flags reset on entry. Exits are checked in the source's order: a 1% stop on the bar close, then the opposite-zone RSI take-profit, then a 10-day time stop. Positions are sized at 50% of equity notional, unlevered. Orders are market orders at the signal bar's close, which equals the next bar's open on a 24/7 venue.

This implements the amended hypothesis. Iteration 2 kept the literal opening-update mapping, where current_rsi == previous_rsi, so the strict crosses could never fire (0 entry sides over 1390 bars). This version evaluates on each completed daily bar: previous_rsi is the RSI at bar N-1's close and current_rsi is the RSI at bar N's close. The time stop is measured in real days from position.ts_opened (time_stop_days=10) instead of the source's ns/86400 bug. Parameters and config now follow the hypothesis's optimization plan names (rsi_period, oversold/overbought_threshold, time_stop_days tunable; position_fraction=0.5, stop_loss_percent=0.01, warmup_extra_bars=10, leverage=1 fixed). This replaces the stale previous_config, which no longer matched the hypothesis. Risk route (b): signal/stop/time exits with notional capped at 50% of equity. Every other rule is kept: the flag updates from previous_rsi before trading, the close-based stop, the exit order, and no re-entry on the bar that exits.

Verification Results

No change needed. Optionally, suppress entries until delta_count >= ~5*rsi_period so the seed transient does not matter.

The RSI is seeded once from the base template's bar buffer (16 bars at the first evaluation) and then updated incrementally over the full history. TqSdk recomputes it on a rolling ~200-bar kline window. The EWM(alpha=1/N) seed decays within a few dozen bars, so values match the source after warmup. Only the first few evaluations differ slightly.

None required.

should_enter clears was_oversold/was_overbought as soon as it returns a side, even if the base then drops the order (min_notional or zero size). The source has the same behaviour (it resets the flag when it places the order), so this is faithful. Entries are 50% of equity, far above $10, so the case is practically unreachable.

The stop is anchored on the signal bar's close (entry_price_value), not on the fill price. A market order fills at that close on this 24/7 venue, so the two coincide apart from slippage. After a restart the code re-anchors on avg_px_open. This matches the source, which anchors on the price at the decision.

A 1% stop checked on the close of a daily DOT bar (daily std about 4.5%) sits well inside one day's noise, so most trades will likely end at the stop on the next bar. Expected per-trade return is then dominated by stop-outs of about -1% or worse against occasional RSI take-profits. The about 0.09% Hyperliquid taker round trip is small relative to that, but net expectancy could easily be negative. The stop fraction is fixed by the research contract, so the optimizer cannot relax it. The analyst should check the exit-reason mix (stop / take-profit / time) and avg_trade_return_pct against the 0.15% floor. The sandbox counted 536 trades in about 2,091 bars, which fits frequent short stop-out trades.

Backtest Review

Sharpe
-0.25
Total return
-44.15%
Max drawdown
60.12%
Trades
268
Win rate
28.0%
Profit factor
0.87

The code is a faithful completed-bar port. Both labelled fixes work: the strategy now trades (221 closed trades, 125 long and 96 short) where the literal port produced none, and the time stop measures real days.

The sample is reliable: 2021-01 to 2025-08 development period, 1,664 data days, metrics_reliable true.

Net expectancy is negative. The average trade returns -0.249% of notional against the 0.15% Hyperliquid floor. Profit factor is 0.88, Sharpe -0.21, total return -35.2%, and max drawdown 54.2% against the 30% contract limit.

Fees did not cause the loss. Commissions totalled $8.5k, while the net loss was about $35k.

QA's concern is borne out. 105 of the 221 trades closed after one bar. The 1% stop is checked on the daily close, but DOT moves about 4.5% a day, so the stop fires at whatever loss the next close prints. Losing trades averaged -4.2% of notional (worst -23.9%), not -1%.

The 28% win rate and +9.9% average win do not cover the frequent noise stop-outs. The strategy lost money in 4 of 5 calendar years (2022 -28%, 2023 -2%, 2024 -6%, 2025 -6.5%).

Buy-and-hold DOT returned about -77% over the same window. The strategy's 54% drawdown with a -35% return does not show an edge beyond partial exposure.

Iteration History

Verification failed (Layer 3 — sandbox backtest): No trades produced Bar type used: DOTUSD.HYPERLIQUID-1-DAY-LAST-EXTERNAL, Bars processed: 1390 Diagnostics: should_enter() returned a side 0 times over 1390 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

A tight percentage stop that is only checked on the bar close does not cap losses on a volatile daily market; it turns noise into frequent full-bar losses, so the stop distance has to be sized to the instrument's daily range before an RSI re-cross edge can be judged.

The backtest review returned 'abandon' for negative net expectancy on an adequate sample. Fees were not the cause ($8.5k commissions against a net loss of about $35k): the 1% stop, checked on the daily close, sat well inside DOT's roughly 4.5% daily move, so 105 trades closed after one bar and losing trades averaged -4.2% of notional. The stop and position size were fixed by the research contract, so optimization could not fix the loss.

A port of the TqSdk 'RSI' demo by Chaos onto DOTUSD.HYPERLIQUID daily bars: long-short RSI(6) 35/65 re-cross reversal evaluated on completed bars, with a 1% close-checked stop, an opposite-zone RSI take-profit, a 10-day time stop and unlevered 50%-of-equity sizing.

On the development period the analyst reviewed (2021-01 to 2025-08), 221 trades averaged -0.249% of notional against the 0.15% Hyperliquid floor, with profit factor 0.88, Sharpe -0.21, a -35.2% total return and a 54.2% max drawdown. The attached full-window backtest (2021-01-27 to 2026-10-18) was worse: 268 trades, -0.296% average trade, Sharpe -0.25, -44.1% return, 60.1% max drawdown and a 28% win rate.

Analysis

RSI

Analysis

RSI.py

Backtest and paper results are hypothetical. Trading involves risk of loss.