This strategy is a dynamic grid trading system based on the TTM indicator, which determines market trend direction by calculating exponential moving averages (EMAs) of highs and lows, and deploys a grid trading system around a dynamically updated base price. The grid’s direction and price levels adjust according to the trend, executing trades when price crosses predefined grid levels, with each trade risking a fixed percentage of account equity.
The core logic lies in TTM state calculation, implemented through the following steps:
The grid trading system adjusts dynamically based on TTM state:
This strategy combines TTM trend detection with dynamic grid trading to create an adaptive, risk-controlled trading system. Through dynamic adjustment of grid direction and price levels, the strategy can effectively adapt to different market environments. While inherent risks exist, through appropriate parameter settings and optimization measures, the strategy demonstrates good practical value and development potential.
/*backtest start: 2024-12-04 00:00:00 end: 2024-12-11 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("TTM Grid Strategy", overlay=true) // Input parameters int ttmPeriod = input.int(6, minval=1, title="TTM Period") int gridLevels = input.int(5, minval=2, title="Grid Levels") float gridSpacing = input.float(0.01, minval=0.0001, title="Grid Spacing (%)") // Calculate TTM State ttmState() => lowMA = ta.ema(low, ttmPeriod) highMA = ta.ema(high, ttmPeriod) lowThird = (highMA - lowMA) / 3 + lowMA highThird = 2 * (highMA - lowMA) / 3 + lowMA if close > highThird 1 else if close < lowThird 0 else -1 // State tracking variables var float gridBasePrice = 0.0 var int gridDirection = -1 // Determine grid state updateGridState(float currentClose, int currentState) => float newBasePrice = gridBasePrice int newDirection = gridDirection if currentState != -1 and currentState != gridDirection newBasePrice := currentClose newDirection := currentState [newBasePrice, newDirection] // Calculate grid levels calcGridLevels(float basePrice, int direction, int levels) => float[] buyLevels = array.new_float(levels) float[] sellLevels = array.new_float(levels) for i = 1 to levels multiplier = i * gridSpacing if direction == 1 // Buy grid array.set(buyLevels, i-1, basePrice * (1 - multiplier)) array.set(sellLevels, i-1, basePrice * (1 + multiplier)) else // Sell grid array.set(buyLevels, i-1, basePrice * (1 + multiplier)) array.set(sellLevels, i-1, basePrice * (1 - multiplier)) [buyLevels, sellLevels] // Execute grid trades executeGridTrades(float basePrice, int direction, int levels) => [buyLevels, sellLevels] = calcGridLevels(basePrice, direction, levels) for i = 0 to levels - 1 float buyLevel = array.get(buyLevels, i) float sellLevel = array.get(sellLevels, i) if direction == 1 // Buy grid if low <= buyLevel strategy.entry("GridBuy" + str.tostring(i), strategy.long, comment="Buy Level " + str.tostring(i)) if high >= sellLevel strategy.entry("GridSell" + str.tostring(i), strategy.short, comment="Sell Level " + str.tostring(i)) else // Sell grid if high >= buyLevel strategy.entry("GridBuy" + str.tostring(i), strategy.long, comment="Buy Level " + str.tostring(i)) if low <= sellLevel strategy.entry("GridSell" + str.tostring(i), strategy.short, comment="Sell Level " + str.tostring(i)) // Main strategy logic currentState = ttmState() [newGridBasePrice, newGridDirection] = updateGridState(close, currentState) // Update global variables if newGridBasePrice != gridBasePrice gridBasePrice := newGridBasePrice if newGridDirection != gridDirection gridDirection := newGridDirection // Execute grid trades executeGridTrades(newGridBasePrice, newGridDirection, gridLevels) // Visualization plotColor = newGridDirection == 1 ? color.green : color.red plot(newGridBasePrice, color=plotColor, style=plot.style_cross)