Stratégie multi-périodes de croisement de moyennes mobiles


Date de création: 2023-10-09 16:41:04 Dernière modification: 2023-10-09 16:41:04
Copier: 2 Nombre de clics: 651
1
Suivre
1617
Abonnés

Aperçu

La stratégie est basée sur un système de croisement de moyennes mobiles, utilisant des moyennes mobiles de différentes périodes pour déterminer le moment d’acheter et de vendre. La stratégie combine des fonctionnalités de suivi des tendances telles que les arrêts de perte, les arrêts d’arrêt et les arrêts de perte pour localiser les gains et éviter les risques.

Principe de stratégie

La stratégie utilise deux ensembles de moyennes mobiles, respectivement les lignes rapides et les lignes lentes. Les lignes rapides ont une période plus courte, représentant une tendance à court terme; les lignes lentes ont une période plus longue, représentant une tendance à long terme.

Dans le code, la ligne rapide est ma1 et la ligne lente est ma2. Ma1 et ma2 peuvent choisir différents types de moyennes mobiles, telles que SMA, EMA, etc., et différents paramètres de période peuvent être définis.

Lorsque ma1 est en or, ma2 génère un signal long et fait plus; lorsque ma1 est en or, ma2 génère un signal short et fait court. Lors de la négociation réelle, il peut être combiné avec des fonctions de suivi de tendance, de stop loss, de stop stop loss, etc., pour verrouiller les bénéfices et éviter les risques.

Analyse des avantages

Cette stratégie présente les avantages suivants:

  1. Les idées stratégiques sont simples, claires, faciles à comprendre et à mettre en œuvre.

  2. Les moyennes mobiles de différents types et paramètres peuvent être choisies de manière flexible et s’appliquer à différents environnements de marché.

  3. La conception multi-cyclique capte à la fois les tendances à court et à long terme et évite les erreurs.

  4. Les conditions d’ouverture sont personnalisables et la fréquence des transactions est strictement contrôlée.

  5. Il est possible de définir des conditions d’arrêt et d’arrêt de perte pour contrôler efficacement les risques.

  6. Vous pouvez ajouter un suivi de la tendance, un suivi des pertes et un suivi des bénéfices.

  7. Les paramètres peuvent être optimisés pour rendre la stratégie plus stable et plus fiable.

Analyse des risques

La stratégie présente également les risques suivants:

  1. La croisée des moyennes mobiles doubles est en retard et peut manquer le meilleur moment pour une inversion des prix.

  2. La mauvaise configuration de la moyenne mobile peut générer plus de faux signaux.

  3. Les événements soudains entraînent un retour en arrière rapide, ce qui réduit le risque d’être renversé.

  4. Dans une tendance, il est plus probable que les prix restent du côté de la moyenne pendant une longue période.

  5. Les paramètres ne sont pas optimisés correctement et peuvent être sur-optimisés pour une période donnée.

Les mesures de gestion des risques correspondantes:

  1. En combinaison avec d’autres indicateurs, les signaux de filtrage permettent d’éviter les fausses brèches.

  2. Le réglage des cycles doit suivre le principe du trading de tendance et tester les paramètres d’optimisation.

  3. Le contrôle des risques doit être prudent et les paramètres de stop loss raisonnables.

  4. Le coût de l’attente patiente.

  5. La robustesse des paramètres est testée dans divers environnements de marché.

Direction d’optimisation

Cette stratégie peut être optimisée dans les domaines suivants:

  1. Testez plus de types de moyennes mobiles, comme les moyennes mobiles pondérées.

  2. Augmentation des cycles dynamiques basés sur la volatilité et ajustement des paramètres de la moyenne en fonction des variations du marché.

  3. Les conditions d’entrée stratégiques peuvent être ajoutées à l’horaire ou au filtrage de base pour réduire le taux d’erreur.

  4. Les conditions de sortie permettent de définir un stop-loss dynamique, en ajustant le stop-loss en fonction de la volatilité du marché.

  5. Il est possible d’établir un système d’optimisation des paramètres pour réaliser le retour d’historique et l’optimisation des paramètres de la stratégie.

  6. Ajout d’algorithmes d’apprentissage automatique, utilisant l’IA pour optimiser les paramètres et filtrer les signaux.

Résumer

La stratégie multi-période de croisement de la moyenne mobile est une stratégie de suivi de tendance plus classique. La stratégie permet de réaliser des bénéfices stables en sélectionnant les paramètres appropriés, en optimisant la logique d’entrée et de sortie et en contrôlant strictement le risque.

