Signal school ep3: SMART DCA uses dynamic order placing based on TA

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")




Featured products and TTP memberships