0bps

Strategy vault / Trend following

Dual Moving Average Crossover Tracking Strategy

This strategy calculates crossover between two groups of moving averages SMA and EMA to determine market trend direction for tracking trades. Specifically, it uses one fast and one slow moving average pair. It goes…

Author
ChaoZhang
Complexity
Intermediate · 59 lines
Parameters
11
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

This strategy calculates crossover between two groups of moving averages SMA and EMA to determine market trend direction for tracking trades.

Specifically, it uses one fast and one slow moving average pair. It goes long when the fast line crosses above the slow line, and goes short on the downward crossover. Exits occur when price drops back below the slow line or rises above the fast line. Customization of MA lengths, barred closing etc. allows parameter optimization.

The advantage of this dual MA strategy is simple and clear rules based on two dynamic MAs. Using EMA offers more sensitivity in capturing reversals. But whipsaws also occur easily during range-bound markets.

In general, the dual MA crossover tracking strategy suits trending markets for trading in the direction of momentum. But proper parameter tuning, strict stop loss and position sizing is crucial for long-term stability of this strategy.

Parameters

NameDefaultWhat it controls
v_input_12011Start Year
v_input_2trueStart Month
v_input_3trueStart Day
v_input_42050Finish Year
v_input_512Finish Month
v_input_631Finish Day
v_input_721Length MA1
v_input_8falseexponential
v_input_9trueLength MA2
v_input_10falseexponential
v_input_11falseLength bars close

Source Pine Script

/*backtest
start: 2023-08-11 00:00:00
end: 2023-09-10 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
// strategy("Moving Average Strategy of BiznesFilosof", shorttitle="MAS of BiznesFilosof", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=20, commission_type=strategy.commission.percent, commission_value=0.15, pyramiding=0)

//Period
startY = input(title="Start Year", defval = 2011)
startM = input(title="Start Month", defval = 1, minval = 1, maxval = 12)
startD = input(title="Start Day", defval = 1, minval = 1, maxval = 31)
finishY = input(title="Finish Year", defval = 2050)
finishM = input(title="Finish Month", defval = 12, minval = 1, maxval = 12)
finishD = input(title="Finish Day", defval = 31, minval = 1, maxval = 31)
//finish = input(2019, 02, 28, 00, 00)
timestart = timestamp(startY, startM, startD, 00, 00)
timefinish = timestamp(finishY, finishM, finishD, 23, 59)
window = time >= timestart and time <= timefinish ? true : false // Lenghth strategy

lma1 = input(title="Length MA1", defval = 21, minval=1)
exponential1 = input(false, title="exponential")
lma2 = input(title="Length MA2", defval = 1, minval=1)
exponential2 = input(false, title="exponential")
lbars = input(title="Length bars close", defval = 0, minval=0)

ma1 = exponential1 ? ema(close, lma1) : sma(close, lma1)
ma2 = exponential2 ? ema(close, lma2) : sma(close, lma2)

//source = close
source = ma2

//open
strategy.entry("LongEntryID", strategy.long, comment="LONG", when = crossover(ma2, ma1) and window)
strategy.entry("ShortEntryID", strategy.short, comment="SHORT", when = crossunder(ma2, ma1) and window)

if crossunder(source, ma1) and strategy.position_size > 0
    strategy.close_all()
if crossunder(ma2[lbars], ma1[lbars]) and strategy.position_size > 0 and lbars != 0
    strategy.close_all()    
if crossover(source, ma1) and strategy.position_size < 0
    strategy.close_all()
if crossover(ma2[lbars], ma1[lbars]) and strategy.position_size < 0 and lbars != 0
    strategy.close_all()      

src = close
src1 = high
src2 = low
maH = exponential1 ? ema(src1, lma1) : sma(src1, lma1)
maL = exponential1 ? ema(src2, lma1) : sma(src2, lma1)
maColor = src>maH ? green : src<maL ? red : blue

plot(ma1, title="MA1", color=maColor, linewidth=2, style=line)
plot(ma2, title="MA2", color=gray, linewidth=1, style=line)

Published by ChaoZhang on the FMZ strategy square · last modified 2023-09-11. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Dual-Moving-Average-Crossover-Tracking-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open