A estratégia de cruzamento de média móvel dupla julga a direção da tendência do preço calculando médias móveis de diferentes períodos e realiza a tendência seguinte.
Esta estratégia baseia-se em médias móveis exponenciais (EMA) de 9, 21 e 50 períodos. A EMA de 9 períodos representa a tendência de curto prazo, a EMA de 21 períodos representa a tendência de médio prazo e a EMA de 50 períodos representa a tendência de longo prazo.
Quando a EMA de 9 períodos cruza a EMA de 21 períodos, ela sinaliza uma tendência de alta no curto prazo, assim indo longo.
A lógica para entrada longa/curta, take profit e stop loss é configurada. A condição de entrada é o cruzamento dos MA. Long take profit é o preço de entrada * (1 + input take profit ratio), short take profit é o preço de entrada * (1 - input take profit ratio). Long stop loss é o preço de entrada * (1 - input stop loss ratio), short stop loss é o preço de entrada * (1 + input stop loss ratio).
Alguns filtros também são adicionados, como o filtro de tendência para evitar o lado, e o filtro de ações para evitar a negociação quando a ação da estratégia é muito baixa.
Em resumo, esta estratégia usa crossovers duplos da EMA para determinar a direção da tendência do preço, com uma lógica adequada de lucro e stop loss, que pode capturar tendências de médio a longo prazo.
Usando cruzamento duplo de MA para determinar a direção da tendência, a lógica é simples e fácil de entender.
A adopção de EMAs de períodos diferentes pode determinar as tendências a curto e a longo prazo.
O lucro e a lógica de stop loss bloqueiam o lucro e controlam o risco.
Os filtros ajudam a evitar alguns sinais falsos até certo ponto.
Os parâmetros podem ser configurados livremente, os períodos podem ser otimizados para diferentes ambientes de mercado.
Como uma estratégia de um único fator, os sinais de negociação podem não ser estáveis o suficiente.
Quando ocorre o crossover, o preço pode já ter subido/descenso um trecho, com o risco de comprar alto e vender baixo.
Os custos de negociação não são considerados, os retornos reais poderiam ser inferiores.
Não há stop loss em vigor, o risco de perda ilimitada em condições extremas de mercado.
Soluções:
Otimizar os períodos de MA para sinais mais estáveis.
Adicionar outros indicadores aos sinais de filtragem.
Aumentar o volume do comércio para reduzir o impacto dos custos.
Configure o stop loss adequado para limitar a perda máxima.
A estratégia pode ser otimizada nos seguintes aspectos:
Otimizar os períodos de MA para encontrar as melhores combinações ou utilizar a otimização adaptativa para selecionar dinamicamente os melhores períodos.
Adicione outros indicadores técnicos como MACD, KD etc. para filtrar sinais e melhorar a qualidade, ou use aprendizado de máquina para marcar sinais e filtrar falsos.
Incorporar análise de volume. Não captar sinal se o volume for insuficiente no cruzamento MA.
Verifique as flutuações de preços antes de ocorrer o cruzamento.
Construir mecanismos dinâmicos de stop loss como trailing stop loss, Chandelier Exit etc, para reduzir a distância de stop loss, mas mantê-lo eficaz.
Otimizar o dimensionamento das posições, como fixo/dinâmico/leveraged, a fim de alcançar rácios de lucro/perda mais razoáveis.
Considere de forma abrangente os custos de negociação, deslizamento.
A estrutura geral desta estratégia é sólida, com uma lógica simples de cruzamento de EMA dupla para determinar a direção da tendência, juntamente com uma lógica de lucro e stop loss para capturar tendências. Como uma estratégia de fator único, pode ser otimizada ainda mais em parâmetros, filtros de sinal, etc. Para torná-la mais robusta. Com o stop loss e o dimensionamento de posição adequados, os riscos podem ser reduzidos ainda mais.
/*backtest start: 2023-10-16 00:00:00 end: 2023-11-15 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © TradingMentalist //@version=4 strategy("Initial template",initial_capital=1000, overlay=true, pyramiding=0, commission_type=strategy.commission.percent, commission_value=0.04, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, currency = currency.USD) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////inputs //turn on/off longs/shorts / extraneous conditions longinc=input(true, title="include longs?") lConSw2=input(true, title="condition two?") lConSw3=input(true, title="condition three?") shotinc=input(true, title="include shorts?") sConSw2=input(true, title="condition two?") sConSw3=input(true, title="condition three?") //turn on/off / adjust trade filters (average range/average equity) sidein2 = input(200, step=10, title='lookback for average range (bars)') sidein = input(1, title='filter trades if range is less than (%)')/100 equityIn = input(40, title='filter trades if equity is below ema()') sidewayssw = input(true, title='sideways filter?') equitysw = input(true, title='equity filter?') longtpin = input(1,step=0.1, title='long TP %')/100 longslin = input(0.4,step=0.1, title='long SL %')/100 shorttpin = input(1,step=0.1, title='short TP %')/100 shortslin = input(0.4,step=0.1, title='short SL %')/100 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////filters //(leave as is) side1 = (close[1] + close[sidein2]) / 2 side2 = close[1] - close[sidein2] side3 = side2 / side1 notsideways = side3 > sidein equityMa = equitysw ? ema(strategy.equity, equityIn) : 0 equityCon = strategy.equity >= equityMa ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////indicators ma1 = ema(close, 9) ma2 = ema(close, 21) ma3 = ema(close, 50) plot(ma1, color=color.new(#E8B6B0,50)) plot(ma2, color=color.new(#B0E8BE,50)) plot(ma3, color=color.new(#00EEFF,50)) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////conditions //adjust conditions //------------------------------------------- longCondition1 = crossover(ma2,ma3) longCondition2 = close[5] > close[10] longCondition3 = close[1] > close[2] shortCondition1 = crossover(ma3,ma2) shortCondition2 = close[5] < close[10] shortCondition3 = close[1] < close[2] closelong = shortCondition1 closeshort = longCondition1 //------------------------------------------- //(leave as is) longCondition1in = longCondition1 longCondition2in = lConSw2 ? longCondition2 : true longCondition3in = lConSw3 ? longCondition3 : true shortCondition1in = shortCondition1 shortCondition2in = sConSw2 ? shortCondition2: true shortCondition3in = sConSw3 ? shortCondition3: true longConditions = longCondition1in and longCondition2in and longCondition3in shortConditions = shortCondition1in and shortCondition2in and shortCondition3in ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////execution //(leave as is) long = sidewayssw ? notsideways and equityCon and longConditions : equityCon and longConditions short = sidewayssw ? notsideways and equityCon and shortConditions : equityCon and shortConditions ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////risk //(leave as is) longtplevel = strategy.position_avg_price * (1 + longtpin) longsllevel = strategy.position_avg_price * (1 - longslin) shorttplevel = strategy.position_avg_price * (1 - shorttpin) shortsllevel = strategy.position_avg_price * (1 + shortslin) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////timeframe //adjust timeframe //------------------------------------------- startyear = 2000 startmonth = 1 startday = 1 stopyear = 9999 stopmonth = 12 stopday = 31 //------------------------------------------- //(leave as is) startperiod = timestamp(startyear,startmonth,startday,0,0) periodstop = timestamp(stopyear,stopmonth,stopday,0,0) timeframe() => time >= startperiod and time <= periodstop ? true : false ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////orders //comments are empty characters for clear chart if timeframe() if longinc if strategy.position_size == 0 or strategy.position_size > 0 strategy.entry(id="long", long=true, when=long, comment=" ") strategy.exit("stop","long", limit=longtplevel, stop=longsllevel,comment=" ") strategy.close(id="long", when=closelong, comment = " ") if shotinc if strategy.position_size == 0 or strategy.position_size < 0 strategy.entry(id="short", long=false, when=short, comment = " ") strategy.exit("stop","short", limit=shorttplevel, stop=shortsllevel,comment = " ") strategy.close(id="short", when=closeshort, comment = " ")