Cette stratégie utilise deux moyennes mobiles avec des paramètres différents pour les opérations de croisement afin de déterminer la direction de la tendance et les positions ouvertes/fermées. La stratégie permet de choisir parmi 9 types différents de moyennes mobiles, y compris la moyenne mobile simple (SMA), la moyenne mobile exponentielle (EMA), la moyenne mobile pondérée (WMA), la moyenne mobile Arnaud Legoux (ALMA), la moyenne mobile pondérée en volume (VWMA), etc. La stratégie définit également des niveaux de stop loss et de take profit.
La logique de base de cette stratégie consiste à comparer les valeurs de deux lignes moyennes mobiles et à déterminer la direction de la tendance du marché en fonction de leur croisement. Plus précisément, nous définissons une ligne rapide et une ligne lente en utilisant deux moyennes mobiles. Lorsque la ligne rapide traverse au-dessus de la ligne lente, nous pensons que le marché est en tendance haussière et va long. Lorsque la ligne rapide traverse en dessous de la ligne lente, nous pensons que le marché est en tendance baissière et va court.
Après avoir entré dans une position, si le prix touche la ligne stop loss, nous sortons de la position pour réduire les pertes. Si le prix touche la ligne take profit, nous sortons de la position pour verrouiller les bénéfices comme prévu. Cela nous permet de verrouiller les bénéfices et d'empêcher les pertes de s'étendre davantage.
D'après la logique du code, la stratégie peut être divisée en quatre parties:
Calculer les moyennes mobiles: sur la base du type de moyenne mobile sélectionné par l'utilisateur, calculer les moyennes mobiles de ligne rapide et de ligne lente.
Générer des signaux commerciaux générer des signaux longs et courts basés sur les situations de croisement de la ligne rapide et de la ligne lente.
En fonction du prix d'entrée et des pourcentages de stop loss/take profit définis, calculez en temps réel les niveaux de prix stop loss et take profit.
Entrée et sortie basée sur les signaux long/short, sortie basée sur les signaux stop loss/take profit.
Le plus grand avantage de cette stratégie est qu'elle permet de choisir librement parmi de nombreux types de moyennes mobiles. Différents types de moyennes mobiles ont des sensibilités différentes aux prix. Les utilisateurs peuvent choisir la moyenne mobile appropriée en fonction de leurs propres besoins. En outre, la longueur des moyennes mobiles peut être personnalisée pour optimiser la dimension temporelle.
Une autre avantage est que les mécanismes de stop loss et de take profit sont définis. Cela peut efficacement prévenir de nouvelles pertes et bloquer les bénéfices. Dans l'ensemble, cette stratégie est assez flexible avec une grande personnalisation, adaptée aux utilisateurs ayant des besoins différents.
Le principal risque de cette stratégie est que les moyennes mobiles ont un retard. Lorsque les prix fluctuent soudainement violemment, les moyennes mobiles ne peuvent pas répondre à temps, ce qui peut entraîner une perte du meilleur moment d'entrée ou de sortie. Cela peut entraîner de grosses pertes.
Un autre risque est la mise en place de niveaux de stop loss et de take profit. Si la plage est trop petite, elle peut être vulnérable aux scalpers. Si elle est trop grande, il est facile de ne pas réussir à verrouiller les bénéfices à temps. Par conséquent, les paramètres stop loss / take profit doivent être optimisés en fonction des conditions du marché lors du trading en direct.
En général, cette stratégie repose principalement sur des moyennes mobiles pour déterminer la direction de la tendance.
Cette stratégie peut être optimisée dans les aspects suivants:
Optimiser le type de moyenne mobile. Sélectionner des moyennes mobiles plus appropriées en fonction des différents environnements de marché et des produits de négociation.
Optimiser les paramètres de la moyenne mobile et ajuster la longueur de la moyenne mobile afin de mieux l'adapter aux caractéristiques du marché.
Ajouter d'autres indicateurs pour la filtration. MACD, RSI et d'autres indicateurs peuvent être ajoutés pour éviter les transactions fréquentes lorsqu'il n'y a pas de tendance claire.
Optimiser les ratios stop loss/take profit. Calculer les paramètres optimaux stop loss/take profit sur la base des données historiques.
Ajouter des modèles d'apprentissage automatique. Utiliser LSTM, algorithmes de forêt aléatoires pour prédire les mouvements de prix et aider à générer des signaux de trading.
Adopter des algorithmes de stop loss de suivi. Permettre à la ligne de stop loss de se déplacer progressivement avec les mouvements de prix pour réduire la probabilité d'être touché.
Dans l'ensemble, cette stratégie est relativement simple et directe. Elle détermine la direction de la tendance via un croisement et appartient à une stratégie de suivi de tendance typique. Les avantages sont d'être facile à comprendre et très flexible avec des types et paramètres de moyennes mobiles personnalisables. Les inconvénients sont des réactions plus lentes aux événements soudains et un certain degré de retard. En général, cette stratégie convient aux investisseurs qui recherchent des rendements stables à long terme.
/*backtest start: 2022-12-26 00:00:00 end: 2024-01-01 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 strategy("Kozlod - Yet Another Moving Average Cross Strategy", shorttitle="kozlod_yamacs", overlay = true) // // author: Kozlod // date: 2018-03-06 // //////////// // INPUTS // //////////// ma_type = input(title = "MA Type", defval = "SMA", options = ['SMA', 'EMA', 'WMA', 'ALMA', 'VWMA', 'HMA', 'LSMA', 'SMMA', 'DEMA']) short_ma_len = input(title = "Short MA Length", defval = 5, minval = 1) short_ma_src = input(title = "Short MA Source", defval = close) long_ma_len = input(title = "Long MA Length", defval = 15, minval = 2) long_ma_src = input(title = "Long MA Source", defval = close) alma_offset = input(title = "ALMA Offset", type = float, defval = 0.85, step = 0.01, minval = 0, maxval = 1) alma_sigma = input(title = "ALMA Sigma", type = float, defval = 6, step = 0.01) lsma_offset = input(title = "LSMA Offset", defval = 0, step = 1) sl_lev_perc = input(title = "SL Level % (0 - Off)", type = float, defval = 0, minval = 0, step = 0.01) pt_lev_perc = input(title = "PT Level % (0 - Off)", type = float, defval = 0, minval = 0, step = 0.01) // Set initial values to 0 short_ma = 0.0 long_ma = 0.0 // Simple Moving Average (SMA) if ma_type == 'SMA' short_ma := sma(short_ma_src, short_ma_len) long_ma := sma(long_ma_src, long_ma_len) // Exponential Moving Average (EMA) if ma_type == 'EMA' short_ma := ema(short_ma_src, short_ma_len) long_ma := ema(long_ma_src, long_ma_len) // Weighted Moving Average (WMA) if ma_type == 'WMA' short_ma := wma(short_ma_src, short_ma_len) long_ma := wma(long_ma_src, long_ma_len) // Arnaud Legoux Moving Average (ALMA) if ma_type == 'ALMA' short_ma := alma(short_ma_src, short_ma_len, alma_offset, alma_sigma) long_ma := alma(long_ma_src, long_ma_len, alma_offset, alma_sigma) // Hull Moving Average (HMA) if ma_type == 'HMA' short_ma := wma(2*wma(short_ma_src, short_ma_len/2)-wma(short_ma_src, short_ma_len), round(sqrt(short_ma_len))) long_ma := wma(2*wma(long_ma_src, long_ma_len /2)-wma(long_ma_src, long_ma_len), round(sqrt(long_ma_len))) // Volume-weighted Moving Average (VWMA) if ma_type == 'VWMA' short_ma := vwma(short_ma_src, short_ma_len) long_ma := vwma(long_ma_src, long_ma_len) // Least Square Moving Average (LSMA) if ma_type == 'LSMA' short_ma := linreg(short_ma_src, short_ma_len, lsma_offset) long_ma := linreg(long_ma_src, long_ma_len, lsma_offset) // Smoothed Moving Average (SMMA) if ma_type == 'SMMA' short_ma := na(short_ma[1]) ? sma(short_ma_src, short_ma_len) : (short_ma[1] * (short_ma_len - 1) + short_ma_src) / short_ma_len long_ma := na(long_ma[1]) ? sma(long_ma_src, long_ma_len) : (long_ma[1] * (long_ma_len - 1) + long_ma_src) / long_ma_len // Double Exponential Moving Average (DEMA) if ma_type == 'DEMA' e1_short = ema(short_ma_src, short_ma_len) e1_long = ema(long_ma_src, long_ma_len) short_ma := 2 * e1_short - ema(e1_short, short_ma_len) long_ma := 2 * e1_long - ema(e1_long, long_ma_len) ///////////// // SIGNALS // ///////////// long_signal = crossover( short_ma, long_ma) short_signal = crossunder(short_ma, long_ma) // Calculate PT/SL levels // Initial values last_signal = 0 prev_tr_price = 0.0 pt_level = 0.0 sl_level = 0.0 // Calculate previous trade price prev_tr_price := long_signal[1] or short_signal[1] ? open : nz(last_signal[1]) != 0 ? prev_tr_price[1] : na // Calculate SL/PT levels pt_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 + pt_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 - pt_lev_perc / 100) : na sl_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 - sl_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 + sl_lev_perc / 100) : na // Calculate if price hit sl/pt long_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) == 1 and close >= pt_level long_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) == 1 and close <= sl_level short_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) == -1 and close <= pt_level short_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) == -1 and close >= sl_level // What is last active trade? last_signal := long_signal ? 1 : short_signal ? -1 : long_hit_pt or long_hit_sl or short_hit_pt or short_hit_sl ? 0 : nz(last_signal[1]) ////////////// // PLOTTING // ////////////// // Plot MAs plot(short_ma, color = red, linewidth = 2) plot(long_ma, color = green, linewidth = 2) // Plot Levels plotshape(prev_tr_price, style = shape.cross, color = gray, location = location.absolute, size = size.small) plotshape(sl_lev_perc > 0 ? sl_level : na, style = shape.cross, color = red, location = location.absolute, size = size.small) plotshape(pt_lev_perc > 0 ? pt_level : na, style = shape.cross, color = green, location = location.absolute, size = size.small) ////////////// // STRATEGY // ////////////// strategy.entry("long", true, when = long_signal) strategy.entry("short", false, when = short_signal) strategy.close("long", when = long_hit_pt or long_hit_sl) strategy.close("short", when = short_hit_pt or short_hit_sl)