0bps

Strategy vault / Trend following

MACD Multi Indicator Trend Following Strategy

This strategy integrates MACD, moving averages, alligator and more to identify trend direction for trend following. The logic is: 1. Compute MACD short, long and histogram lines 2. Use histogram direction to…

Author
ChaoZhang
Complexity
Intermediate · 161 lines
Parameters
21
Backtest bar
30m · intraday
Tested on
BTC/USDT · futures

Strategy Logic

This strategy integrates MACD, moving averages, alligator and more to identify trend direction for trend following.

The logic is:

  1. Compute MACD short, long and histogram lines

  2. Use histogram direction to determine short-term trend

  3. Plot multiple moving averages to gauge price position

  4. Alligator lines judge overall trend strength

  5. Combining above indicators, go long/short when aligned

  6. Stop loss when indicators flip for early reversal

By synthesizing multiple indicators, it aims to trade strong trends and cut losses early when reversals happen.

Advantages

  • MACD judges short-term trend and strength

  • MA positions determine mid- to long-term trends

  • Alligator shows overall trend strength

  • Multiple indicators improve accuracy

Risks

  • Extensive parameter optimization needed

  • Conflicting signals hard to interpret

  • Lagging issues with MAs etc

Summary

This strategy attempts to comprehensively determine trend direction using multiple indicators. But lagging issues and signal conflicts warrant caution despite optimization.

Parameters

NameDefaultWhat it controls
v_input_112Fast Length
v_input_226Slow Length
v_input_3_close0Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4
v_input_int_19Signal Smoothing
v_input_string_10Oscillator MA Type: EMA | SMA
v_input_string_20Signal Line MA Type: EMA | SMA
v_input_int_2200Length
v_input_10_close0Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4
v_input_int_3falseOffset
v_input_int_413Jaw Length
v_input_int_58Teeth Length
v_input_int_65Lips Length
v_input_118Jaw Offset
v_input_125Teeth Offset
v_input_133Lips Offset
v_input_4#2962FF(?Color Settings)MACD Line
v_input_5#FF6D00Signal Line
v_input_6#26A69A(?Histogram)Above   Grow
v_input_7#B2DFDBFall
v_input_8#FFCDD2Below Grow
v_input_9#FF5252Fall

Source Pine Script

