Esta estratégia usa duas médias móveis com configurações de parâmetros diferentes para operações de crossover para determinar a direção da tendência e posições abertas / fechadas. A estratégia permite escolher entre 9 tipos diferentes de médias móveis, incluindo média móvel simples (SMA), média móvel exponencial (EMA), média móvel ponderada (WMA), média móvel Arnaud Legoux (ALMA), média móvel ponderada por volume (VWMA), etc. A estratégia também define níveis de stop loss e take profit.
A lógica central desta estratégia é comparar os valores de duas linhas médias móveis e determinar a direção da tendência do mercado com base em seu cruzamento. Especificamente, definimos uma linha rápida e uma linha lenta usando duas médias móveis. Quando a linha rápida cruza acima da linha lenta, acreditamos que o mercado está em uma tendência ascendente e vai longo. Quando a linha rápida cruza abaixo da linha lenta, acreditamos que o mercado está em uma tendência descendente e vai curto.
Depois de entrar em uma posição, se o preço tocar a linha de stop loss, sairemos da posição para cortar perdas. Se o preço tocar a linha de take profit, sairemos da posição para bloquear lucros como esperado. Isso nos permite bloquear lucros e evitar que as perdas se expandam ainda mais.
A partir da lógica do código, a estratégia pode ser dividida em quatro partes:
Calcular as médias móveis Com base na selecção do tipo de média móvel pelo utilizador, calcular as médias móveis de linha rápida e de linha lenta.
Gerar sinais comerciais gerar sinais longos e curtos baseados nas situações de cruzamento da linha rápida e linha lenta.
Configure os níveis de stop loss e take profit. Com base no preço de entrada e nas percentagens de stop loss/take profit, calcule os níveis de stop loss e take profit em tempo real.
Entrar com base nos sinais long/short, sair com base nos sinais stop loss/take profit.
A maior vantagem desta estratégia é que permite escolher livremente entre muitos tipos de médias móveis. Diferentes tipos de médias móveis têm diferentes sensibilidades aos preços. Os usuários podem escolher a média móvel apropriada com base em suas próprias necessidades. Além disso, o comprimento das médias móveis pode ser personalizado para otimizar a dimensão do tempo.
Outra vantagem é que os mecanismos de stop loss e take profit são definidos, o que pode efetivamente evitar perdas adicionais e bloquear os lucros.
O principal risco desta estratégia é que as médias móveis têm atraso. Quando os preços flutuam de repente violentamente, as médias móveis não podem responder a tempo, o que pode levar a perder o melhor momento de entrada ou saída. Isso pode levar a grandes perdas.
Outro risco é a definição de níveis de stop loss e take profit. Se a faixa for muito pequena, pode ser vulnerável aos scalpers. Se for muito grande, é fácil não conseguir bloquear os lucros a tempo. Portanto, os parâmetros stop loss/take profit precisam ser otimizados de acordo com as condições do mercado durante a negociação ao vivo.
Em geral, esta estratégia depende principalmente de médias móveis para determinar a direção da tendência. portanto, sua eficácia pode ser comprometida quando eventos repentinos causam grandes oscilações de preços. Além disso, as configurações de parâmetros também podem ter um grande impacto nos retornos da estratégia.
Esta estratégia pode ser otimizada nos seguintes aspectos:
Otimizar o tipo de média móvel. Selecionar as médias móveis mais adequadas com base em diferentes ambientes de mercado e produtos de negociação.
Otimizar os parâmetros da média móvel, ajustar o comprimento da média móvel para que se adapte melhor às características do mercado.
Adicionar outros indicadores para filtragem. MACD, RSI e outros indicadores podem ser adicionados para evitar negociações frequentes quando não há uma tendência clara.
Otimizar os rácios stop loss/take profit. Calcular os parâmetros de stop loss/take profit ideais com base em dados históricos.
Adicionar modelos de aprendizagem de máquina. Use LSTM, algoritmos de floresta aleatória para prever movimentos de preços e ajuda na geração de sinais de negociação.
Adotar algoritmos de stop loss de trailing. permitir que a linha de stop loss se mova gradualmente com os movimentos de preço para reduzir a probabilidade de ser atingida.
Em geral, esta estratégia é relativamente simples e direta. Determina a direção da tendência através de cruzamento e pertence a uma estratégia típica de tendência. As vantagens são ser fácil de entender e altamente flexível com tipos e parâmetros de média móvel personalizáveis. As desvantagens são reações mais lentas a eventos repentinos e algum grau de atraso. Em geral, esta estratégia é adequada para investidores que buscam retornos constantes a longo prazo.
/*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)