To make our community more profitable we decided to start a series in which we will review open-source TradingView strategies. The aim of the review is to select a strategy (or a number of strategies) from TradingView and run a reality check on it, optimize it and convert it into alerts, so you can set it up as a bot on the WunderTrading platform.

Video overview
What we will provide
Open-strategy source
Strategy adjustment for particular exchange, pair, and timeframe
Backtest
This week we decided to go with the new MACD strategy for the Bitcoin Perpetual (BTC-Perp). This strategy is based on the trend-following momentum indicator. Similarly to our RSI-VWAP version 2 we included the Money Flow index as an additional point for entry. This strategy shows a good stable profit curve and has a significant number of observations in the backtest to confirm the results.
IMPORTANT
Input Partial take profits in your WunderTrading Bot settings
This is a trend strategy and works better in the trending market
We added the trend identifier using the EMA and SMA interaction
We added inputs for the period selection, so you could see how the strategy is performing on a monthly basis.
ATR for Stop Loss
MFI was added for the additional entries.
Partial Take-profits
Settings
Applicable to FTX: BTC-PERP 30 min
Input | Value |
Period | 39 |
Fast Length | 7 |
Slow Length | 23 |
Source | close |
Signal Smoothing | 10 |
Length | 15 |
Lower | 12 |
Upper | 80 |
Long Take Profit 1% | 1 |
Long Take Profit 1 Qty | 20 |
Trailing Stop | 1.3 |
SL Multiplier | 2 |
ATR Period | 40 |
Strategy script code
You can copy this code and paste it into your TradingView
//(c) Wunderbit Trading
//@version=4
strategy("MACD Strategy", overlay=false, pyramiding=0, commission_type=strategy.commission.percent, commission_value=0.07, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, currency = currency.USD)
// FUNCTIONS
Ema(src,p) =>
ema = 0.
sf = 2/(p+1)
ema := nz(ema[1] + sf*(src - ema[1]),src)
Sma(src,p) => a = cum(src), (a - a[max(p,0)])/max(p,0)
Atr(p) =>
atr = 0.
Tr = max(high - low, max(abs(high - close[1]), abs(low - close[1])))
atr := nz(atr[1] + (Tr - atr[1])/p,Tr)
/// TREND
ribbon_period = input(39, "Period", step=1)
leadLine1 = ema(close, ribbon_period)
leadLine2 = sma(close, ribbon_period)
// p3 = plot(leadLine1, color= #53b987, title="EMA", transp = 50, linewidth = 1)
// p4 = plot(leadLine2, color= #eb4d5c, title="SMA", transp = 50, linewidth = 1)
// fill(p3, p4, transp = 60, color = leadLine1 > leadLine2 ? #53b987 : #eb4d5c)
//Upward Trend
UT=leadLine2 < leadLine1
DT=leadLine2>leadLine1
// MACD
fast_length = input(title="Fast Length", type=input.integer, defval=7)
slow_length = input(title="Slow Length", type=input.integer, defval=23)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 10)
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=false)
// Plot colors
col_grow_above = #26A69A
col_grow_below = #FFCDD2
col_fall_above = #B2DFDB
col_fall_below = #EF5350
col_macd = #0094ff
col_signal = #ff6a00
// Calculating
fast_ma = sma_source ? Sma(src, fast_length) : Ema(src, fast_length)
slow_ma = sma_source ? Sma(src, slow_length) : Ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? Sma(macd, signal_length) : Ema(macd, signal_length)
hist = macd - signal
//plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 )
plot(macd, title="MACD", color=col_macd, transp=0)
plot(signal, title="Signal", color=col_signal, transp=0)
/// MFI
source = hlc3
length = input(15, minval=1)
lower = input(12, minval=0, maxval=50)
upper = input(80, minval=50, maxval=100)
// DrawMFI_f=input(true, title="Draw MFI?", type=bool)
HighlightBreaches=input(true, title="Highlight Oversold/Overbought?")
// MFI
upper_s = sum(volume * (change(source) <= 0 ? 0 : source), length)
lower_s = sum(volume * (change(source) >= 0 ? 0 : source), length)
mf = rsi(upper_s, lower_s)
mfp = plot(mf, color=color.new(color.gray,0), linewidth=1)
top = hline(upper, color=color.new(color.gray, 100), linewidth=1, editable=false)
bottom = hline(lower, color=color.new(color.gray,100), linewidth=1, editable=false)
hline(0, color=color.new(color.black,100), editable=false)
hline(100, color=color.new(color.black,100), editable=false)
// Breaches
b_color = (mf > upper) ? color.new(color.red,70) : (mf < lower) ? color.new(color.green,60) : na
bgcolor(HighlightBreaches ? b_color : na)
fill(top, bottom, color=color.gray, transp=75)
// TAKE PROFIT AND STOP LOSS
long_tp1_inp = input(1, title='Long Take Profit 1 %', step=0.1)/100
long_tp1_qty = input(20, title="Long Take Profit 1 Qty", step=1)
long_trailing = input(1.3, title='Trailing Stop Long', step=0.1) / 100
long_take_level_1 = strategy.position_avg_price * (1 + long_tp1_inp)
// Stop Loss
multiplier = input(2, "SL Mutiplier", minval=1, step=0.1)
ATR_period=input(40,"ATR period", minval=1, step=1)
// Strategy
entry_long=crossover(macd,signal) or (crossover(mf,lower) and leadLine2 < leadLine1)
entry_price_long=valuewhen(entry_long,close,0)
SL_floating_long = entry_price_long - multiplier*Atr(ATR_period)
exit_long= close < SL_floating_long
///// BACKTEST PERIOD ///////
testStartYear = input(2018, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)
testStopYear = input(9999, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)
testPeriod() =>
time >= testPeriodStart and time <= testPeriodStop ? true : false
if testPeriod()
if UT
strategy.entry("long", strategy.long, when=entry_long == true, comment="Insert Enter Long commnet")
strategy.exit("TP1","long", qty_percent=long_tp1_qty, limit=long_take_level_1)
strategy.exit("Trail stop","long", trail_points=entry_price_long * long_trailing / syminfo.mintick, trail_offset=entry_price_long * long_trailing / syminfo.mintick)
strategy.close("long", exit_long == true, comment="Insert exit long commnet" )