
Стратегия использует два различных параметров для перекрестных операций с подвижными средними, открывает и закрывает позиции в зависимости от направления тренда, основанного на перекрестных сигналах. Стратегия позволяет выбрать 9 различных типов подвижных средних, включая простые подвижные средние (SMA), индексированные подвижные средние (EMA), весовые подвижные средние (WMA), ALMA и количественные подвижные средние (VWMA).
Центральная логика этой стратегии заключается в сравнении значений двух движущихся средних и определении направления рыночной тенденции на основе пересечения двух движущихся средних. В частности, мы устанавливаем два движущихся средних: быструю и медленную.
После входа в позицию, если цена достигнет стоп-линии, то убыток будет выведен из позиции; если цена достигнет стоп-линии, то прибыль достигнет ожидаемой. Таким образом, можно заблокировать прибыль, чтобы предотвратить расширение убытка.
С точки зрения логики кода, стратегия состоит из четырех частей:
Вычислить скользящую среднюю. В зависимости от выбранного пользователем типа скользящей средней, вычислить скользящую среднюю для быстрой и медленной линии.
генерирует торговые сигналы. В зависимости от пересечения быстрых и медленных линий, генерирует сигналы о доходе и о недоходе.
Установка стоп-стоп-позиции. В зависимости от цены входа и установленного стоп-стоп-процента, в реальном времени рассчитывается цена стоп-линии и стоп-стоп-линии.
Вход и выход. Вход в соответствии с сигналом “сделай больше, сделай пустое”. Выход в соответствии с сигналом “стоп-стоп”.
Самым большим преимуществом этой стратегии является свобода выбора между различными типами скользящих средних. Различные типы скользящих средних имеют разную чувствительность к ценам, и пользователь может выбрать подходящий скользящий средний в соответствии со своими потребностями. Кроме того, можно настроить длину скользящих средних для оптимизации временного измерения.
Еще одним преимуществом является установка механизма стоп-стоп. Это может эффективно предотвратить дальнейшее расширение убытков, при этом блокируя прибыль. В целом, стратегия является более гибкой, с высокой степенью настройки и подходит для пользователей с разными потребностями.
Основной риск этой стратегии заключается в том, что движущаяся средняя имеет запаздывание. Когда цены внезапно сильно колеблются, движущаяся средняя не может вовремя отреагировать, что может привести к тому, что будет пропущен оптимальный момент входа или выхода. Это приводит к большим потерям.
Другим риском является установка стоп-стоп-позиции. Если установка слишком мала, возможно, она будет арбитражирована; если она слишком велика, она может привести к тому, что прибыль не будет заблокирована вовремя. Поэтому в реальном мире параметры стоп-стопа оптимизируются в соответствии с рыночными условиями.
В целом, стратегия опирается на движущиеся средние для определения направления тренда, поэтому эффект снижается, когда внезапные события приводят к значительным колебаниям цен. Кроме того, параметры стратегии также оказывают большое влияние на прибыль стратегии.
Эта стратегия может быть оптимизирована в следующих аспектах:
Типы оптимизированных скользящих средних. Выбор наиболее подходящих скользящих средних в зависимости от различных рыночных условий и видов торгов.
Параметры оптимизации скользящих средних. Корректировка длины скользящих средних периодов, чтобы они соответствовали рыночным характеристикам.
Добавление фильтра на другие индикаторы. Можно добавить другие индикаторы, такие как MACD, RSI, чтобы избежать частой торговли на рынках без тенденций.
Оптимизируйте коэффициент остановки убытков. Вычислите оптимальный параметр остановки убытков на основе исторических данных.
Добавление моделей машинного обучения. Использование алгоритмов, таких как LSTM, Random Forest, для прогнозирования движения цен, а также для генерации торговых сигналов.
Использование алгоритмов отслеживания стоп-убытков. Позволяет стоп-линиям постепенно двигаться в соответствии с движением цены, уменьшая вероятность того, что стоп-убытки будут вызваны.
В целом, эта стратегия является более простой, прямой, ориентированной на тренд, и является типичной стратегией для следования тренду. Преимущества этой стратегии заключаются в простоте и легкости понимания, высокой гибкости, возможности самостоятельного выбора типа движущейся средней и параметров.
/*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)