// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © sharkpunch
//@version=4
strategy(title = "zeroline", overlay=true, currency = currency.USD, initial_capital = 100000, pyramiding = 2, process_orders_on_close = true)
//==============================================================================
// CONVERT TO BASE CURRENCY {
//==============================================================================
// Get quote currency
quoteCurrency = syminfo.currency
// Get currency pair rate quoted against USD (base currency)
usdUSDrate = security("USDUSD", "D", close[1])
gbpUSDrate = security("GBPUSD", "D", close[1])
audUSDrate = security("AUDUSD", "D", close[1])
nzdUSDrate = security("NZDUSD", "D", close[1])
cadUSDrate = security("CADUSD", "D", close[1])
chfUSDrate = security("CHFUSD", "D", close[1])
eurUSDrate = security("EURUSD", "D", close[1])
jpyUSDrate = security("JPYUSD", "D", close[1])
// Function to get currency rate into variable
cr_function(source) =>
if quoteCurrency == "USD"
1
else
if quoteCurrency == "GBP"
gbpUSDrate
else
if quoteCurrency == "AUD"
audUSDrate
else
if quoteCurrency == "NZD"
nzdUSDrate
else
if quoteCurrency == "CAD"
cadUSDrate
else
if quoteCurrency == "CHF"
chfUSDrate
else
if quoteCurrency == "EUR"
eurUSDrate
else
jpyUSDrate
// Put currency rate function into variable
cr_multi = cr_function(tr(true))
//}
//==============================================================================
//==============================================================================
// BACKTEST DATE RANGE - Select Dates {
//==============================================================================
// Date Range
startDate = timestamp(2018,01,01,00,00,00)
endDate = timestamp(2021,01,01,00,00,00)
dateWindow() => time >= startDate and time <= endDate ? true : false
//}
//==============================================================================
//==============================================================================
// RULES - Inputs {
//==============================================================================
// Toggle One Candle Rule
R2_OCR_Check_Conf = input(true, title = "One Candle Rule")
// Toggle 1 x ATR Rule
R1_ATR_Check_Conf = input(false, title = "ATR Rule")
R1_ATR_Multiple = input(defval = 1.0, title = "ATR Multiple")
// Toggle Bridge Too Far Rule
R3_BTF_Check_Conf = input(true, title = "Bridge Too Far Rule")
R3_BTF_Period = input(defval = 7, title = "Bridge Too Far Period")
//}
//==============================================================================
//==============================================================================
// MONEY MANAGEMENT (ATR / Risk / Position Size) {
//==============================================================================
// Enter percetange risk
percentRisk = input(title = "Risk Per Trade", defval = 0.02, minval = 0.001, maxval = 0.05)
// Enter ATR Inputs
atrLength = 14
atrMulti_Profit = input(title = "ATR Profit Multiple", defval = 1.0)
atrMulti_Loss = input(title = "ATR Loss Multiple", defval = 1.5)
// Average True Range (ATR) Function
ma_function(source, atrLength) => rma(source, atrLength)
truncate(number,decimals) =>
factor = pow(10, decimals)
int(number * factor) / factor
atr = truncate(ma_function(tr(true), atrLength), 5)
posSize = round(((strategy.initial_capital * percentRisk) / (atrMulti_Loss * atr))/cr_multi)
//}
//==============================================================================
//==============================================================================
// INDICATOR 1 (C1) - Trigger / Confirmation {
//==============================================================================
// Toggle C1 inclusion in strategy
Ind_1_Check_Trig = input(true, title = "Indicator 1 - C1 - Trigger")
Ind_1_Check_Conf = input(true, title = "Indicator 1 - C1 - Confirmation")
// DIDI Index function
DidicurtaLength = input(title="Short Length", defval=4)
DidimediaLength = input(title="Medium Length", defval=8)
DidilongaLength = input(title="Long Length", defval=17)
Didisrc = close
Didimedia = sma(Didisrc, DidimediaLength)
Didicurta = sma(Didisrc, DidicurtaLength) / Didimedia
Didilonga = sma(Didisrc, DidilongaLength) / Didimedia
// Bridge Too Far Rule
Count_BTF = float(0.0)
Count_BTF := cross(Didicurta,Didilonga) ? 0 : Count_BTF[1] + 1
Ind_BTF_Conf = Ind_1_Check_Conf and R3_BTF_Check_Conf ? Count_BTF <= R3_BTF_Period ? true : false : true
// Trigger Long and Short Orders
Ind_1_L_Trigger = Ind_1_Check_Trig ? crossover(Didicurta,Didilonga) ? true : false : false
Ind_1_S_Trigger = Ind_1_Check_Trig ? crossunder(Didicurta,Didilonga) ? true : false : false
// Confirmation Long and Short Orders
Ind_1_L_Conf = Ind_1_Check_Conf ? Didicurta > Didilonga ? true : false : true
Ind_1_S_Conf = Ind_1_Check_Conf ? Didicurta < Didilonga ? true : false : true
//}
//==============================================================================
//==============================================================================
// INDICATOR 2 (C2) - Confirmation {
//==============================================================================
// Toggle C2 inclusion in strategy
Ind_2_Check_Conf = input(true, title = "Indicator 2 - C2 - Confirmation")
// parameters
kuskus_range = input(22, title="Range Periods")
pricesmoothing = input(0.3, title="Price Smoothing")
indexsmoothing = input(0.3, title="Index Smoothing")
kuskus_emaLength = input(18, title="EMA Length")
highesthigh = highest( high, kuskus_range)
lowestlow = lowest(low, kuskus_range)
greatestrange = 0.0
greatestrange := (highesthigh - lowestlow) != 0 ? (highesthigh - lowestlow) : greatestrange[1]
midprice = (high + low) / 2
// pricelocation
pricelocation = 2 * ((midprice - lowestlow) / greatestrange) - 1
// smoothing of pricelocation
extmapbuffer = 0.0
extmapbuffer := pricesmoothing *nz(extmapbuffer[1]) + (1 - pricesmoothing) * pricelocation
smoothedlocation = 0.0
smoothedlocation := (extmapbuffer > 0.99 ? 0.99 : (extmapbuffer < -0.99 ? -0.99 : extmapbuffer)) != 1 ? (extmapbuffer >0.99 ? 0.99 : (extmapbuffer < -0.99 ? -0.99 : extmapbuffer)) : smoothedlocation[1]
// fisher location
fishindex = log(( 1 + smoothedlocation) / (1 - smoothedlocation))
// smoothing of fishindex
extmapbuffer1 = 0.0
extmapbuffer1 := indexsmoothing * nz(extmapbuffer1[1]) + ( 1 - indexsmoothing) * fishindex
kuskus = extmapbuffer1
// add Expoential Moving Average (EMA)
kuskus_ma = ema(kuskus,kuskus_emaLength)
Ind_2_L_Conf = Ind_2_Check_Conf ? kuskus > 0 ? true : false : true
Ind_2_S_Conf = Ind_2_Check_Conf ? kuskus < 0 ? true : false : true
//}
//==============================================================================
//==============================================================================
// INDICATOR 3 (VOL) - Confirmation {
//==============================================================================
// Toggle Volume inclusion in strategy
Ind_3_Check_Conf = input(true, title = "Indicator 3 - Volume")
lookback = input(6, title = "Lookback")
mmaLength = input(6, title = "MMA Length")
mmaMode = input(title = "MMA Mode", defval="ema", options=["ema", "wma", "swma", "vwma", "hull", "tema"])
smmaLength = input(6)
smmaMode = input(title = "SMMA Mode", defval="ema", options=["ema", "wma", "swma", "vwma", "hull", "tema"])
nLength = 3
filterHigh = input(0.05, title = "Filter High")
filterLow = input(-0.05, title = "Filter Low")
price = close
tema(src, len) =>
ema1 = ema(src, len)
ema2 = ema(ema1, len)
ema3 = ema(ema2, len)
(3 * ema1) - (3 * ema2) + ema3
tdfi_ma(mode, src, len) =>
mode == "ema" ? ema(src, len) :
mode == "wma" ? wma(src, len) :
mode == "swma" ? swma(src) :
mode == "vwma" ? vwma(src, len) :
mode == "hull" ? wma((2 * wma(src, len / 2)) - wma(src, len), round(sqrt(len))) :
mode == "tema" ? tema(src, len) :
sma(src, len)
tdfi() =>
mma = tdfi_ma(mmaMode, price * 1000, mmaLength)
smma = tdfi_ma(smmaMode, mma, smmaLength)
impetmma = mma - mma[1]
impetsmma = smma - smma[1]
divma = abs(mma - smma)
averimpet = (impetmma + impetsmma) / 2
tdf = pow(divma, 1) * pow(averimpet, nLength)
tdf / highest(abs(tdf), lookback * nLength)
ntdf = tdfi()
Ind_3_L_Conf = Ind_3_Check_Conf ? ntdf > filterHigh ? true : false : true
Ind_3_S_Conf = Ind_3_Check_Conf ? ntdf < filterLow ? true : false : true
//}
//==============================================================================
//==============================================================================
// INDICATOR 4 (BL) - Trigger / Confirmation {
//==============================================================================
// Toggle Baseline inclusion in strategy
Ind_4_Check_Trig = input(true, title = "Indicator 4 - BL - Trigger")
Ind_4_Check_Conf = input(true, title = "Indicator 4 - BL - Confirmation")
kama_length = input(title="Length", type=input.integer, defval=10)
kama_fastLength = input(title="Fast EMA Length", type=input.integer, defval=2)
kama_slowLength = input(title="Slow EMA Length", type=input.integer, defval=30)
kama_src = close
mom = abs(change(kama_src, kama_length))
volatility = sum(abs(change(kama_src)), kama_length)
// Efficiency Ratio
kama_er = volatility != 0 ? mom / volatility : 0
fastAlpha = 2 / (kama_fastLength + 1)
slowAlpha = 2 / (kama_slowLength + 1)
// KAMA Alpha
sc = pow((kama_er * (fastAlpha - slowAlpha)) + slowAlpha, 2)
baseline = 0.0
baseline := sc * kama_src + (1 - sc) * nz(baseline[1])
// Plot KAMA and ATR bands on chart
plot(Ind_4_Check_Conf ? baseline : na, title="KAMA", linewidth=2, color=color.yellow, transp=0)
plot(Ind_4_Check_Conf ? baseline + R1_ATR_Multiple*atr : na, title="KAMA", linewidth=1, color=color.white, transp=80)
plot(Ind_4_Check_Conf ? baseline - R1_ATR_Multiple*atr: na, title="KAMA", linewidth=1, color=color.white, transp=80)
// Confirmation long and short orders for 1x ATR rule
Ind_4_L_Conf_ATR = R1_ATR_Check_Conf ? close < baseline + R1_ATR_Multiple*atr ? true : false : true
Ind_4_S_Conf_ATR = R1_ATR_Check_Conf ? close > baseline - R1_ATR_Multiple*atr ? true : false : true
// Trigger long and short orders
Ind_4_L_Trig = Ind_4_Check_Trig ? crossover(close,baseline) ? true : false : false
Ind_4_S_Trig = Ind_4_Check_Trig ? crossunder(close,baseline) ? true : false : false
// Confirmation long and short orders
Ind_4_L_Conf = Ind_4_Check_Conf ? close > baseline ? true : false : true
Ind_4_S_Conf = Ind_4_Check_Conf ? close < baseline ? true : false : true
//}
//==============================================================================
//==============================================================================
// INDICATOR 5 (EX) - Exit {
//==============================================================================
// Toggle Exit inclusion in strategy
Ind_5_Check_Exit_C1 = input(true, title = "Indicator 5 - Exit - C1 Trigger")
Ind_5_Check_Exit_BL = input(true, title = "Indicator 5 - Exit - BL Trigger")
Ind_5_Check_Exit = input(true, title = "Indicator 5 - Exit - Exit Trigger")
oscar_len = input(title="Length", defval=8)
oscar_slowLen = input(title="Slow Length", defval=10)
smoothing = "RMA"
OscarOfIndicator = close
A = highest(OscarOfIndicator, oscar_len)
B = lowest(OscarOfIndicator, oscar_len)
OscarRough = (OscarOfIndicator - B) / (A - B) * 100
Oscar1 = (OscarRough[1] / 3) * 2
OscarThird = OscarRough / 3
Oscar = Oscar1 + OscarThird
smoothedOscarRough = rma(OscarRough, oscar_len)
smoothedOscar = rma(Oscar, oscar_len)
// Trigger Exit by Exit Indicator
Ind_5_L_Exit = Ind_5_Check_Exit ? crossunder(smoothedOscarRough, smoothedOscar) ? true : false : false
Ind_5_S_Exit = Ind_5_Check_Exit ? crossover(smoothedOscarRough, smoothedOscar) ? true : false : false
// Trigger Exit by Baseline Indicator
Ind_5_L_Exit_BL = Ind_5_Check_Exit_BL ? crossunder(close, baseline) ? true : false : false
Ind_5_S_Exit_BL = Ind_5_Check_Exit_BL ? crossover(close, baseline) ? true : false : false
// Trigger Exit by C1 Indicator
Ind_5_L_Exit_C1 = Ind_5_Check_Exit_C1 ? crossunder(Didicurta,Didilonga) ? true : false : false
Ind_5_S_Exit_C1 = Ind_5_Check_Exit_C1 ? crossover(Didicurta,Didilonga) ? true : false : false
//}
//==============================================================================
//==============================================================================
// INDICATOR 6 (CON) - Continuation Trades {
//==============================================================================
// Toggle Continuation Trades inclusion in strategy
Ind_6_Check = input(true, title = "Indicator 6 - Continuation Trade")
// Continuation Trades
Count_Con = float(0.0)
Count_Con := cross(close,baseline) ? 0 : strategy.position_size != 0 ? 1 : strategy.position_size[1] != 0 and strategy.position_size == 0 ? 2 : Count_Con[1]
Ind_Con_Trig = Ind_6_Check ? Count_Con == 2 ? true : false : false
//kuskus_emaLength = input(14, title="EMA Length")
//kuskus_ma = ema(kuskus,kuskus_emaLength)
// Trigger Long and Short Orders
Ind_6_L_Trigger = Ind_6_Check ? crossover(kuskus, kuskus_ma) ? true : false : false
Ind_6_S_Trigger = Ind_6_Check ? crossunder(kuskus, kuskus_ma) ? true : false : false
//}
//==============================================================================
//==============================================================================
// ENTRY CONDITIONS - Submit Orders {
//==============================================================================
//Long or Short Condition 1 - C1 Cross - Combine all indicator long signals here
longCondition1 = strategy.position_size<=0 and (Ind_1_L_Trigger or Ind_1_L_Trigger[1] and R2_OCR_Check_Conf) and Ind_2_L_Conf and Ind_3_L_Conf and Ind_4_L_Conf and Ind_4_L_Conf_ATR
shortCondition1 = strategy.position_size>=0 and (Ind_1_S_Trigger or Ind_1_S_Trigger[1] and R2_OCR_Check_Conf) and Ind_2_S_Conf and Ind_3_S_Conf and Ind_4_S_Conf and Ind_4_S_Conf_ATR
plotshape(longCondition1 or shortCondition1, color = color.blue, style=shape.circle, text="C1\nEntry", location=location.bottom, transp=75, size=size.tiny)
//Long or Short Condition 2 - Baseline Cross - Combine all indicator long signals here
longCondition2 = strategy.position_size<=0 and Ind_1_L_Conf and Ind_2_L_Conf and Ind_3_L_Conf and (Ind_4_L_Trig or Ind_4_L_Trig[1] and R2_OCR_Check_Conf) and Ind_4_L_Conf_ATR and Ind_BTF_Conf
shortCondition2 = strategy.position_size>=0 and Ind_1_S_Conf and Ind_2_S_Conf and Ind_3_S_Conf and (Ind_4_S_Trig or Ind_4_S_Trig[1] and R2_OCR_Check_Conf) and Ind_4_S_Conf_ATR and Ind_BTF_Conf
//plotshape((longCondition2 or shortCondition2) and (Ind_1_L_Trigger and Ind_1_S_Trigger) == false , color = color.blue, style=shape.circle, text="BL\nEntry", location=location.bottom, transp=75, size=size.tiny)
//Long or Short Condition 3 - Continuation Trades - Combine all indicator long signals here
longCondition3 = strategy.position_size<=0 and Ind_6_L_Trigger and Ind_1_L_Conf and Ind_2_L_Conf and Ind_3_L_Conf and Ind_4_L_Conf and Ind_4_L_Conf_ATR and Ind_Con_Trig
shortCondition3 = strategy.position_size>=0 and Ind_6_S_Trigger and Ind_1_S_Conf and Ind_2_S_Conf and Ind_3_S_Conf and Ind_4_S_Conf and Ind_4_S_Conf_ATR and Ind_Con_Trig
plotshape(longCondition3 or shortCondition3, color = color.blue, style=shape.circle, text="Cont\nEntry", location=location.bottom, transp=75, size=size.tiny)
// Define long and short variables
entry_long = (longCondition1 or longCondition2 or longCondition3) and dateWindow()
entry_short = (shortCondition1 or shortCondition2 or shortCondition3) and dateWindow()
// Store values
entry_atr = float(0.0) //set float
entry_price = float(0.0) //set float
entry_atr := strategy.position_size == 0 or entry_long or entry_short ? atr : entry_atr[1]
entry_price := strategy.position_size == 0 or entry_long or entry_short ? close : entry_price[1]
// Submit long and short orders based on entry conditions
if(entry_long)
strategy.entry(id="Long Entry 1", long=true, qty=posSize*0.5)
strategy.entry(id="Long Entry 2", long=true, qty=posSize*0.5)
if(entry_short)
strategy.entry(id="Short Entry 1", long=false, qty=posSize*0.5)
strategy.entry(id="Short Entry 2", long=false, qty=posSize*0.5)
//}
//==============================================================================
//==============================================================================
// STATIC OR TRAILING STOP LOSS - Conditions {
//==============================================================================
// Toggle static/trailing stop loss
Exit_Type = input(defval = "Trailing SL", title = "Exit Condition Type", options = ["Static","Trailing SL"])
// Calculate stop loss and take profit distance (in price)
nLoss = entry_atr * atrMulti_Loss // 1.5 x atr as default
nProfit = entry_atr * atrMulti_Profit // 1.0 x atr as default
// Find long entry stop loss and take profit
long_stop_level = float(0.0) //set float
long_profit_level = float(0.0) //set float
if(Exit_Type == "Static")
long_stop_level := entry_price - nLoss
long_profit_level := entry_price + nProfit
else
long_stop_level := strategy.opentrades == 2 or entry_long ? entry_price - nLoss : strategy.opentrades == 1 ? max(close - nLoss, nz(long_stop_level[1],0), strategy.position_avg_price + 0.001) : na
long_profit_level := entry_price + nProfit
// Find short entry stop loss and take profit
short_stop_level = float(0.0) //set float
short_profit_level = float(0.0) //set float
if(Exit_Type == "Static")
short_stop_level := entry_price + nLoss
short_profit_level := entry_price - nProfit
else
short_stop_level := strategy.opentrades == 2 or entry_short ? entry_price + nLoss : strategy.opentrades == 1 ? min(close + nLoss, nz(short_stop_level[1],10000000), strategy.position_avg_price - 0.001) : na
short_profit_level := entry_price - nProfit
// Plot stop loss and profit level on graph; hide levels when no trade
plot(strategy.position_size <= 0 or entry_long or entry_short ? na : long_stop_level, color=color.red, style=plot.style_linebr, linewidth = 2)
plot(strategy.position_size <= 0 or entry_long or entry_short or strategy.opentrades == 1 ? na : long_profit_level, color=color.lime, style=plot.style_linebr, linewidth = 2)
plot(strategy.position_size >= 0 or entry_long or entry_short ? na : short_stop_level, color=color.red, style=plot.style_linebr, linewidth = 2)
plot(strategy.position_size >= 0 or entry_long or entry_short or strategy.opentrades == 1 ? na : short_profit_level, color=color.lime, style=plot.style_linebr, linewidth = 2)
//}
//==============================================================================
//==============================================================================
// EXIT CONDITIONS (Static/Trailing SL/Exit Indicator) {
//==============================================================================
// Submit exit orders on static stop loss and take profit
if(Exit_Type == "Static") // use a static stop loss
// Long and Short Entry 1
strategy.exit("TP/SL 1", "Long Entry 1", stop = long_stop_level, limit = long_profit_level)
strategy.exit("TP/SL 1", "Short Entry 1", stop = short_stop_level, limit = short_profit_level)
// Long and Short Entry 2
strategy.exit("TP/SL 2", "Long Entry 2", stop = long_stop_level, limit = long_profit_level)
strategy.exit("TP/SL 2", "Short Entry 2", stop = short_stop_level, limit = short_profit_level)
else // use a trailing stop loss
// Long and Short Entry 1
strategy.exit("TP/SL 1", "Long Entry 1", stop = long_stop_level, limit = long_profit_level)
strategy.exit("TP/SL 1", "Short Entry 1", stop = short_stop_level, limit = short_profit_level)
// Long and Short Entry 2
strategy.exit("TP/SL 2", "Long Entry 2", stop = long_stop_level, limit = na)
strategy.exit("TP/SL 2", "Short Entry 2", stop = short_stop_level, limit = na)
// Submit exit orders when C1 exit triggers
// Long and Short Entry 1
strategy.close(id="Long Entry 1", comment = "Exit Long 1", when = Ind_5_L_Exit_C1)
strategy.close(id="Short Entry 1", comment = "Exit Short 1", when = Ind_5_L_Exit_C1)
// Long and Short Entry 2
strategy.close(id="Long Entry 2", comment = "Exit Long 2", when = Ind_5_L_Exit_C1)
strategy.close(id="Short Entry 2", comment = "Exit Short 2", when = Ind_5_S_Exit_C1)
plotshape(strategy.position_size > 0 and Ind_5_L_Exit_C1, color = color.red, style=shape.xcross, text="C1\nExit", location=location.bottom, transp=75, size=size.tiny)
plotshape(strategy.position_size < 0 and Ind_5_S_Exit_C1, color = color.red, style=shape.xcross, text="C1\nExit", location=location.bottom, transp=75, size=size.tiny)
// Submit exit orders when BL exit triggers
// Long and Short Entry 1
strategy.close(id="Long Entry 1", comment = "Exit Long 1", when = Ind_5_L_Exit_BL)
strategy.close(id="Short Entry 1", comment = "Exit Short 1", when = Ind_5_S_Exit_BL)
// Long and Short Entry 2
strategy.close(id="Long Entry 2", comment = "Exit Long 2", when = Ind_5_L_Exit_BL)
strategy.close(id="Short Entry 2", comment = "Exit Short 2", when = Ind_5_S_Exit_BL)
plotshape(strategy.position_size > 0 and Ind_5_L_Exit_BL, color = color.red, style=shape.xcross, text="BL\nExit", location=location.bottom, transp=75, size=size.tiny)
plotshape(strategy.position_size < 0 and Ind_5_S_Exit_BL, color = color.red, style=shape.xcross, text="BL\nExit", location=location.bottom, transp=75, size=size.tiny)
// Submit exit orders when exit indicator triggers
// Long and Short Entry 1
strategy.close(id="Long Entry 1", comment = "Exit Long 1", when = Ind_5_L_Exit)
strategy.close(id="Short Entry 1", comment = "Exit Short 1", when = Ind_5_S_Exit)
// Long and Short Entry 2
strategy.close(id="Long Entry 2", comment = "Exit Long 2", when = Ind_5_L_Exit)
strategy.close(id="Short Entry 2", comment = "Exit Short 2", when = Ind_5_S_Exit)
plotshape(strategy.position_size > 0 and Ind_5_L_Exit, color = color.red, style=shape.xcross, text="Ind\nExit", location=location.bottom, transp=75, size=size.tiny)
plotshape(strategy.position_size < 0 and Ind_5_S_Exit, color = color.red, style=shape.xcross, text="Ind\nExit", location=location.bottom, transp=75, size=size.tiny)
//}
//==============================================================================
//==============================================================================
// PLOT LABELS {
//==============================================================================
//Plot strategy label to chart on current candle
labelText = "Pos Size: " + tostring(strategy.position_size) + "\nEntry Price: " + tostring(entry_price) + "\nEntry ATR:" + tostring(entry_atr)
stratLabel = label.new(x=bar_index, y=na, text=labelText, yloc=yloc.abovebar, color=color.black, textcolor=color.white, style=label.style_labeldown)
label.delete(stratLabel[1]) //Delete label from previous candle
//}
//==============================================================================
Show all 494 lines