Code source de la stratégie
/*backtest
start: 2023-09-08 00:00:00
end: 2023-10-08 00:00:00
period: 4h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
// The majority of this script I took from the Autoview website. There are some typos in the original that I've fixed, some things I've added, things I will add, and I'm tired pulling my strategy code out and uploading this to pastebin for people.
// DISCLAIMER: I am not a financial advisor, this is not financial advice, do not use this code without first doing your own research, etc, etc, it's not my fault when you lose your house.

strategy("Moving Averages Cross - MTF - Strategy", "MA Cross", overlay=true, pyramiding=0, initial_capital=100000, currency=currency.USD, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type=strategy.commission.percent, commission_value=0.1)

bgcolor ( color=black, transp=40, title='Blackground', editable=true)

///////////////////////////////////////////////
//* Backtesting Period Selector | Component *//
///////////////////////////////////////////////

//* https://www.tradingview.com/script/eCC1cvxQ-Backtesting-Period-Selector-Component *//
//* https://www.tradingview.com/u/pbergden/ *//
//* Modifications made *//

testStartYear = input(2018, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,00,00)

testStopYear = input(9999, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)

testPeriod() => true

/////////////////////////////////////
//* Put your strategy logic below *//
/////////////////////////////////////

sp1 = input("----", title="--------Moving Average 1----------", options=["----"])
maUseRes1   = input(defval = false, title = "Use Different Resolution?")
//maReso1     = input(defval = "60", title = "Set Resolution", type = resolution)
maReso1     = input(defval='60', title = "Set Resolution Minutes")
maType1     = input("EMA", title="MA", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "Hull", "LSMA", "ALMA"])
maSource1   = input(defval = close, title = "Source")
maLength1   = input(defval = 15, title = "Period", minval = 1)
lsmaOffset1 = input(defval = 1, title = "Least Squares (LSMA) Only - Offset Value", minval = 0)
almaOffset1 = input(defval = 0.85, title = "Arnaud Legoux (ALMA) Only - Offset Value", minval = 0, step = 0.01)
almaSigma1  = input(defval = 6, title = "Arnaud Legoux (ALMA) Only - Sigma Value", minval = 0)

sp2 = input("----", title="--------Moving Average 2----------", options=["----"])
maUseRes2   = input(defval = false, title = "Use Different Resolution?")
//maReso2    = input(defval = "60", title = "Set Resolution", type = resolution)
maReso2     = input(defval='60', title = "Set Resolution Minutes")
maType2    = input("EMA", title="MA", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "Hull", "LSMA", "ALMA"])
maSource2   = input(defval = close, title = "Source")
maLength2   = input(defval = 30, title = "Period", minval = 1)
lsmaOffset2 = input(defval = 1, title = "Least Squares (LSMA) Only - Offset Value", minval = 0)
almaOffset2 = input(defval = 0.85, title = "Arnaud Legoux (ALMA) Only - Offset Value", minval = 0, step = 0.01)
almaSigma2  = input(defval = 6, title = "Arnaud Legoux (ALMA) Only - Sigma Value", minval = 0)

//Function from @JayRogers thank you man awesome work
variant(type, src, len, lsmaOffset, almaOffset, almaSigma) =>
    v1 = sma(src, len)                                                  // Simple
    v2 = ema(src, len)                                                  // Exponential
    v3 = 2 * v2 - ema(v2, len)                                          // Double Exponential
    v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)               // Triple Exponential
    v5 = wma(src, len)                                                  // Weighted
    v6 = vwma(src, len)                                                 // Volume Weighted
    v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len    // Smoothed
    v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))   // Hull
    v9 = linreg(src, len, lsmaOffset)                                   // Least Squares
    v10 = alma(src, len, almaOffset, almaSigma)                         // Arnaud Legoux
    type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="Hull"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1
//Different resolution function    
reso(exp, res, use) => use ? security(tickerid, res, exp) : exp    
    
ma1 = reso(variant(maType1, maSource1, maLength1, lsmaOffset1, almaOffset1, almaSigma1), maReso1, maUseRes1)
ma2 = reso(variant(maType2, maSource2, maLength2, lsmaOffset2, almaOffset2, almaSigma2), maReso2, maUseRes2)

plotma1 = plot(ma1, color=green, tranps=50, linewidth = 2 )
plotma2 = plot(ma2, color=red,   tranps=50, linewidth = 2 )

