Esta é uma estratégia quantitativa de negociação que utiliza médias móveis e indicadores MACD para operações de avanço em ambas as direções.
A estratégia usa 3 médias móveis SMMA de diferentes comprimentos e 1 média móvel EMA para determinar a direção da tendência. Ao mesmo tempo, combina o indicador MACD para julgar tendências de curto prazo e oportunidades de entrada. Especificamente, a condição de gatilho de compra é: o preço atravessa todas as médias móveis para cima, e as médias mais curtas estão acima das mais longas; enquanto a condição de gatilho de venda é o oposto, o preço atravessa todas as médias móveis para baixo, e as médias mais curtas estão abaixo das mais longas.
Pode-se ver que esta estratégia utiliza médias móveis para julgar as direções da tendência de médio e longo prazo, e MACD para capturar melhores oportunidades de entrada, julgando reversões de curto prazo.
A vantagem desta operação interperíodo é que pode selecionar pontos de reversão de curto prazo adequados para entrar na direção da tendência de alta probabilidade, obtendo assim uma melhor relação risco/recompensação.
A filtragem multi-nível das 3 médias SMMA mais uma linha EMA pode determinar eficazmente a direcção da tendência a médio e longo prazo para evitar a negociação contra a tendência.
O indicador MACD que avalia os pontos de reversão de curto prazo para a entrada pode obter melhores níveis de preços de entrada.
A relação estrita de seqüência da média móvel como condição de filtragem pode reduzir a probabilidade de operações erradas.
Os principais riscos desta estratégia são:
As próprias médias móveis têm propriedades de atraso maiores, que podem perder oportunidades de inversão de tendência a curto prazo.
Os indicadores MACD são propensos a gerar sinais falsos e precisam ser filtrados em combinação com os níveis de preços.
Os julgamentos de vários prazos aumentam a complexidade da estratégia e são propensos ao fracasso.
Para abordar o risco 1 e o risco 2, podemos otimizar encurtando adequadamente a média móvel e o ciclo de sinal para responder rapidamente a inversões de tendência de curto prazo.
Os principais aspectos que podem ser otimizados nesta estratégia incluem:
Otimizar os parâmetros das médias móveis e do MACD para melhor corresponder às características de diferentes ciclos e variedades, como encurtar o comprimento das médias móveis, aumentar o parâmetro do sinal, etc.
Aumentar as estratégias de stop loss utilizando ATR ou outros indicadores para definir paradas em movimento razoáveis.
Procure por melhores indicadores ou métodos de filtragem para substituir os sinais MACD. Por exemplo, introduza indicadores de volatilidade e filtre os sinais de acordo.
Teste diferentes relações de rácio de lucro e perda para obter combinações de parâmetros com melhores rácios risco-recompensa.
Em geral, este é um sistema inovador único com pensamento cross-timeframe. Utiliza as vantagens de médias móveis e MACD para alcançar uma estratégia de operação de julgamento conjunto em vários prazos. Ao otimizar e ajustar parâmetros e critérios de filtragem, essa estratégia pode se tornar uma solução quantitativa de negociação muito prática.
/*backtest start: 2023-10-22 00:00:00 end: 2023-11-21 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/ // © SoftKill21 //@version=4 strategy("Koala Script",initial_capital=1000, commission_type=strategy.commission.cash_per_contract, commission_value=0.000065, slippage=3) fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31) fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12) fromYear = input(defval = 2000, title = "From Year", minval = 1970) // To Date Inputs toDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31) toMonth = input(defval = 8, title = "To Month", minval = 1, maxval = 12) toYear = input(defval = 2031, title = "To Year", minval = 1970) startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) len = input(3, minval=1, title="Length") src = input(hl2, title="Source") smma = 0.0 sma1 = sma(src, len) smma := na(smma[1]) ? sma1 : (smma[1] * (len - 1) + src) / len len2 = input(6, minval=1, title="Length") src2 = input(hl2, title="Source") smma2 = 0.0 sma2 = sma(src2, len2) smma2 := na(smma2[1]) ? sma2 : (smma2[1] * (len2 - 1) + src2) / len2 len3 = input(9, minval=1, title="Length") src3 = input(hl2, title="Source") smma3 = 0.0 sma3 = sma(src3, len3) smma3 := na(smma3[1]) ? sma3 : (smma3[1] * (len3 - 1) + src3) / len3 len4 = input(50, minval=1, title="Length") src4 = input(close, title="Source") smma4 = 0.0 sma4 = sma(src4, len4) smma4 := na(smma4[1]) ? sma4 : (smma4[1] * (len4 - 1) + src4) / len4 len5 = input(200, minval=1, title="Length") src5 = input(close, title="Source") out5 = ema(src5, len5) timeinrange(res, sess) => time(res, sess) != 0 london=timeinrange(timeframe.period, "0300-1045") londonEntry=timeinrange(timeframe.period, "0300-0845") time_cond = time >= startDate and time <= finishDate and londonEntry fast_length = input(title="Fast Length", type=input.integer, defval=12) slow_length = input(title="Slow Length", type=input.integer, defval=26) srcc = input(title="Source", type=input.source, defval=close) signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9) sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false) sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=false) // Calculating fast_ma = sma_source ? sma(srcc, fast_length) : ema(srcc, fast_length) slow_ma = sma_source ? sma(srcc, slow_length) : ema(srcc, slow_length) macd = fast_ma - slow_ma signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length) hist = macd - signal longCond = close > out5 and close > smma4 and close > smma3 and close > smma2 and close > smma and londonEntry and smma > smma2 and smma2>smma3 and smma3>smma4 and smma4>out5 shortCond = close < out5 and close < smma4 and close < smma3 and close < smma2 and close < smma and londonEntry and smma < smma2 and smma2<smma3 and smma3<smma4 and smma4<out5 //longCond2 = crossover(close,out5) and crossover(close,smma4) and crossover(close,smma3) and crossover(close,smma2) and crossover(close,smma) and time_cond //shortCond2 = crossunder(close,out5) and crossunder(close,smma4) and crossunder(close,smma3) and crossunder(close,smma2) and crossunder(close,smma) and time_cond length=input(14, title="ATR Length") mult=input(1.0, title="Percentage Multiplier (for ex., 0.7 = 70%)", step=0.1, minval=0.1, maxval=5.0) oa=input(false, title="Show actual ATR") ii=syminfo.pointvalue==0 s=ii?na:oa?atr(length):(syminfo.pointvalue * mult * atr(length)) tp=input(300,title="tp") sl=input(300,title="sl") //tp = s*10000 //sl= s*10000 //if(tp>300) // tp:=300 //if(sl>300) // sl:=300 //if(sl<150) // sl:=150 //if(tp<150) // tp:=150 strategy.initial_capital = 50000 //MONEY MANAGEMENT--------------------------------------------------------------'' balance = strategy.netprofit + strategy.initial_capital //current balance floating = strategy.openprofit //floating profit/loss risk = input(3,type=input.float,title="Risk %")/100 //risk % per trade //Calculate the size of the next trade temp01 = balance * risk //Risk in USD temp02 = temp01/sl //Risk in lots temp03 = temp02*100000 //Convert to contracts size = temp03 - temp03%1000 //Normalize to 1000s (Trade size) if(size < 10000) size := 10000 //Set min. lot size strategy.entry("long",1,when=longCond ) strategy.exit("closelong","long", profit=tp,loss=sl) //strategy.close("long",when= crossunder(close[4],smma4) and close[4] > close[3] and close[3]>close[2] and close[2] > close[1] and close[1] > close) strategy.entry("short",0,when=shortCond ) strategy.exit("closeshort","short", profit=tp,loss=sl) //strategy.close("short",when= crossover(close[4],smma4) and close[4] < close[3] and close[3]< close[2] and close[2] < close[1] and close[1] < close) strategy.close_all(when = not london) maxEntry=input(2,title="max entries") // strategy.risk.max_intraday_filled_orders(maxEntry)