Stratégie quantitative avec signal stochastique, filtre SMA et arrêt aléatoire des pertes / prise de profit

Auteur:ChaoZhang est là., Date: 2024-01-08 16h07
Les étiquettes:

img

Résumé

L'idée principale est de générer des signaux de trading avec l'indicateur stochastique, filtrer les signaux avec SMA, mettre en œuvre une ouverture de position bidirectionnelle, et définir des points de stop-loss aléatoires et de profit pour verrouiller les bénéfices.

La logique de la stratégie

La stratégie utilise des croisements de lignes de l'indicateur stochastique de 5 jours %K et %D pour générer des signaux de négociation. Lorsque %K traverse %D depuis le bas, un signal d'achat est généré. Lorsque %K traverse en dessous de %D depuis le haut, un signal de vente est généré. Pour filtrer les faux signaux, des lignes SMA de 50 jours sont utilisées - seulement lorsque le prix de clôture est inférieur au point bas de la SMA, un signal d'achat est valide; seulement lorsque le prix de clôture est supérieur au point élevé de la SMA, un signal de vente est valide.

La stratégie d'achat ouvre une position longue avec une quantité fixe. Lorsqu'elle reçoit un signal de vente, si elle est en mode de négociation à sens unique, elle ferme la position longue précédente et ouvre une position courte. Si elle est en mode de couverture, elle ouvre simplement une position courte supplémentaire pour la couverture. Pour chaque unité de négociation, des points de stop-loss et de prise de profit aléatoires sont définis en fonction d'un certain pourcentage du prix actuel. Cela permet de verrouiller les profits et de contrôler les risques.

Les avantages

Le plus grand avantage de cette stratégie est qu'elle utilise des signaux stochastiques avec un filtre SMA pour atteindre un taux de faux signaux relativement faible dans le trading bidirectionnel. Cela offre plus d'opportunités de profit. En outre, le mécanisme de stop loss / take profit aléatoire permet de tirer profit à temps après avoir réalisé des profits, en évitant de rendre tous les profits; et de réduire les pertes en cas de perte énorme, pour réduire les pertes. En résumé, la stratégie a une plus grande marge bénéficiaire et un meilleur contrôle des risques.

Les risques

Les principaux risques de cette stratégie sont les suivants: les faux signaux de l'indicateur stochastique peuvent entraîner des pertes inutiles; les points de stop loss/take profit aléatoires inappropriés peuvent être trop agressifs, entraînant une sortie prématurée ou tardive, ce qui a une incidence sur la rentabilité; l'incapacité de réduire les pertes à temps dans les opérations de couverture peut entraîner une amplification des pertes.

Pour réduire les risques, les paramètres du filtre SMA peuvent être optimisés pour filtrer davantage de faux signaux. Considérez également la combinaison d'autres indicateurs pour déterminer les tendances du marché afin d'éviter de négocier contre les tendances. Enfin, une plage de stop loss raisonnable doit être définie et des points de stop loss indépendants doivent être utilisés pour les unités de couverture pour contrôler le risque.

Directions d'optimisation

Les stratégies peuvent être optimisées dans les aspects suivants:

  1. Optimiser les paramètres de Stochastique pour trouver la meilleure combinaison de paramètres pour réduire les faux signaux.

  2. Optimiser ou ajouter d'autres indicateurs techniques pour aider Stochastique à déterminer les tendances, par exemple MACD, KD, etc.

  3. Utilisez des modèles d'apprentissage automatique pour étudier des mesures telles que la précision, le taux de victoire, etc. des signaux stochastiques sous différents paramètres, afin de trouver l'espace de paramètres optimal.

  4. Optimiser les algorithmes de stop loss/take profit aléatoires pour les rendre plus intelligents et dynamiques, par exemple en incorporant des concepts tels que le déplacement des stop loss, la dimensionnement des positions, etc.

  5. Ajouter un module de dimensionnement de la position, permettant des ajustements dynamiques de la position en fonction des performances, des régimes du marché, etc.

Conclusion

La stratégie quantique DayLight Hunter avec position bidirectionnelle, signal stochastique et stop-loss/take profit aléatoire combine les signaux de croisement stochastique, le principe du filtre SMA, le trading bidirectionnel et la méthode stop-loss/take profit aléatoire. Elle présente des avantages tels que des signaux relativement précis, des opportunités de trading bidirectionnelles abondantes, un stop-loss/profit-taking flexible et des risques dans une plage acceptable.