// Long/Short Logic
longLogic =  crossover(ma1,ma2) ? 1 : 0
shortLogic = crossunder(ma1,ma2) ? 1 : 0

//////////////////////////
//* Strategy Component *//
//////////////////////////

isLong = input(false, "Longs Only")
isShort = input(false, "Shorts Only")
isFlip = input(false, "Flip the Opens")

long = longLogic
short = shortLogic

if isFlip
    long := shortLogic
    short := longLogic
else
    long := longLogic
    short := shortLogic

if isLong
    long := long
    short := na

if isShort
    long := na
    short := short
    
////////////////////////////////
//======[ Signal Count ]======//
////////////////////////////////

sectionLongs = 0
sectionLongs := nz(sectionLongs[1])
sectionShorts = 0
sectionShorts := nz(sectionShorts[1])

if long
    sectionLongs := sectionLongs + 1
    sectionShorts := 0

if short
    sectionLongs := 0
    sectionShorts := sectionShorts + 1

//////////////////////////////
//======[ Pyramiding ]======//
//////////////////////////////

pyrl = input(1, "Pyramiding less than") // If your count is less than this number
pyre = input(0, "Pyramiding equal to") // If your count is equal to this number
pyrg = input(1000000, "Pyramiding greater than") // If your count is greater than this number

longCondition = long and sectionLongs <= pyrl or long and sectionLongs >= pyrg or long and sectionLongs == pyre ? 1 : 0
shortCondition = short and sectionShorts <= pyrl or short and sectionShorts >= pyrg or short and sectionShorts == pyre ? 1 : 0

////////////////////////////////
//======[ Entry Prices ]======//
////////////////////////////////

last_open_longCondition = na
last_open_shortCondition = na
last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1])
last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1])

////////////////////////////////////
//======[ Open Order Count ]======//
////////////////////////////////////

sectionLongConditions = 0
sectionLongConditions := nz(sectionLongConditions[1])
sectionShortConditions = 0
sectionShortConditions := nz(sectionShortConditions[1])

if longCondition
    sectionLongConditions := sectionLongConditions + 1
    sectionShortConditions := 0

if shortCondition
    sectionLongConditions := 0
    sectionShortConditions := sectionShortConditions + 1
    
///////////////////////////////////////////////
//======[ Position Check (long/short) ]======//
///////////////////////////////////////////////

last_longCondition = na
last_shortCondition = na
last_longCondition := longCondition ? time : nz(last_longCondition[1])
last_shortCondition := shortCondition ? time : nz(last_shortCondition[1])

in_longCondition = last_longCondition > last_shortCondition
in_shortCondition = last_shortCondition > last_longCondition

/////////////////////////////////////
//======[ Position Averages ]======//
/////////////////////////////////////

totalLongs = 0.0
totalLongs := nz(totalLongs[1])
totalShorts = 0.0
totalShorts := nz(totalShorts[1])
averageLongs = 0.0
averageLongs := nz(averageLongs[1])
averageShorts = 0.0
averageShorts := nz(averageShorts[1]) 

if longCondition
    totalLongs := totalLongs + last_open_longCondition
    totalShorts := 0.0

if shortCondition
    totalLongs := 0.0
    totalShorts := totalShorts + last_open_shortCondition

averageLongs := totalLongs / sectionLongConditions
averageShorts := totalShorts / sectionShortConditions

/////////////////////////////////
//======[ Trailing Stop ]======//
/////////////////////////////////

isTS = input(false, "Trailing Stop")
tsi = input(1000, "Activate Trailing Stop Price (%). Divided by 100 (1 = 0.01%)") / 100 
ts = input(575, "Trailing Stop (%). Divided by 100 (1 = 0.01%)") / 100

last_high = na
last_low = na
last_high_short = na
last_low_short = na
last_high := not in_longCondition ? na : in_longCondition and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_high_short := not in_shortCondition ? na : in_shortCondition and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_shortCondition ? na : in_shortCondition and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])
last_low_short := not in_longCondition ? na : in_longCondition and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

long_ts = isTS and not na(last_high) and low <= last_high - last_high / 100 * ts and longCondition == 0 and last_high >= averageLongs + averageLongs / 100 * tsi
short_ts = isTS and not na(last_low) and high >= last_low + last_low / 100 * ts and shortCondition == 0 and last_low <= averageShorts - averageShorts/ 100 * tsi

///////////////////////////////
//======[ Take Profit ]======//
///////////////////////////////

