So you want the signal for buy and short only appear when there is a swing i.e. change from Long to Short or Short to Long avoiding repeated same direction signals.
Code: Select all
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © podolkerod
//@version=5
varip str_script_title = "[Learn] DCA using signal"
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------{
indicator(str_script_title, overlay=true) // timeframe="", timeframe_gaps=true)
// Colors
varip color_ma01 = #d1d4dc // #f5eb5d // #ffe0b2
varip color_ma02 = #f1c21b // #f5b771 // #33DBF7
varip color_ma03 = #00e2ff // #f57d51 // #FFA7CF
varip color_ma04 = #f55151 // #EBADF7
varip color_ma05 = #cc125b // #FF8A5E
varip color_ma06 = #b249c3
varip color_supertrendUp = #2ABEB3
varip color_supertrendDn = #FF7A65
varip color_LongA = #2ABEB3
varip color_LongB = #00C09F
varip color_LongC = #00C6C7
varip color_LongD = #00BA45
varip color_LongE = #00B1FF
varip color_LongF = #008AC4
varip color_ShrtA = #E61C5D
varip color_ShrtB = #FF791B
varip color_ShrtC = #FF55F3
varip color_ShrtD = #FF4766
varip color_ShrtE = #FF7A65
varip color_ShrtF = #E59C24
varip color_enterL_Price = #ffffff // #f7894980
varip color_longSL = #4a0d70
varip color_longTP = #53B71A
varip color_longSLhit = #961EE1
varip color_longTPhit = #53B71A
varip color_enterS_Price = #ffffff // #f7894980
varip color_shortSL = #4a0d70
varip color_shortTP = #1ECBE1
varip color_shortSLhit = #961EE1
varip color_shortTPhit = #1AA2B7
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
// MOVING AVERAGES
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════{
i_emaLength1 = input.int(title="EMA 1", defval=8)
i_emaLength2 = input.int(title="EMA 2", defval=20)
i_emaLength3 = input.int(title="EMA 3", defval=50)
i_emaLength4 = input.int(title="EMA 4", defval=100)
ema1 = ta.ema(close, i_emaLength1)
ema2 = ta.ema(close, i_emaLength2)
ema3 = ta.ema(close, i_emaLength3)
ema4 = ta.ema(close, i_emaLength4)
plot(ema1, color=color.blue)
plot(ema2, color=color.green)
plot(ema3, color=color.red)
plot(ema4, color=color.yellow)
//---------------------------------------------------------------------------------------------------------------------------------
// END of MOVING AVERAGES
//---------------------------------------------------------------------------------------------------------------------------------}
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
// SIGNAL FILTERS & RULES
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════{
// Inputs
//----------------------------------//----------------------------------//{
varip groupShowSignals = "Show/Hide Signals"
i_draw_LongA = input(false, 'Long A', group = groupShowSignals, inline="L01")
i_draw_LongB = input(false, 'Long B', group = groupShowSignals, inline="L01")
i_draw_LongC = input(false, 'Long C', group = groupShowSignals, inline="L01")
i_draw_ShrtA = input(false, 'Short A', group = groupShowSignals, inline="L02")
i_draw_ShrtB = input(false, 'Short B', group = groupShowSignals, inline="L02")
i_draw_ShrtC = input(false, 'Short C', group = groupShowSignals, inline="L02")
// Filters
ema1_crossOver_ema2 = ta.crossover(ema1, ema2)
ema2_crossOver_ema3 = ta.crossover(ema2, ema3)
ema3_crossOver_ema4 = ta.crossover(ema3, ema4)
ema1_crossUnder_ema2 = ta.crossunder(ema1, ema2)
ema2_crossUnder_ema3 = ta.crossunder(ema2, ema3)
ema3_crossUnder_ema4 = ta.crossunder(ema3, ema4)
// Entry Exit Conditions
entryLong_A = ema1_crossOver_ema2
entryShrt_A = ema2_crossOver_ema3
entryLong_B = ema3_crossOver_ema4
entryShrt_B = ema1_crossUnder_ema2
entryLong_C = ema2_crossUnder_ema3
entryShrt_C = ema3_crossUnder_ema4
entryLong_All = entryLong_A or entryLong_B or entryLong_C
entryShrt_All = entryShrt_A or entryShrt_B or entryShrt_C
signal_Off = 0
//----------------------------------//----------------------------------//}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
// END OF SIGNAL FILTERS & RULES
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------}
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
// STRATEGY TESTER
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════{
// Input Signal
//----------------------------------//----------------------------------//{
varip groupBacktestStrat = "Visualize Backtest"
i_trigger_entryL = input.string(title="Long OP | Exit Trigger", defval="OFF", inline="line_bt_signal_0",
options=[
"LONG ALL",
"Long A", "Long B", "Long C",
"SHORT ALL",
"Short A", "Short B", "Short C",
"OFF"
], group = groupBacktestStrat)
i_trigger_exitL = input.string(title="", defval="OFF", inline="line_bt_signal_0",
options=[
"LONG ALL",
"Long A", "Long B", "Long C",
"SHORT ALL",
"Short A", "Short B", "Short C",
"OFF"
], group = groupBacktestStrat)
i_trigger_entryS = input.string(title="Short OP | Exit Trigger", defval="OFF", inline="line_bt_signal_1",
options=[
"LONG ALL",
"Long A", "Long B", "Long C",
"SHORT ALL",
"Short A", "Short B", "Short C",
"OFF"
], group = groupBacktestStrat)
i_trigger_exitS = input.string(title="", defval="OFF", inline="line_bt_signal_1",
options=[
"LONG ALL",
"Long A", "Long B", "Long C",
"SHORT ALL",
"Short A", "Short B", "Short C",
"OFF"
], group = groupBacktestStrat)
// Declarations
enterL =
i_trigger_entryL=="LONG ALL" ? entryLong_All :
i_trigger_entryL=="Long A" ? entryLong_A :
i_trigger_entryL=="Long B" ? entryLong_B :
i_trigger_entryL=="Long C" ? entryLong_C :
i_trigger_entryL=="SHORT ALL" ? entryShrt_All :
i_trigger_entryL=="Short A" ? entryShrt_A :
i_trigger_entryL=="Short B" ? entryShrt_B :
i_trigger_entryL=="Short C" ? entryShrt_C :
signal_Off
exitL =
i_trigger_exitL=="LONG ALL" ? entryLong_All :
i_trigger_exitL=="Long A" ? entryLong_A :
i_trigger_exitL=="Long B" ? entryLong_B :
i_trigger_exitL=="Long C" ? entryLong_C :
i_trigger_exitL=="SHORT ALL" ? entryShrt_All :
i_trigger_exitL=="Short A" ? entryShrt_A :
i_trigger_exitL=="Short B" ? entryShrt_B :
i_trigger_exitL=="Short C" ? entryShrt_C :
signal_Off
enterS =
i_trigger_entryS=="LONG ALL" ? entryLong_All :
i_trigger_entryS=="Long A" ? entryLong_A :
i_trigger_entryS=="Long B" ? entryLong_B :
i_trigger_entryS=="Long C" ? entryLong_C :
i_trigger_entryS=="SHORT ALL" ? entryShrt_All :
i_trigger_entryS=="Short A" ? entryShrt_A :
i_trigger_entryS=="Short B" ? entryShrt_B :
i_trigger_entryS=="Short C" ? entryShrt_C :
signal_Off
exitS =
i_trigger_exitS=="LONG ALL" ? entryLong_All :
i_trigger_exitS=="Long A" ? entryLong_A :
i_trigger_exitS=="Long B" ? entryLong_B :
i_trigger_exitS=="Long C" ? entryLong_C :
i_trigger_exitS=="SHORT ALL" ? entryShrt_All :
i_trigger_exitS=="Short A" ? entryShrt_A :
i_trigger_exitS=="Short B" ? entryShrt_B :
i_trigger_exitS=="Short C" ? entryShrt_C :
signal_Off
// Input TP SL (%)
varip groupBacktestTPSL = "TP / SL"
i_strat_longTPpercent = input.float(title="Long TP | Long SL (%)", minval=0.0, step=0.1, defval=0.66, inline='L01', group = groupBacktestTPSL) / 100
i_strat_longSLpercent = input.float(title="", minval=0.0, step=0.1, defval=5.1, inline='L01', group = groupBacktestTPSL) / 100
i_strat_shrtTPpercent = input.float(title="Short TP | Short SL (%)", minval=0.0, step=0.1, defval=0.66, inline='L02', group = groupBacktestTPSL) / 100
i_strat_shrtSLpercent = input.float(title="", minval=0.0, step=0.1, defval=5.1, inline='L02', group = groupBacktestTPSL) / 100
//----------------------------------//----------------------------------//}
// Calculation
//----------------------------------//----------------------------------//{
// Detect what was last signal (long or short)
enterL_enterS = 0
last_enterL = enterL and (nz(enterL_enterS[1]) == 0 or nz(enterL_enterS[1]) == -1)
last_enterS = enterS and (nz(enterL_enterS[1]) == 0 or nz(enterL_enterS[1]) == 1)
enterL_enterS := last_enterL ? 1 : last_enterS ? -1 : enterL_enterS[1]
// Entry price
enterL_Price = ta.valuewhen(last_enterL, close, 0)
enterS_Price = ta.valuewhen(last_enterS, close, 0)
// Fixed TP SL prices
longSL = enterL_Price * (1 - i_strat_longSLpercent)
shortSL = enterS_Price * (1 + i_strat_shrtSLpercent)
longTP = enterL_Price * (1 + i_strat_longTPpercent)
shortTP = enterS_Price * (1 - i_strat_shrtTPpercent)
// Remove first bar for SL/TP (you can't enter a trade at bar close THEN hit your SL on that same bar)
longBar1 = ta.barssince(last_enterL)
longBar2 = longBar1 >= 1 ? true : false
shortBar1 = ta.barssince(last_enterS)
shortBar2 = shortBar1 >= 1 ? true : false
// Check for SL hit during a bar
longSLhit = enterL_enterS==1 and longBar2 and low < longSL
shortSLhit = enterL_enterS==-1 and shortBar2 and high > shortSL
// Check for TP hit during bar
longTPhit = enterL_enterS==1 and longBar2 and high > longTP
shortTPhit = enterL_enterS==-1 and shortBar2 and low < shortTP
// Reset enterL_enterS if SL/TP hit during bar
enterL_enterS := (enterL_enterS==1 or enterL_enterS==0) and longBar2 and (longSLhit or longTPhit) ? 0 :
(enterL_enterS==-1 or enterL_enterS==0) and shortBar2 and (shortSLhit or shortTPhit) ? 0 : enterL_enterS
//----------------------------------//----------------------------------//}
// Plot
//----------------------------------//----------------------------------//{
// Plot Entry Price
plot(enterL_enterS==1 ? enterL_Price : na, style=plot.style_linebr, color=color_enterL_Price, linewidth=2, title="Entry Long")
plot(enterL_enterS==-1 ? enterS_Price : na, style=plot.style_linebr, color=color_enterS_Price, linewidth=2, title="Entry Short")
// plot TP SL lines
plot(enterL_enterS==1 ? longSL : na, style=plot.style_linebr, color=color_longSL, linewidth=1, title="Long Fixed SL")
plot(enterL_enterS==-1 ? shortSL : na, style=plot.style_linebr, color=color_shortSL, linewidth=1, title="Short Fixed SL")
plot(enterL_enterS==1 ? longTP : na, style=plot.style_linebr, color=color_longTP, linewidth=1, title="Long Fixed TP")
plot(enterL_enterS==-1 ? shortTP : na, style=plot.style_linebr, color=color_shortTP, linewidth=1, title="Short Fixed TP")
// Plot SL Hit
plotshape(longSLhit, style=shape.labelup, location=location.belowbar, color=color_longSLhit, size=size.tiny, title="Long SL Hit", text=" Long SL", textcolor=color.white)
plotshape(shortSLhit, style=shape.labeldown, location=location.abovebar, color=color_shortSLhit, size=size.tiny, title="Short SL Hit", text=" Short SL", textcolor=color.white)
// Plot TP Hit
plotshape(longTPhit, style=shape.labeldown, location=location.abovebar, color=color_longTPhit, size=size.tiny, title="Long TP Hit", text="Long TP", textcolor=color.white)
plotshape(shortTPhit, style=shape.labelup, location=location.belowbar, color=color_shortTPhit, size=size.tiny, title="Short TP Hit", text="Short TP", textcolor=color.white)
//----------------------------------//----------------------------------//}
// Connector for [BT] Robotempur or TESW - Robotempur
//----------------------------------//----------------------------------//{
strat_trigger = 0
var trade_cond = 0
var StopLoss = float ( na )
var TakeProfit = float ( na )
var EntryPrice = float ( na )
if enterL
StopLoss := enterL_Price * ( 1 - i_strat_longSLpercent )
TakeProfit := enterL_Price * ( 1 + i_strat_longTPpercent )
EntryPrice := enterL_Price
trade_cond := 1
strat_trigger := 1
else if enterS
StopLoss := enterS_Price * ( 1 + i_strat_shrtSLpercent )
TakeProfit := enterS_Price * ( 1 - i_strat_shrtTPpercent )
EntryPrice := enterS_Price
trade_cond := -1
strat_trigger := -1
strat_TP_long = longTPhit
strat_SL_long = longSLhit
strat_TP_shrt = shortTPhit
strat_SL_shrt = shortSLhit
if trade_cond > 0 and strat_TP_long
strat_trigger := 3
else if trade_cond < 0 and strat_TP_shrt
strat_trigger := -3
// For [BT] Robotempur
if trade_cond > 0 and ( exitL or strat_SL_long or strat_TP_long)
strat_trigger := 2
EntryPrice := float ( na )
trade_cond := 0
else if trade_cond < 0 and ( exitS or strat_SL_shrt or strat_TP_shrt)
strat_trigger := -2
EntryPrice := float ( na )
trade_cond := 0
//----------------------------------//----------------------------------//}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
// END OF STRATEGY TESTER
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------}
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════
// ALERTS
//═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════{
var string currentA = na
if entryLong_A and currentA != "L"
currentA := "L"
if entryShrt_A and currentA != "S"
currentA := "S"
alertcondition(entryLong_A and (currentA != currentA[1]), "Long A", message="Long A" + ' on {{ticker}} {{interval}} at {{close}}')
plotchar(i_draw_LongA ? entryLong_A and (currentA != currentA[1]) : na, title = 'Long A', char='.', color=color.new(color_LongA, 0), location = location.belowbar, size = size.normal, text='L-A')
alertcondition(entryShrt_A and (currentA != currentA[1]), "Short A", message="Short A" + ' on {{ticker}} {{interval}} at {{close}}')
plotchar(i_draw_ShrtA ? entryShrt_A and (currentA != currentA[1]) : na, title = 'Short A', char='.', color=color.new(color_ShrtA, 0), location = location.abovebar, size = size.normal, text='S-A')
// Create Alert Conditions
alertcondition(entryLong_All, "++LONG ALL", message="Long All" + ' on {{ticker}} {{interval}} at {{close}}')
alertcondition(entryShrt_All, "--SHORT ALL", message="Short All" + ' on {{ticker}} {{interval}} at {{close}}')
//alertcondition(entryLong_A, "Long A", message="Long A" + ' on {{ticker}} {{interval}} at {{close}}')
alertcondition(entryLong_B, "Long B", message="Long B" + ' on {{ticker}} {{interval}} at {{close}}')
alertcondition(entryLong_C, "Long C", message="Long C" + ' on {{ticker}} {{interval}} at {{close}}')
//alertcondition(entryShrt_A, "Short A", message="Short A" + ' on {{ticker}} {{interval}} at {{close}}')
alertcondition(entryShrt_B, "Short B", message="Short B" + ' on {{ticker}} {{interval}} at {{close}}')
alertcondition(entryShrt_C, "Short C", message="Short C" + ' on {{ticker}} {{interval}} at {{close}}')
// Plot Signals
//plotchar(i_draw_LongA ? entryLong_A : na, title = 'Long A', char='.', color=color.new(color_LongA, 0), location = location.belowbar, size = size.normal, text='L-A')
plotchar(i_draw_LongB ? entryLong_B : na, title = 'Long B', char='.', color=color.new(color_LongB, 0), location = location.belowbar, size = size.normal, text='L-B')
plotchar(i_draw_LongC ? entryLong_C : na, title = 'Long C', char='.', color=color.new(color_LongC, 0), location = location.belowbar, size = size.normal, text='L-C')
//plotchar(i_draw_ShrtA ? entryShrt_A : na, title = 'Short A', char='.', color=color.new(color_ShrtA, 0), location = location.abovebar, size = size.normal, text='S-A')
plotchar(i_draw_ShrtB ? entryShrt_B : na, title = 'Short B', char='.', color=color.new(color_ShrtB, 0), location = location.abovebar, size = size.normal, text='S-B')
plotchar(i_draw_ShrtC ? entryShrt_C : na, title = 'Short C', char='.', color=color.new(color_ShrtC, 0), location = location.abovebar, size = size.normal, text='S-C')
// Plot Strategy Tester
plot(strat_trigger, "═══════ [BT] Strategy Trigger ═══════", color ( na ), editable = false, display = display.none )
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
// END OF ALERTS
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------}