Stratégie de négociation de crypto-monnaie haussière/baissière basée sur la corrélation basée sur l'indice CCI de Wall Street

Auteur:ChaoZhang est là., Date: 2023-11-01 11h27 et 20h
Les étiquettes:

img

Résumé

Il s'agit d'une stratégie de négociation automatisée qui génère des signaux longs/courts/close sur la crypto-monnaie cible en fonction de la tendance calculée d'une crypto-monnaie de référence considérée comme corrélée avec elle, à l'aide de l'indice Wall Street Chasing Ring.

Avec des paramètres par défaut et ETH/USDT comme symbole de base, la stratégie montre de bons résultats de backtest sur des symboles tels que DENT/USDT, BTT/USDT, FTT/USDT, DOT/USDT, etc. Cela a du sens car ETH est assez influent sur les marchés de la cryptographie.

Remarque: la stratégie avec les paramètres par défaut est destinée à un délai de 4h. Sur d'autres délais, essayez une durée de support différente.

Comment fonctionne la stratégie

  1. Une WMA est calculée sur le symbole de base, avec une longueur de 200 par défaut.

  2. Quand la WMA est en hausse, allez long, quand elle tombe, allez court.

  3. Le TakeProfit pour Long/Short et le StopLoss pour Long/Short sont des pourcentages calculés donc 0,05 = 5% etc. De plus, le TakeProfit/StopLoss sont calculés sur le symbole de base et non sur le symbole du graphique.

  4. La stratégie utilise des ordres de marché pour l'entrée et la sortie basés sur la logique suivante:

    • Lorsque la WMA est en hausse et qu'il n'y a pas de position, entrée longue

    • Lorsque la WMA est en baisse et qu'il n'y a pas de position, une entrée courte

    • Lorsque le bénéfice de la position longue >= TakeProfitLong pourcentage, close long

    • Lorsque le bénéfice de la position courte >= TakeProfitShort en pourcentage, close short

    • Lorsque la perte de position longue >= StopLossLong pourcentage, close long

    • Lorsque la perte de position courte >= StopLossShort en pourcentage, close short

  5. Les prix TakeProfit et StopLoss sont mis à jour en temps réel en fonction des variations de prix du symbole de base.

Analyse des avantages

  1. La stratégie est hautement adaptable pour une utilisation sur plusieurs crypto-monnaies en ajustant les paramètres.

  2. L'utilisation du CCI de Wall Street pour déterminer la tendance permet d'éviter les mauvaises transactions induites par le bruit.

  3. L'intégration de TakeProfit et StopLoss permet de suivre la tendance tout en contrôlant la perte par transaction.

  4. Le trading entièrement automatisé sans intervention manuelle permet un fonctionnement 24 heures sur 24.

Analyse des risques

  1. Risque de découplage du prix de la cryptographie cible de la cryptographie de base, conduisant à l'échec de la stratégie. Peut optimiser en utilisant plusieurs cryptographes de base et en choisissant celui le plus corrélé.

  2. Risque de volatilité soudaine en arrêtant les positions. Peut ajuster le pourcentage StopLoss ou utiliser des arrêts de trailing.

  3. Le risque de TakeProfit pour cent est trop faible pour capturer des gains de tendance suffisants.

  4. Risque de fausse rupture conduisant à une sortie stop-loss.

Directions d'optimisation

  1. Utiliser une analyse de corrélation entre plusieurs cryptos de base et combiner des indicateurs pour réduire le risque de cryptos de base unique.

  2. Ajouter le suivi des tendances pour ajuster dynamiquement TakeProfit/StopLoss en fonction de la volatilité.

  3. Ajoutez des arrêts par étapes pour éviter que des mouvements extrêmes n'arrêtent les positions.

  4. Ajouter une logique de réentrée pour éviter de manquer d'autres tendances après la sortie du stop loss.

  5. Optimiser les paramètres et les réglages du CCI pour améliorer l'efficacité du signal.

  6. Optimiser les paramètres séparément pour chaque crypto cible afin d'améliorer l'adaptabilité.

  7. Optimiser la taille des positions en fonction de la taille du compte.