/*backtest
start: 2023-12-31 00:00:00
end: 2024-01-07 00:00:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
var int slippage = 0
strategy("X48 - DayLight Hunter | Strategy | V.01.01", overlay=true, calc_on_order_fills = true, initial_capital = 50,default_qty_type = strategy.fixed, default_qty_value = 1, commission_type = strategy.commission.percent, commission_value = 0, currency = currency.USD, slippage = 0)

var bool hedge_mode = false
var int sto_buy = 0
var int sto_sell = 0

Trade_Mode = input.string(defval = "Hedge", title = "⚖️ Mode For Trade [Oneway / Hedge]", options = ["Oneway", "Hedge"], group = "Mode Trade", tooltip = "Oneway = Switching Position Type With Signal\nHedge Mode = Not Switching Position Type Unitl TP or SL")
Risk_Mode = input.string(defval = "Low Risk", title = "⚖️ Risk Signal Mode [Low / Medium / High]", options = ["Low Risk", "Medium Risk", "High Risk"], group = "Mode Trade", tooltip = "[[Signal Form Stochastic]]\nLow Risk is >= 80 and <= 20\nMedium Risk is >= 70 and <= 30\nHigh Risk is >= 50 and <=50")

if Trade_Mode == "Oneway"
    hedge_mode := false
else
    hedge_mode := true

if Risk_Mode == "Low Risk"
    sto_buy := 20
    sto_sell := 80
else if Risk_Mode == "Medium Risk"
    sto_buy := 30
    sto_sell := 70
else if Risk_Mode == "High Risk"
    sto_buy := 50
    sto_sell := 50

periodK = input.int(15, title="%K Length", minval=1, group = "Stochastic Setting", inline = "Sto0")
smoothK = input.int(3, title="%K Smoothing", minval=1, group = "Stochastic Setting", inline = "Sto0")
periodD = input.int(3, title="%D Smoothing", minval=1, group = "Stochastic Setting", inline = "Sto0")

SMA_Mode = input.bool(defval = true, title = "SMA High and Low Filter Mode", group = "SMA Filter Mode", tooltip = "Sell Signal With Open >= SMA High\nBuy Signal With Close <= SMA Low")
SMA_High = input.int(defval = 50, title = "SMA High", group = "SMA Filter Mode", inline = "SMA1")
SMA_Low = input.int(defval = 50, title = "SMA Low", group = "SMA Filter Mode", inline = "SMA1")

k = ta.sma(ta.stoch(close, high, low, periodK), smoothK)
d = ta.sma(k, periodD)
high_line = ta.sma(high, SMA_High)
low_line = ta.sma(low, SMA_Low)
plot(SMA_Mode ? high_line : na, "H-Line", color = color.yellow, linewidth = 2)
plot(SMA_Mode ? low_line : na, "L-Line", color = color.blue, linewidth = 2)

entrybuyprice = strategy.position_avg_price

var bool longcondition = na
var bool shortcondition = na

if SMA_Mode == true
    longcondition := ta.crossover(k,d) and d <= sto_buy and close < low_line and open < low_line// or ta.crossover(k, 20)// and close <= low_line
    shortcondition := ta.crossunder(k,d) and d >= sto_sell and close > high_line and open > high_line// or ta.crossunder(k, 80)// and close >= high_line
else
    longcondition := ta.crossover(k,d) and d <= sto_buy
    shortcondition := ta.crossunder(k,d) and d >= sto_sell
//longcondition_double = ta.crossover(d,20) and close < low_line// and strategy.position_size > 0
//shortcondition_double = ta.crossunder(d,80) and close > high_line// and strategy.position_size < 0

//=============== TAKE PROFIT and STOP LOSS by % =================

tpsl(percent) =>
    strategy.position_avg_price * percent / 100 / syminfo.mintick
GR4 = "=====🆘🆘🆘 TAKE PROFIT & STOP LOSS BY [%] 🆘🆘🆘====="
mode= input.bool(title="🆘 Take Profit & Stop Loss By Percent (%)", defval=true, group=GR4, tooltip = "Take Profit & Stop Loss by % Change\n0 = Disable")
tp_l = tpsl(input.float(0, title='🆘 TP [LONG] % >> [Oneway Only]', group=GR4, tooltip = "0 = Disable"))
tp_s = tpsl(input.float(0, title='🆘 TP [SHORT] % >> [Oneway Only]', group=GR4, tooltip = "0 = Disable"))
sl = tpsl(input.float(0, title='🆘 Stop Loss %', group=GR4, tooltip = "0 = Disable"))
tp_pnl = input.float(defval = 1, title = "🆘 TP by PNL $ eg. (0.1 = 0.1$)", group = GR4)
spread_size = input.float(defval = 0.350, title = "🆘 Spread Point Size(Eg. 35 Point or 350 Point From Your Broker Digits)", tooltip = "Spread Point Form Your Broker \nEg. 1920.124 - 1920.135 or 1920.12 - 1920.13\nPlease Check From Your Broker", group = GR4)

GR5 = "===💮💮💮 Hedge Mode 💮💮💮==="
//hedge_mode = input.bool(defval = true, title = "⚖️ Hedge Mode", group = GR5)
hedge_point = input.int(defval = 500, title = "💯 Hedge Point Range", group = GR5, tooltip = "After Entry Last Position And Current Price More Than Point Range Are Open New Hedge Position")
hedge_gale = input.float(defval = 2.0, title = "✳️ Martingale For Hedge Multiply [default = 2]", tooltip = "Martingale For Multiply Hedge Order", group = GR5)
hedge_point_size = hedge_point/100

calcStopLossPrice(OffsetPts) =>
    if strategy.position_size > 0
        strategy.position_avg_price - OffsetPts * syminfo.mintick
    else if strategy.position_size < 0
        strategy.position_avg_price + OffsetPts * syminfo.mintick
    else
        na

calcStopLossL_AlertPrice(OffsetPts) =>
    strategy.position_avg_price - OffsetPts * syminfo.mintick
calcStopLossS_AlertPrice(OffsetPts) =>
    strategy.position_avg_price + OffsetPts * syminfo.mintick

calcTakeProfitPrice(OffsetPts) =>
    if strategy.position_size > 0
        strategy.position_avg_price + OffsetPts * syminfo.mintick
    else if strategy.position_size < 0
        strategy.position_avg_price - OffsetPts * syminfo.mintick
    else
        na

calcTakeProfitL_AlertPrice(OffsetPts) =>
    strategy.position_avg_price + OffsetPts * syminfo.mintick
calcTakeProfitS_AlertPrice(OffsetPts) =>
    strategy.position_avg_price - OffsetPts * syminfo.mintick

var stoploss = 0.
var stoploss_l = 0.
var stoploss_s = 0.
var takeprofit = 0.
var takeprofit_l = 0.
var takeprofit_s = 0.
var takeprofit_ll = 0.
var takeprofit_ss = 0.

if mode == true
    if (strategy.position_size > 0)
        if sl > 0
            stoploss := calcStopLossPrice(sl)
            stoploss_l := stoploss
        else if sl <= 0
            stoploss := na
        if tp_l > 0
            takeprofit := tp_l
            takeprofit_ll := close + ((close/100)*tp_l)
            //takeprofit_s := na
        else if tp_l <= 0
            takeprofit := na
    if (strategy.position_size < 0)
        if sl > 0
            stoploss := calcStopLossPrice(sl)
            stoploss_s := stoploss
        else if sl <= 0
            stoploss := na
        if tp_s > 0
            takeprofit := tp_s
            takeprofit_ss := close - ((close/100)*tp_s)
            //takeprofit_l := na
        else if tp_s <= 0
            takeprofit := na
    else if strategy.position_size == 0
        stoploss := na
        takeprofit := na
        //takeprofit_l := calcTakeProfitL_AlertPrice(tp_l)
        //takeprofit_s := calcTakeProfitS_AlertPrice(tp_s)
        //stoploss_l := calcStopLossL_AlertPrice(sl)
        //stoploss_s := calcStopLossS_AlertPrice(sl)

//////////// INPUT BACKTEST RANGE ////////////////////////////////////////////////////
var string BTR1         = '════════⌚⌚ INPUT BACKTEST TIME RANGE ⌚⌚════════'
i_startTime             = input(defval = timestamp("01 Jan 1945 00:00 +0000"), title = "Start", inline="timestart", group=BTR1, tooltip = 'Start Backtest YYYY/MM/DD')
i_endTime               = input(defval = timestamp("01 Jan 2074 23:59 +0000"), title = "End", inline="timeend", group=BTR1, tooltip = 'End Backtest YYYY/MM/DD')
//////////////// Strategy Alert For X4815162342 BOT //////////////////////
Text_Alert_Future = '{{strategy.order.alert_message}}'
copy_Fu = input( defval= Text_Alert_Future ,    title="Alert Message for BOT", inline = '00'  ,group = '═ Bot Setting ═ \n >> If You Dont Use Bot Just Pass It' ,tooltip = 'Alert For X48-BOT > Copy and Paste To Alert Function')
TimeFrame_input = input(defval= 'Input Your TimeFrame [1m, 15m, 1h, 4h, 1d ,1w]' ,    title="TimeFrame Text Alert", inline = '00'  ,group = '═ Bot Setting ═ \n >> If You Dont Use Bot Just Pass It')
string Alert_EntryL = '🪙 Asset : {{ticker}} \n💱 Status : {{strategy.market_position}}\n🕛 TimeFrame : '+str.tostring(TimeFrame_input)+'\n💸 Price : {{strategy.order.price}} $\n✅ TP : '+str.tostring(takeprofit_ll)+' $\n❌ SL : '+str.tostring(stoploss_l)+' $\n⏰ Time : {{timenow}}'
string Alert_EntryS = '🪙 Asset : {{ticker}} \n💱 Status : {{strategy.market_position}}\n🕛 TimeFrame : '+str.tostring(TimeFrame_input)+'\n💸 Price : {{strategy.order.price}} $\n✅ TP : '+str.tostring(takeprofit_ss)+' $\n❌ SL : '+str.tostring(stoploss_s)+' $\n⏰ Time : {{timenow}}'
string Alert_TPSL = '🪙 Asset : {{ticker}}\n🕛 TimeFrame : '+str.tostring(TimeFrame_input)+'\n💹 {{strategy.order.comment}}\n💸 Price : {{strategy.order.price}} $\n⏰ Time : {{timenow}}'

if true
    if longcondition
        strategy.entry("Long", strategy.long, comment = "🌙", alert_message = Alert_EntryL)
    //if longcondition_double
    //    //strategy.cancel_all()
    //    strategy.entry("Long2", strategy.long, comment = "🌙🌙")
    //    //strategy.exit("Exit",'Long', qty_percent = 100 , profit = takeprofit, stop = stoploss, comment_profit = "TP💚L", comment_loss = "SL💚L")
    if shortcondition
        strategy.entry("Short", strategy.short, comment = "👻", alert_message = Alert_EntryS)
        //strategy.exit("Exit",'Short', qty_percent = 100, profit = takeprofit, stop = stoploss, comment_profit = "TP❤️️S", comment_loss = "SL❤️️S")
    //if shortcondition_double
    //    //strategy.cancel_all()
    //    strategy.entry("Short2", strategy.short, comment = "👻👻")

if strategy.position_size > 0 and strategy.opentrades >= 1 and hedge_mode == true
    entrypricel = strategy.opentrades.entry_price(strategy.opentrades - 1)
    callpointsize =  entrypricel - close
    lastsize = strategy.position_size
    if callpointsize >= hedge_point_size and longcondition
        strategy.order("Long2", strategy.long, qty = lastsize * hedge_gale, comment = "🌙⌛", alert_message = Alert_EntryL)

else if strategy.position_size < 0 and strategy.opentrades >= 1 and hedge_mode == true
    entryprices = strategy.opentrades.entry_price(strategy.opentrades - 1)
    callpointsize = (entryprices - close)* -1
    lastsize = (strategy.position_size) * -1
    if callpointsize >= hedge_point_size and shortcondition
        strategy.order("Short2", strategy.short, qty = lastsize * hedge_gale, comment = "👻⌛", alert_message = Alert_EntryS)

last_price_l = (strategy.opentrades.entry_price(strategy.opentrades - 1) + (strategy.opentrades.entry_price(strategy.opentrades - 1)/100) * takeprofit) + spread_size
last_price_s = (strategy.opentrades.entry_price(strategy.opentrades - 1) - (strategy.opentrades.entry_price(strategy.opentrades - 1)/100) * takeprofit) - spread_size 
current_price = request.security(syminfo.tickerid, "1", close)
current_pricel = request.security(syminfo.tickerid, "1", close) + spread_size
current_prices = request.security(syminfo.tickerid, "1", close) - spread_size
//if mode == true
if strategy.position_size > 0 and strategy.openprofit >= tp_pnl and mode == true and hedge_mode == true
    lastsize = strategy.position_size
    lastprofitorder = strategy.openprofit
    //if lastprofitorder >= 0.07
    //strategy.close('Long', qty = lastsize, comment = "TP💚L", alert_message = Alert_TPSL, immediately = true)
    strategy.cancel_all()
    strategy.close_all(comment = "TP💚PNL", alert_message = Alert_TPSL, immediately = true)
    //strategy.close_all(comment = "TP💚LH", alert_message = Alert_TPSL)
    //strategy.exit("Exit",'Long2', qty_percent = 100, profit = last_price_l, stop = stoploss, comment_profit = "TP💚LH", comment_loss = "SL💚LH", alert_message = Alert_TPSL)
    //strategy.exit("Exit",'Long', qty_percent = 100, profit = last_price_l, stop = stoploss, comment_profit = "TP💚L", comment_loss = "SL💚L", alert_message = Alert_TPSL)
else if strategy.position_size > 0 and strategy.openprofit < tp_pnl and mode == true and hedge_mode == true
    strategy.exit("Exit",'Long', qty_percent = 100, stop = stoploss, comment_loss = "SL💚%L", alert_message = Alert_TPSL)

if strategy.position_size > 0 and mode == true and hedge_mode == false
    //strategy.close_all(comment = "TP💚LH", alert_message = Alert_TPSL, immediately = true)
    strategy.exit("Exit",'Long', qty_percent = 100, profit = takeprofit, stop = stoploss, comment_profit = "TP💚%L", comment_loss = "SL💚%L", alert_message = Alert_TPSL)
    //strategy.exit("Exit",'Long', qty_percent = 100, profit = takeprofit, stop = stoploss, comment_profit = "TP💚LL", comment_loss = "SL💚L", alert_message = Alert_TPSL)

//else if strategy.position_size > 0 and strategy.opentrades > 1
//    lastsize = strategy.position_size
//    lastprofitorder = strategy.openprofit
//    if lastprofitorder >= 0.07
//        strategy.close_all(comment = "TP💚LL", alert_message = Alert_TPSL)
if strategy.position_size < 0 and strategy.openprofit >= tp_pnl and mode == true and hedge_mode == true
    lastsize = (strategy.position_size) * -1
    lastprofitorder = strategy.openprofit
    //if lastprofitorder >= 0.07
    //strategy.close('Short', qty = lastsize, comment = "TP❤️️S", alert_message = Alert_TPSL, immediately = true)
    strategy.cancel_all()
    strategy.close_all(comment = "TP❤️️PNL", alert_message = Alert_TPSL, immediately = true)
    //strategy.close_all(comment = "TP❤️️SH", alert_message = Alert_TPSL)
    //strategy.exit("Exit",'Short2', qty_percent = 100, profit = last_price_s, stop = stoploss, comment_profit = "TP❤️️SH", comment_loss = "SL❤️️SH", alert_message = Alert_TPSL)
    //strategy.exit("Exit",'Short', qty_percent = 100, profit = last_price_s, stop = stoploss, comment_profit = "TP❤️️S", comment_loss = "SL❤️️S", alert_message = Alert_TPSL)
else if strategy.position_size < 0 and strategy.openprofit < tp_pnl and mode == true and hedge_mode == true
    strategy.exit("Exit",'Short', qty_percent = 100, stop = stoploss, comment_loss = "SL❤️️%S", alert_message = Alert_TPSL)
if strategy.position_size < 0 and mode == true and hedge_mode == false
    //strategy.close_all(comment = "TP❤️️SH", alert_message = Alert_TPSL, immediately = true)
    strategy.exit("Exit",'Short', qty_percent = 100, profit = takeprofit, stop = stoploss, comment_profit = "TP❤️️%S", comment_loss = "SL❤️️%S", alert_message = Alert_TPSL)
    //strategy.exit("Exit",'Short', qty_percent = 100, profit = takeprofit, stop = stoploss, comment_profit = "TP❤️️S", comment_loss = "SL❤️️S", alert_message = Alert_TPSL)

//else if strategy.position_size < 0 and strategy.opentrades > 1
//    lastsize = (strategy.position_size) * -1
//    lastprofitorder = strategy.openprofit
//    if lastprofitorder >= 0.07
//        strategy.close_all(comment = "TP❤️️SS", alert_message = Alert_TPSL)

//===================== เรียกใช้  library =========================
import X4815162342/X48_LibaryStrategyStatus/2 as fuLi 
//แสดงผล Backtest

show_Net = input.bool(true,'Monitor Profit&Loss', inline = 'Lnet', group = '= PNL MONITOR SETTING =')
position_ = input.string('bottom_center','Position', options = ['top_right','middle_right','bottom_right','top_center','middle_center','bottom_center','middle_left','bottom_left'] , inline = 'Lnet')
size_i = input.string('auto','size', options = ['auto','tiny','small','normal'] , inline = 'Lnet') 
color_Net = input.color(color.blue,"" , inline = 'Lnet')
// fuLi.NetProfit_Show(show_Net , position_ , size_i,  color_Net )


Plus de