
A estratégia usa dois diferentes parâmetros de configuração de média móvel para a operação de cruzamento, de acordo com a direção da tendência de julgamento de sinal de cruzamento, para abrir e fechar posições. A estratégia permite a escolha de 9 diferentes tipos de média móvel, incluindo a média móvel simples (SMA), a média móvel indexada (EMA), a média móvel ponderada (WMA), a média móvel de Almo (ALMA) e a média móvel de valor quantitativo (VWMA), etc. A estratégia define simultaneamente o ponto de parada e o ponto de parada.
A lógica central da estratégia é comparar os valores de duas médias móveis e determinar a direção da tendência do mercado com base no cruzamento das duas médias móveis. Concretamente, configuramos duas médias móveis de linha rápida e linha lenta. Quando a linha rápida atravessa a linha lenta, considere que o mercado entrou em uma tendência ascendente, fazendo mais; quando a linha rápida atravessa a linha lenta, considere que o mercado entrou em uma tendência descendente, fazendo vazio.
Depois de entrar em posição, se o preço tocar a linha de parada, o prejuízo é retirado da posição; se o preço tocar a linha de parada, o lucro atinge a expectativa. Isso pode bloquear os lucros e evitar a expansão dos prejuízos.
De acordo com a lógica do código, a estratégia se divide em quatro partes principais:
Calcule a média móvel. Dependendo do tipo de média móvel escolhido pelo usuário, calcule a média móvel de linha rápida e lenta.
Geração de sinais de negociação. Dependendo da intersecção das linhas rápida e lenta, geração de sinais de fazer mais e fazer menos.
De acordo com o preço de entrada e o percentual de parada de parada, o preço da linha de parada e da linha de parada é calculado em tempo real.
Entrar e sair. Entrar de acordo com o sinal de fazer mais e fazer menos. Sair de acordo com o sinal de parar e parar.
A maior vantagem da estratégia é a liberdade de escolher entre vários tipos de médias móveis. Diferentes tipos de médias móveis têm diferentes sensibilidades ao preço, e o usuário pode escolher a média móvel adequada de acordo com suas próprias necessidades. Além disso, é possível personalizar a duração das médias móveis para otimizar a dimensão do tempo.
Outra vantagem é a configuração de um mecanismo de parada de perda. Isso pode prevenir efetivamente a expansão de perdas e, ao mesmo tempo, bloquear os lucros.
O principal risco desta estratégia é que a média móvel é retardada. Quando os preços sofrem uma grande flutuação, a média móvel não pode responder em tempo hábil, o que pode levar a perder o melhor momento de entrada ou saída. Isso pode causar grandes perdas.
Outro risco é a configuração da posição de parada de perda. Se a configuração for muito pequena, é possível que seja arbitragem; se for muito grande, é fácil que os lucros não sejam bloqueados a tempo. Portanto, o parâmetro de parada de perda deve ser otimizado de acordo com a situação do mercado no mercado.
Em geral, a estratégia se baseia principalmente em médias móveis para determinar a direção da tendência, portanto, o efeito é descontado quando eventos inesperados levam a grandes flutuações de preços. Além disso, a configuração de parâmetros também pode ter um grande impacto nos ganhos da estratégia.
A estratégia pode ser melhorada em vários aspectos:
Tipos de Média Móvel Otimizada. Escolha a média móvel mais adequada de acordo com diferentes cenários de mercado e variedades de negociação.
Parâmetros de otimização de médias móveis. Ajustar a duração das médias móveis para que sejam mais adequadas às características do mercado.
Adicionar filtros de outros indicadores. Outros indicadores, como MACD, RSI, podem ser adicionados, evitando a negociação frequente em mercados sem tendência.
Otimizar a proporção de stop loss. Calcular o parâmetro de stop loss ideal com base nos dados históricos.
Adição de modelos de aprendizagem de máquina. Usando algoritmos como LSTM, floresta aleatória e outros para prever movimentos de preços, auxiliando na geração de sinais de negociação.
O uso de algoritmos de rastreamento de stop. Permite que a linha de stop se mova gradualmente com a movimentação do preço, reduzindo a probabilidade de que o stop seja acionado.
A estratégia é simples, direta e, em geral, segue a tendência através da direção da tendência. As vantagens são simples e fáceis de entender, alta flexibilidade, e você pode escolher o tipo de média móvel e os parâmetros. A desvantagem é a reação lenta a eventos inesperados, existindo um certo atraso.
/*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)