Strategies
Hummingbot GridStrike port: long-side static grid of 190 post-only buy levels from 0.38 to 0.75, each closed by a post-only take-profit 0.1% above its fill, whole grid flattened at market if mid falls to 0.35, re-armed when price is back in the band (WLDUSDT.OKX USDT swap, 1-MINUTE, net position, 2x margin, 35% of equity grid budget)
Outcome: Abandoned
HummingbotWldOkxSwapGridStrike
Outcome Summary
HummingbotWldOkxSwapGridStrike ported hummingbot's GridStrike as a long-only 190-level buy grid on WLDUSDT.OKX at 2x leverage, corrected from an earlier attempt that failed on a spot venue. After 3 iterations, the backtest showed negative expectancy: an average trade return of -0.19% of notional, and in the full report a -15.8% return, Sharpe -0.30 and 39% max drawdown over 426 trades. Most equity swings came from unrealized inventory that tracked WLD's direction rather than from grid profits. The analyst abandoned it at backtest review because the frozen 0.1% take-profit is structurally consumed by costs, so optimization and the later stages (analyst, risk review, promotion) were never reached.
Hypothesis
Implementation
Hummingbot GridStrike port on WLDUSDT.OKX swap (1-minute bars): one-sided BUY grid with ~190 linear levels from start_price to end_price, built when the close is inside the band. Each bar tops up post-only buy limits on the nearest free levels until max_open_orders are resting. Each filled level gets a post-only reduce-only take-profit sell at level*(1+0.001). If the close falls to limit_price or below, all orders are cancelled and the position is closed at market; the grid re-arms when price is back inside the band. Grid budget is 35% of equity when the grid is created, min order is 0.5% of the budget, account leverage is 2x.
Iteration 3 fixes the Layer 1.5 failure 'conflicting top-level and parameter leverage' and moves the port to the amended hypothesis. Venue is now WLDUSDT.OKX swap with leverage 2.0 at top level and in parameters, the parameter names are the research plan's (total_amount_quote_pct_equity, min_order_amount_quote_frac, min_order_margin, order_frequency_s, activation_bounds=None), and _optimization_plan is the research plan verbatim. Per the hypothesis, the only flatten is limit_price, so the old upper-band drain was removed. The 3 s, batch-1 throttle becomes a per-bar top-up to max_open_orders. The bar close stands in for mid. Leverage only adds margin headroom in position_size; exposure is set by the budget.
Verification Results
Optional, for the Research Lead or the next revision: add the source's end_price exit (cancel, flatten remaining lots at market, set grid_active=False) so the port matches the executor exactly. No change is needed to pass this review.
The pinned GridExecutor (grid_executor.py, control_triple_barrier) has a take_profit_condition after the limit_price check: for side BUY, `mid_price > config.end_price` closes the executor with CloseType.TAKE_PROFIT. With keep_position=False, any remaining lots are then closed and the controller waits until mid is back in the band before creating a new executor. The hypothesis lists limit_price as the only flatten, and the code follows the hypothesis, so this is not a mismatch with the spec. The practical effect is small: by the time mid is above 0.75, almost every lot's 0.1% take-profit (at most ~0.7508) has already filled. What differs is that the port keeps the old grid, sized to the equity at its creation, with its top two buys resting. The source would rebuild a new grid sized to the equity at re-entry.
Keep a set of the lot indices that have a live buy_id, sell_id or quantity, and loop only over that set. Keep the free-level candidates for the nearest-level search in a sorted structure, e.g. bisect around the current price. The logic stays the same.
Runtime: on every 1-minute bar, _reconcile_lots, _place_lot_take_profits and _place_grid_buys each loop over all ~190 levels and do cache.order lookups. Over ~1.7M bars of history, the sandbox projects ~5,000 s per baseline backtest (runtime_review_required=true). That is expensive for a walk-forward with at least 25 trials per window.
None required.
min_bars_required() overrides the base method and returns 1. This is deliberate and consistent with the contract's warmup_bars=1, since a grid needs no indicator history. Noted only because Layer 1 flagged the override.
Each grid cycle earns a 0.1% take-profit against a 0.04% maker round trip, so the net is about 0.06% of the lot's notional. That is below the analyst's 0.10-0.15% per-trade floor, so the full backtest's avg_trade_return_pct will probably fail the floor unless the floor is applied net of maker fees. The P&L is many small wins (the 0.1% take-profits) against a rare large loss (the 0.35 flatten). Each limit_price event costs about 13% of equity in the worst case. Judge the result on drawdown and the frequency of limit_price events, not on win rate. On bar data, a touch fills a limit order with probability 0.7-0.95 and queue position is not modelled. Fills at an exact 0.1% take-profit are therefore probably optimistic relative to a real post-only queue. The source decides every 3 s; this port decides every 1 minute (20x). The mechanism is resting limit orders, which the engine can simulate. It is not a speed or queue race, so lesson L169 is noted here but does not block.
Backtest Review
- Sharpe
- -0.30
- Total return
- -0.16%
- Max drawdown
- 0.39%
- Trades
- 426
- Win rate
- 13.6%
- Profit factor
- 0.74
The trades match the port. All 163 are long. Lot sizes are about 300-500 WLD (about $180, which is 35% of equity spread over 190 levels). Entries rest at grid levels and exits come about 0.1% above, mostly within 1-10 minutes. The grid stays idle while price is outside the 0.38-0.75 band, which explains the empty months from 2023 to early 2025.
Risk stayed contained. Max drawdown is 13.3%, against the contract's 25% and buy-and-hold WLD's fall of more than 80% from its 2023-24 levels, so the result is not just market exposure. There was no liquidation.
Net expectancy is negative on a usable sample. A trade here is a full open-to-flat cycle of the net position, and there are 163 of them. The average trade return is -0.19% of notional, against an OKX floor of 0.15%. Profit factor is 0.97, Sharpe -0.04, total return -1.9%, and summed closed-trade P&L is -$10.
The per-lot economics leave nothing after costs. The take-profit is a fixed 0.1%, the maker round trip costs 0.04%, and modelled costs bring the net near zero. In 125 of the 163 closed trades the exit price is above the entry price, yet the price P&L is negative. For example, 261 WLD bought at 0.7011 and sold at 0.7018 is +$0.18 gross, but it is booked as -$0.007 with $0.073 commission. That is consistent with an extra modelled cost per fill (impact is folded into the result) roughly equal to the remaining edge. I have not verified the mechanism.
Most of the equity movement is unrealized inventory. Dec 2025 was -7.4%, Jan 2026 +11.5% and Feb 2026 -11.4%, while realized P&L is about $0. The month-to-month result follows WLD's direction, not the grid spread.
Activity is concentrated: 109 of the 163 closed trades fall in Feb 2026.
Iteration History
Verification failed (Layer 1.5 — hypothesis/config consistency) [class=hypothesis_mismatch]: - optimization_plan conflicting top-level and parameter leverage
Verification failed (Layer 3 — sandbox backtest): Invalid `value` for quantity: 0.0009999999999994458 was rounded to zero due to size increment 0.001 and size precision 3 Bar type used: WLDUSDT.OKX_SPOT-1-MINUTE-LAST-EXTERNAL, Bars processed: 0 Ensure your strategy produces trades with the given data and parameters.
Outcome Summary
A grid whose fixed per-level take-profit (0.1%) is close to round-trip fees plus modelled impact cannot clear the per-trade cost floor, and tuning the band or order count will not change that. A viable version needs a wider per-level spread, which makes it a different strategy from the author's defaults.
The backtest review abandoned it before optimization. Average trade return was -0.19% of notional, below the 0.15% OKX floor. The fixed 0.1% take-profit leaves almost nothing after the 0.04% maker round trip and modelled impact costs, and the take-profit, spacing and sizing were frozen in the research contract. The tunable band and order-count parameters could not raise the per-lot edge.
A faithful port of hummingbot's GridStrike on the WLDUSDT.OKX USDT swap: a long-only static grid of about 190 post-only buy levels between 0.38 and 0.75, each closed by a post-only take-profit 0.1% above its fill, with the whole grid flattened at market if price falls to 0.35. It ran at 2x account leverage with a grid budget of 35% of equity.
In the backtest report (Jul 2023 to Oct 2026, 1-minute bars), the strategy returned -15.8% with a Sharpe of -0.30, a 39.0% max drawdown, a 13.6% win rate, a profit factor of 0.74 and an average trade return of -0.19% of notional over 426 long trades. The backtest review cites a different, smaller sample (Jul 2023 to Feb 2026, 163 closed trades): -1.9% total return, Sharpe -0.04, profit factor 0.97, 13.3% drawdown and the same -0.19% average trade return.
Analysis
GridStrike
Analysis
grid_strike.py
Backtest and paper results are hypothetical. Trading involves risk of loss.