Contents
Version before the stream
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// ยฉ TheTradingParrot
//@version=5
strategy("DCA conceptual", shorttitle='DCA conceptual', format=format.price, overlay=true, default_qty_type=strategy.cash, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=.1, pyramiding=20, slippage=0, calc_on_order_fills=false, initial_capital=1100, currency=currency.NONE, max_labels_count=500, use_bar_magnifier=false)
baseOrder = input.float(title='Base Order size', minval=0, defval=100, group='DCA settings', tooltip='LONG STRATEGY: Quote volume is used to calculate the total capital required. \n\n SHORT STRATEGY: Contract volume is used to calculate the total capital required and total amount of contracts bought.')
safetyOrder = input.float(title='Safety Order size', minval=0, defval=200, group='DCA settings')
maxSafetyOrders = input.float(title='Max safety order count', minval=0, maxval=100, defval=5, group='DCA settings')
priceDeviation = input.float(title='Price deviation in % to open safety orders', step=0.1, maxval=100, minval=0.01, defval=2, group='DCA settings') // the less the more profit
targetProfit = input.float(title='Target profit (%)', step=0.1, minval=0.05, defval=0.9, group='DCA settings')
feePercentage = input.float(0.1, minval=0, step=0.1, title='Fees (%)', group='DCA settings', tooltip='Fee percentage. Make sure you update comissions on strategy settings to the same value for consistency.')
rsiSource = close
rsiDSCLength = input.int(defval=7, title='', group='DSC RSI', inline='rsiDSC2', minval=2, maxval=30, step=1)
rsiDSCTimeFrame = input.timeframe(defval='15', title='', group='DSC RSI', inline='rsiDSC2')
rsiDSCType = input.string(defval='Crossing Up', title='', group='DSC RSI', inline='rsiDSC2', options=['Less Than', 'Greater Than', 'Crossing Down', 'Crossing Up'])
rsiDSCLimit = input.int(defval=30, title='', group='DSC RSI', inline='rsiDSC2', minval=1, maxval=100, step=1)
rsiDSC = request.security(syminfo.tickerid, rsiDSCTimeFrame, ta.rsi(rsiSource, rsiDSCLength))
rsiDSCcond =
rsiDSCType=='Less Than' ? rsiDSC < rsiDSCLimit :
rsiDSCType=='Greater Than' ? rsiDSC > rsiDSCLimit :
rsiDSCType=='Crossing Down' ? ta.crossunder(rsiDSC, rsiDSCLimit) :
rsiDSCType=='Crossing Up' ? ta.crossover(rsiDSC, rsiDSCLimit) :
na
rsiDSC2Length = input.int(defval=7, title='', group='DSC RSI', inline='rsiDSC2', minval=2, maxval=30, step=1)
rsiDSC2TimeFrame = input.timeframe(defval='15', title='', group='DSC RSI', inline='rsiDSC2')
rsiDSC2Type = input.string(defval='Crossing Up', title='', group='DSC RSI', inline='rsiDSC2', options=['Less Than', 'Greater Than', 'Crossing Down', 'Crossing Up'])
rsiDSC2Limit = input.int(defval=30, title='', group='DSC RSI', inline='rsiDSC2', minval=1, maxval=100, step=1)
rsiDSC2 = request.security(syminfo.tickerid, rsiDSC2TimeFrame, ta.rsi(rsiSource, rsiDSC2Length))
rsiDSC2cond =
rsiDSC2Type=='Less Than' ? rsiDSC2 < rsiDSC2Limit :
rsiDSC2Type=='Greater Than' ? rsiDSC2 > rsiDSC2Limit :
rsiDSC2Type=='Crossing Down' ? ta.crossunder(rsiDSC2, rsiDSC2Limit) :
rsiDSC2Type=='Crossing Up' ? ta.crossover(rsiDSC2, rsiDSC2Limit) :
na
rsiSOLength = input.int(defval=7, title='', group='SO RSI', inline='rsiSO3', minval=2, maxval=30, step=1)
rsiSOTimeFrame = input.timeframe(defval='15', title='', group='SO RSI', inline='rsiSO3')
rsiSOType = input.string(defval='Crossing Up', title='', group='SO RSI', inline='rsiSO3', options=['Less Than', 'Greater Than', 'Crossing Down', 'Crossing Up'])
rsiSOLimit = input.int(defval=30, title='', group='SO RSI', inline='rsiSO3', minval=1, maxval=100, step=1)
rsiSO = request.security(syminfo.tickerid, rsiSOTimeFrame, ta.rsi(rsiSource, rsiSOLength))
rsiSOcond =
rsiSOType=='Less Than' ? rsiSO < rsiSOLimit :
rsiSOType=='Greater Than' ? rsiSO > rsiSOLimit :
rsiSOType=='Crossing Down' ? ta.crossunder(rsiSO, rsiSOLimit) :
rsiSOType=='Crossing Up' ? ta.crossover(rsiSO, rsiSOLimit) :
na
bool dealStartCondition = rsiDSCcond and rsiDSC2cond
bool soCondition = rsiSOcond
bool dealIsOpen = strategy.opentrades > 0
bool dealIsNotOpen = strategy.opentrades == 0
botDealStart = dealStartCondition and dealIsNotOpen
float lastOrderPrice = na
float takeProfitPrice = strategy.position_avg_price + strategy.position_avg_price * ((targetProfit+feePercentage) / 100)
lastOrderPrice := dealIsNotOpen ? na : lastOrderPrice[1]
openNewSO = strategy.opentrades < maxSafetyOrders and soCondition and close < lastOrderPrice * (1 - priceDeviation/100)
if dealIsOpen
strategy.exit("exit",from_entry = "DCA Order",qty_percent = 100,limit = takeProfitPrice, comment = 'TP')
if openNewSO
lastOrderPrice := close
strategy.entry('DCA Order', strategy.long, qty=safetyOrder / close, comment='SO')
if botDealStart
strategy.entry('DCA Order', strategy.long, qty=baseOrder / close, comment='BO')
lastOrderPrice := close
plot(strategy.opentrades , "strategy.opentrades", color=na)
a = plot(dealIsOpen ? strategy.position_avg_price : na,"AVG", color=dealIsOpen ? color.green : na , style = plot.style_steplinebr)
b = plot( dealIsOpen ? lastOrderPrice : na ," debug", color=dealIsOpen ?color.gray : na, style = plot.style_steplinebr)
plotshape(dealIsNotOpen and rsiDSCcond and rsiDSC2cond, "BO B",style = shape.labelup,location = location.belowbar,color=color.orange, textcolor = color.white, text = "B")
plotshape(rsiSOcond, "SO B",style = shape.triangleup,location = location.belowbar,color=color.new(color.green, 70), textcolor = color.new(color.white, 70), size = size.tiny)
plotshape(openNewSO, "SO B",style = shape.labelup,location = location.belowbar,color=color.new(color.green, 0), textcolor = color.new(color.white, 0), text = "B")
Live version
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// ยฉ TheTradingParrot
//@version=5
strategy("DCA Conceptual", shorttitle = "DCA C live", format=format.price, overlay=true, default_qty_type=strategy.cash, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=.1, pyramiding=20, slippage=0, calc_on_order_fills=false, initial_capital=1100, currency=currency.NONE, max_labels_count=500, use_bar_magnifier=false)
baseOrder = input.float(title='Base Order size', minval=0, defval=100, group='DCA settings', tooltip='LONG STRATEGY: Quote volume is used to calculate the total capital required. \n\n SHORT STRATEGY: Contract volume is used to calculate the total capital required and total amount of contracts bought.')
safetyOrder = input.float(title='Safety Order size', minval=0, defval=200, group='DCA settings')
maxSafetyOrders = input.float(title='Max safety order count', minval=0, maxval=100, defval=5, group='DCA settings')
priceDeviation = input.float(title='Price deviation in % to open safety orders', step=0.1, maxval=100, minval=0.01, defval=2, group='DCA settings') // the less the more profit
targetProfit = input.float(title='Target profit (%)', step=0.1, minval=0.05, defval=0.9, group='DCA settings')
feePercentage = input.float(0.1, minval=0, step=0.1, title='Fees (%)', group='DCA settings', tooltip='Fee percentage. Make sure you update comissions on strategy settings to the same value for consistency.')
enableSOTA = input.bool(true, "Enable TA for SO")
rsiSource = close
rsiDSCLength = input.int(defval=7, title='', group='DSC RSI', inline='rsiDSC2', minval=2, maxval=30, step=1)
rsiDSCTimeFrame = input.timeframe(defval='15', title='', group='DSC RSI', inline='rsiDSC2')
rsiDSCType = input.string(defval='Crossing Up', title='', group='DSC RSI', inline='rsiDSC2', options=['Less Than', 'Greater Than', 'Crossing Down', 'Crossing Up'])
rsiDSCLimit = input.int(defval=30, title='', group='DSC RSI', inline='rsiDSC2', minval=1, maxval=100, step=1)
rsiDSC = request.security(syminfo.tickerid, rsiDSCTimeFrame, ta.rsi(rsiSource,rsiDSCLength))
rsiDSCcond =
rsiDSCType=='Less Than' ? rsiDSC < rsiDSCLimit :
rsiDSCType=='Greater Than' ? rsiDSC > rsiDSCLimit :
rsiDSCType=='Crossing Down' ? ta.crossunder(rsiDSC, rsiDSCLimit) :
rsiDSCType=='Crossing Up' ? ta.crossover(rsiDSC, rsiDSCLimit) :
na
rsiDSC2Length = input.int(defval=7, title='', group='DSC RSI', inline='rsiDSC2', minval=2, maxval=30, step=1)
rsiDSC2TimeFrame = input.timeframe(defval='15', title='', group='DSC RSI', inline='rsiDSC2')
rsiDSC2Type = input.string(defval='Crossing Up', title='', group='DSC RSI', inline='rsiDSC2', options=['Less Than', 'Greater Than', 'Crossing Down', 'Crossing Up'])
rsiDSC2Limit = input.int(defval=30, title='', group='DSC RSI', inline='rsiDSC2', minval=1, maxval=100, step=1)
rsiDSC2 = request.security(syminfo.tickerid, rsiDSC2TimeFrame, ta.rsi(rsiSource, rsiDSC2Length))
rsiDSC2cond =
rsiDSC2Type=='Less Than' ? rsiDSC2 < rsiDSC2Limit :
rsiDSC2Type=='Greater Than' ? rsiDSC2 > rsiDSC2Limit :
rsiDSC2Type=='Crossing Down' ? ta.crossunder(rsiDSC2, rsiDSC2Limit) :
rsiDSC2Type=='Crossing Up' ? ta.crossover(rsiDSC2, rsiDSC2Limit) :
na
rsiSOLength = input.int(defval=7, title='', group='SO RSI', inline='rsiSO3', minval=2, maxval=30, step=1)
rsiSOTimeFrame = input.timeframe(defval='15', title='', group='SO RSI', inline='rsiSO3')
rsiSOType = input.string(defval='Crossing Up', title='', group='SO RSI', inline='rsiSO3', options=['Less Than', 'Greater Than', 'Crossing Down', 'Crossing Up'])
rsiSOLimit = input.int(defval=30, title='', group='SO RSI', inline='rsiSO3', minval=1, maxval=100, step=1)
rsiSO = request.security(syminfo.tickerid, rsiSOTimeFrame, ta.rsi(rsiSource, rsiSOLength))
rsiSOcond =
rsiSOType=='Less Than' ? rsiSO < rsiSOLimit :
rsiSOType=='Greater Than' ? rsiSO > rsiSOLimit :
rsiSOType=='Crossing Down' ? ta.crossunder(rsiSO, rsiSOLimit) :
rsiSOType=='Crossing Up' ? ta.crossover(rsiSO, rsiSOLimit) :
na
bool dealStartCondition = rsiDSCcond and rsiDSC2cond
bool soCondition = not enableSOTA or rsiSOcond
bool dealIsOpen = strategy.opentrades > 0
bool dealIsNotOpen = strategy.opentrades == 0
bool botDealStart = dealStartCondition and dealIsNotOpen
float lastOrderPrice = na
float takeProfitPrice = strategy.position_avg_price + strategy.position_avg_price * ((targetProfit+feePercentage) / 100)
lastOrderPrice := dealIsNotOpen ? na : lastOrderPrice[1]
bool openNewSO = strategy.opentrades < maxSafetyOrders and close < lastOrderPrice * (1 - priceDeviation/100) and soCondition
dealOpenTxt = input.text_area("","deal open alert txt",group = "3C alerts")
addFundsTxt = input.text_area("","add funds alert txt",group = "3C alerts")
dealCloseTxt = input.text_area("","deal close alert txt",group = "3C alerts")
if dealIsOpen
strategy.exit("exit",from_entry = "DCA Order", qty_percent = 100, limit = takeProfitPrice, comment = "TP", alert_message = dealCloseTxt)
if openNewSO
strategy.entry('DCA Order', strategy.long, qty = safetyOrder / close, comment = 'SO', alert_message = addFundsTxt)
lastOrderPrice := close
if botDealStart
strategy.entry('DCA Order',strategy.long, qty = baseOrder / close, comment = 'BO', alert_message = dealOpenTxt)
lastOrderPrice := close
plot(dealIsOpen ? strategy.position_avg_price : na, "AVG", color = dealIsNotOpen? color.green: na, style = plot.style_steplinebr )
plot(dealIsOpen ? lastOrderPrice : na, "lastOrderPrice", color = dealIsOpen ? color.gray : na, style = plot.style_steplinebr)
plotshape(dealIsNotOpen and rsiDSCcond and rsiDSC2cond, "BO B",style = shape.labelup, location = location.belowbar, color = color.orange, textcolor = color.white, text = "B")
plotshape(rsiSOcond, "SO B", style = shape.triangleup,location = location.belowbar,color=color.new(color.green, 70), textcolor = color.new(color.white, 70), size = size.tiny)
plotshape(openNewSO, "SO B",style = shape.labelup,location = location.belowbar,color=color.new(color.green, 0), textcolor = color.new(color.white, 0), text = "B")