/*backtest
start: 2023-09-06 00:00:00
end: 2023-09-13 00:00:00
period: 30m
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("5MSM VISHNU", overlay=true,process_orders_on_close=true)
//indicator(title="mahakaal", shorttitle="mahakaal", timeframe="", timeframe_gaps=true)

green = #26A69A
red = #FF0000
Yellow = #fcf932

// Getting inputs
fast_length = input(title="Fast Length", defval=12)
slow_length = input(title="Slow Length", defval=26)
src3 = input(title="Source", defval=close)
signal_length = input.int(title="Signal Smoothing",  minval = 1, maxval = 50, defval = 9)
sma_source = input.string(title="Oscillator MA Type",  defval="EMA", options=["SMA", "EMA"])
sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"])
// Plot colors
col_macd = input(#2962FF, "MACD Line  ", group="Color Settings", inline="MACD")
col_signal = input(#FF6D00, "Signal Line  ", group="Color Settings", inline="Signal")
col_grow_above = input(#26A69A, "Above   Grow", group="Histogram", inline="Above")
col_fall_above = input(#B2DFDB, "Fall", group="Histogram", inline="Above")
col_grow_below = input(#FFCDD2, "Below Grow", group="Histogram", inline="Below")
col_fall_below = input(#FF5252, "Fall", group="Histogram", inline="Below")
// Calculating
fast_ma = sma_source == "SMA" ? ta.sma(src3, fast_length) : ta.ema(src3, fast_length)
slow_ma = sma_source == "SMA" ? ta.sma(src3, slow_length) : ta.ema(src3, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal == "SMA" ? ta.sma(macd, signal_length) : ta.ema(macd, signal_length)
hist = macd - signal
//hline(0, "Zero Line", color=color.new(#787B86, 50))

//@version=5
//indicator(title="Moving Average Exponential", shorttitle="EMA", overlay=true, timeframe="", timeframe_gaps=true)
len = input.int(200, minval=1, title="Length")
src2 = input(close, title="Source")
offset = input.int(title="Offset", defval=0, minval=-500, maxval=500)
Bahubali = ta.ema(src2, len)
//plot(out, title="EMA", color=color.blue, offset=offset)

//@version=5
//indicator(title="Williams Alligator", shorttitle="Alligator", overlay=true, timeframe="", timeframe_gaps=true)
smma(src, length) =>
	smma =  0.0
	smma := na(smma[1]) ? ta.sma(src, length) : (smma[1] * (length - 1) + src) / length
	smma
jawLength = input.int(13, minval=1, title="Jaw Length")
teethLength = input.int(8, minval=1, title="Teeth Length")
lipsLength = input.int(5, minval=1, title="Lips Length")
jawOffset = input(8, title="Jaw Offset")
teethOffset = input(5, title="Teeth Offset")
lipsOffset = input(3, title="Lips Offset")
jaw = smma(hl2, jawLength)
teeth = smma(hl2, teethLength)
lips = smma(hl2, lipsLength)
//plot(jaw, "Jaw", offset = jawOffset, color=#2962FF)


if (hist > 9)

    hist := 10


if (hist < -9)

    hist := -10

// Compose alert message
// Entry
alert_msg_long_entry =  
             "BUY ? {{ticker}} CE " + str.tostring(math.floor((close - 100)/100)*100)       + "\n"   + 
             "####################\n\n" + 
             "{{strategy.order.id}}? Target 1:  "         + str.tostring(math.round(close + 35))       + "\n"   + 
             "{{strategy.order.id}}? Target 2:  "         + str.tostring(math.round(close + 45))       + "\n"   +  
             "\n"   +  
             "{{strategy.order.id}} Stop Loss: "         + str.tostring(math.round(close - 30))       + "\n\n" + 
             "\n"   + 
             "ENTRY PRICE: "                              + str.tostring(math.round(close))       + "\n\n" +
             "Current time: {{timenow}} \n"        +      
             "Education purpose only"
             
// Entry
alert_msg_short_entry =  
             "BUY ? {{ticker}} PE " + str.tostring(math.floor((close + 100)/100)*100)       + "\n"   + 
             "####################\n\n" + 
             "{{strategy.order.id}}? Target 1:  "         + str.tostring(math.round(close - 35))       + "\n"   + 
             "{{strategy.order.id}}? Target 2:  "         + str.tostring(math.round(close - 45))       + "\n"   +  
             "\n"   +  
             "ENTRY PRICE: "                             + str.tostring(math.round(close))       + "\n\n" +
             "{{strategy.order.id}} Stop Loss: "         + str.tostring(math.round(close + 30))       + "\n\n" + 
             "Current time: {{timenow}} \n"     +         
             "Education purpose only"
// EXIT
alert_msg_long_exit =  
             "? EXIT {{ticker}} CE LONG POSITION  ! \n" +
             "EXIT PRICE: "                  + str.tostring(math.round(close))            + "\n"   + 
             "\n"   + 
             "Dont wait for exit msg in this ? CHANNEL !! \n" +
             "For ?% accurate & profitable ??? EXIT: \n" +
             "BUY our 'triDEV' tradingview indicator strategy\n" +
             "https://wa.me/917020641496"
             

// EXIT
alert_msg_short_exit =  
             "? EXIT {{ticker}} PE Short POSITION  ! \n" +
             "EXIT PRICE: "                  + str.tostring(math.round(close))            + "\n"   + 
             "\n"   + 
             "Dont wait for exit msg in this ? CHANNEL !! \n" +
             "For ?% accurate & profitable ??? EXIT: \n"   +
             "BUY our 'triDEV' tradingview indicator strategy\n" +
             "https://wa.me/917020641496"
             
             



tyme = time("1440", "0920-1515")

bullishtrend = ((hist > 0)  and (close > lips ) and (low > lips ) and (close > Bahubali) and (lips > jaw) and tyme)
bearishtrend = ((hist < 0)  and (close < lips ) and (high < lips ) and (close < Bahubali) and (lips < jaw) and tyme)
//plot(hist, title="Histogram", style=plot.style_columns, color=(hist > 0 ? ( bullishtrend ? green : Yellow ) : ( bearishtrend ? red : Yellow ) ))

strategy.entry("long", strategy.long, when = bullishtrend , alert_message = alert_msg_long_entry )
strategy.entry("short",strategy.short,when = bearishtrend , alert_message = alert_msg_short_entry)


longexit = (close < lips)  or time("1440", "1515-1530") or (hist <= 0) //or (close < Bahubali)
shortexit = (close > lips) or time("1440", "1515-1530")or (hist >= 0) //or (close > Bahubali)
//strategy.exit("long tsl", "long", trail_points = close * 0.01 / syminfo.mintick, trail_offset = close * 0.01 / syminfo.mintick)
//strategy.exit("shoty tsl", "short", trail_points = close * 0.01 / syminfo.mintick, trail_offset = close * 0.01 / syminfo.mintick)
strategy.exit("long TSL", "long", limit = lips ,when = (longexit), alert_message = alert_msg_long_exit)
strategy.exit("short TSL","short",limit = lips ,when = (shortexit), alert_message = alert_msg_short_exit)

//PLOT FIXED SLTP LINE
// LONG POSITION
long_take_level_1 = strategy.position_avg_price + 35
long_take_level_2 = strategy.position_avg_price + 40
long_stop_level = strategy.position_avg_price - 30

plot(strategy.position_size > 0 ? long_take_level_1 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="1st Long Take Profit")
plot(strategy.position_size > 0 ? long_take_level_2 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="2nd Long Take Profit")
plot(strategy.position_size > 0 ? long_stop_level : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Long Stop Loss")

//PLOT FIXED SLTP LINE
// SHORT POSITION
SHORT_take_level_1 = strategy.position_avg_price - 35
SHORT_take_level_2 = strategy.position_avg_price - 40
SHORT_stop_level = strategy.position_avg_price + 30

plot(strategy.position_size < 0 ? SHORT_take_level_1 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="1st SHORT Take Profit")
plot(strategy.position_size < 0 ? SHORT_take_level_2 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="2nd SHORT Take Profit")
plot(strategy.position_size < 0 ? SHORT_stop_level : na, style=plot.style_linebr, color=color.red, linewidth=1, title="SHORT Stop Loss")

Published by ChaoZhang on the FMZ strategy square · last modified 2023-09-14. 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/MACD-Multi-Indicator-Trend-Following-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