Résumé

Dans l'ensemble, il s'agit d'une stratégie de suivi de tendance typique. L'idée principale est de déterminer la direction de tendance d'une cryptographie de référence en utilisant le Wall Street CCI et de négocier la cryptographie cible en conséquence. La stratégie présente certains avantages mais aussi des risques à noter.


/*backtest
start: 2022-10-25 00:00:00
end: 2023-10-31 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © levieux

//@version=5
strategy(title='Correlation Strategy', shorttitle='Correlation Strategy', initial_capital=1000, overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)

supportLength = input.int(200, minval=1, title='Support Length')
supportSymbol = input('BTC_USDT:swap', title='Correlated Symbol')
supportSource = input(hlc3, title='Price Source')
takeprofitLong = input.float(0.2, 'Take Profit Long', step=0.01)
takeprofitShort = input.float(0.15, 'Take Profit Short', step=0.01)
stoplossLong = input.float(0.1, 'Stop Loss Long', step=0.01)
stoplossShort = input.float(0.04, 'Stop Loss Short', step=0.01)
start = input(defval = timestamp("01 Jan 2016 00:00 +0000"), title = "Start Time")
end = input(defval = timestamp("31 Dec 2050 23:59 +0000"), title = "End Time")

supportTicker = request.security(supportSymbol, timeframe.period, supportSource, lookahead=barmerge.lookahead_off)  //input(close, title="Source")
supportLine = ta.wma(supportTicker, supportLength)

window() => true

if not window()
    strategy.cancel_all()

supportLongPrice = close
supportShortPrice = close

if strategy.position_size > 0
    supportLongPrice := supportLongPrice[1]
if strategy.position_size < 0
    supportShortPrice := supportShortPrice[1]

longCondition = ta.rising(supportLine, 5) and window() and strategy.position_size <= 0
shortCondition = ta.falling(supportLine, 5) and window() and window() and strategy.position_size > 0
takeprofitLongCondition = takeprofitLong > 0 and window() and strategy.position_size > 0 and supportTicker > supportLongPrice * (1 + takeprofitLong)
stoplossLongCondition = stoplossLong > 0 and window() and strategy.position_size > 0 and supportTicker < supportLongPrice * (1 - stoplossLong)
takeprofitShortCondition = takeprofitShort > 0 and window() and strategy.position_size < 0 and supportTicker > supportShortPrice * (1 + takeprofitShort)
stoplossShortCondition = stoplossShort > 0 and window() and strategy.position_size < 0 and supportTicker < supportShortPrice * (1 - stoplossShort)

if longCondition
    strategy.entry('Long', strategy.long)
    supportLongPrice := supportTicker

if shortCondition
    strategy.entry('Short', strategy.short)
    supportShortPrice := supportTicker

if takeprofitLongCondition
    strategy.close('Long')
if stoplossLongCondition
    strategy.close('Long')
if takeprofitShortCondition
    strategy.close('Short')
if stoplossShortCondition
    strategy.close('Short')

///////////////////
// MONTHLY TABLE //

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_month_pnl = 0.0
cur_year_pnl  = 0.0
cur_month_bh = 0.0
cur_year_bh  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
cur_month_bh := new_month ? 0.0 : 
                 (1 + cur_month_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)
var month_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

end_time = false

end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory

if (not na(cur_month_pnl[1]) and (new_month or end_time))
    if (end_time[1])
        array.pop(month_pnl)
        array.pop(month_time)
        
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])
    array.push(month_bh , cur_month_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or end_time))
    if (end_time[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

// Monthly P&L Table    
var monthly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0 or pnl < 2 * bh
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if end_time
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, str.tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(monthly_table, 13, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100)) + " (" + str.tostring(math.round(array.get(year_bh, yi) * 100)) + ")", bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = getCellColor(array.get(month_pnl, mi), array.get(month_bh, mi))
        
        table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100)) + " (" + str.tostring(math.round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)

Plus de