isTP = input(false, "Take Profit")
tp = input(300, "Take Profit (%). Divided by 100 (1 = 0.01%)") / 100
long_tp = isTP and close > averageLongs + averageLongs / 100 * tp and not longCondition
short_tp = isTP and close < averageShorts - averageShorts / 100 * tp and not shortCondition

/////////////////////////////
//======[ Stop Loss ]======//
/////////////////////////////

isSL = input(false, "Stop Loss")
sl = input(575, "Stop Loss (%). Divided by 100 (1 = 0.01%)") / 100
long_sl = isSL and close < averageLongs - averageLongs / 100 * sl and longCondition == 0
short_sl = isSL and close > averageShorts + averageShorts / 100 * sl and shortCondition == 0

/////////////////////////////////
//======[ Close Signals ]======//
/////////////////////////////////

longClose = long_tp or long_sl or long_ts  ? 1 : 0
shortClose = short_tp or short_sl or short_ts ? 1: 0

///////////////////////////////
//======[ Plot Colors ]======//
///////////////////////////////

longCloseCol = na
shortCloseCol = na
longCloseCol := long_tp ? purple : long_sl ? maroon : long_ts ? blue : longCloseCol[1]
shortCloseCol := short_tp ? purple : short_sl ? maroon : short_ts ? blue : shortCloseCol[1]
tpColor = isTP and in_longCondition ? purple : isTP and in_shortCondition ? purple : white
slColor = isSL and in_longCondition ? red : isSL and in_shortCondition ? red : white

//////////////////////////////////
//======[ Strategy Plots ]======//
//////////////////////////////////

// Comment out these lines to use alerts
plot(isTS and in_longCondition ? averageLongs + averageLongs / 100 * tsi : na, "Long Trailing Activate", blue, style=3, linewidth=2)
plot(isTS and in_longCondition and last_high >= averageLongs +  averageLongs / 100 * tsi ? last_high - last_high / 100 * ts : na, "Long Trailing", fuchsia, style=2, linewidth=3)
plot(isTS and in_shortCondition ? averageShorts - averageShorts/ 100 * tsi : na, "Short Trailing Activate", blue, style=3, linewidth=2)
plot(isTS and in_shortCondition and last_low <= averageShorts - averageShorts/ 100 * tsi ? last_low + last_low / 100 * ts : na, "Short Trailing", fuchsia, style=2, linewidth=3)
plot(isTP and in_longCondition and last_high < averageLongs + averageLongs / 100 * tp ? averageLongs + averageLongs / 100 * tp : na, "Long TP", tpColor, style=3, linewidth=2)
plot(isTP and in_shortCondition and last_low > averageShorts - averageShorts / 100 * tp ? averageShorts - averageShorts / 100 * tp : na, "Short TP", tpColor, style=3, linewidth=2)
plot(isSL and in_longCondition and last_low_short > averageLongs - averageLongs / 100 * sl ? averageLongs - averageLongs / 100 * sl : na, "Long SL", slColor, style=3, linewidth=2)
plot(isSL and in_shortCondition and last_high_short < averageShorts + averageShorts / 100 * sl ? averageShorts + averageShorts / 100 * sl : na, "Short SL", slColor, style=3, linewidth=2)

///////////////////////////////
//======[ Alert Plots ]======//
///////////////////////////////


// Uncomment to use Alerts, or the new Signal Plots, but not both
// Old Signal Plots
//plot(longCondition, "Long", green)
//plot(shortCondition, "Short", red)
//plot(longClose, "Long Close", longCloseCol)
//plot(shortClose, "Short Close", shortCloseCol)

// Uncomment for your alerts
//alertcondition(condition=longCondition, title="Long", message="")
//alertcondition(condition=shortCondition, title="Short", message="")
//alertcondition(condition=longClose, title="Long Close", message="")
//alertcondition(condition=shortClose, title="Short Close", message="")

///////////////////////////////////
//======[ Reset Variables ]======//
///////////////////////////////////

if longClose or not in_longCondition
    averageLongs := 0
    totalLongs := 0.0
    sectionLongs := 0
    sectionLongConditions := 0

if shortClose or not in_shortCondition
    averageShorts := 0
    totalShorts := 0.0
    sectionShorts := 0
    sectionShortConditions := 0

////////////////////////////////////////////
//======[ Strategy Entry and Exits ]======//
////////////////////////////////////////////

// Comment out to use alerts
if testPeriod()
    strategy.entry("Long", 1, when=longCondition)
    strategy.entry("Short", 0,  when=shortCondition)
    strategy.close("Long", when=longClose)
    strategy.close("Short", when=shortClose)