Chiến lược này là một hệ thống giao dịch theo xu hướng kết hợp các chỉ số kỹ thuật kép EMA và MACD. Nó nắm bắt xu hướng thị trường thông qua sự chéo chéo của EMA9 với giá và sự chéo chéo của đường MACD nhanh (DIF) với đường chậm (DEA). Chiến lược sử dụng một stop-loss thích nghi dựa trên 5 nến trước đây và sử dụng tỷ lệ phần thưởng-rủi ro 3,5:1 cho các mục tiêu lợi nhuận, tạo thành một hệ thống giao dịch hoàn chỉnh.
Logic cốt lõi được chia thành hướng dài và hướng ngắn: 1. Điều kiện dài: Khi giá đóng phá vỡ trên EMA9 từ dưới, và đường DIF của MACD vượt qua đường DEA, hệ thống tạo ra tín hiệu dài. 2. Điều kiện ngắn: Khi giá đóng phá vỡ dưới EMA9 từ trên và đường DIF của MACD vượt qua dưới đường DEA, hệ thống tạo ra tín hiệu ngắn. 3. Quản lý rủi ro: - Vị trí dài stop-loss được đặt dưới điểm thấp nhất của 5 nến trước đó - Vị trí ngắn dừng lỗ được đặt trên điểm cao nhất của 5 nến trước đó - Mục tiêu lợi nhuận được thiết lập ở 3,5 lần khoảng cách dừng lỗ
Chiến lược này xây dựng một hệ thống giao dịch theo xu hướng hoàn chỉnh thông qua xác nhận hai chỉ số kỹ thuật và quản lý rủi ro nghiêm ngặt. Mặc dù có một số sự phụ thuộc vào môi trường thị trường, chiến lược cho thấy khả năng thích nghi và ổn định tốt thông qua tối ưu hóa tham số hợp lý và quản lý rủi ro.
/*backtest start: 2024-01-17 00:00:00 end: 2025-01-16 00:00:00 period: 2d basePeriod: 2d exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":49999}] */ // ======================= // @version=6 strategy(title="MACD + EMA9 3 h", shorttitle="MACD+EMA9+StopTP_5candles", overlay=true, initial_capital=100000, // Ajuste conforme desejar default_qty_type=strategy.percent_of_equity, default_qty_value=200) // Ajuste % de risco ou quantidade // ----- Entradas (Inputs) ----- emaLen = input.int(9, "Período da EMA 9", minval=1) macdFastLen = input.int(12, "Período MACD Rápido", minval=1) macdSlowLen = input.int(26, "Período MACD Lento", minval=1) macdSignalLen = input.int(9, "Período MACD Signal", minval=1) riskMultiplier = input.float(3.5, "Fator de Multiplicação do Risco (TP)") lookbackCandles = input.int(5, "Quantidade de candles p/ Stop", minval=1) // ----- Cálculo da EMA ----- ema9 = ta.ema(close, emaLen) // ----- Cálculo do MACD ----- [macdLine, signalLine, histLine] = ta.macd(close, macdFastLen, macdSlowLen, macdSignalLen) // DIF cruza DEA para cima ou para baixo macdCrossover = ta.crossover(macdLine, signalLine) // DIF cruza DEA p/ cima macdCrossunder = ta.crossunder(macdLine, signalLine) // DIF cruza DEA p/ baixo // ----- Condições de Compra/Venda ----- // Compra quando: // 1) Preço cruza EMA9 de baixo pra cima // 2) MACD cruza a linha de sinal para cima buySignal = ta.crossover(close, ema9) and macdCrossover // Venda quando: // 1) Preço cruza EMA9 de cima pra baixo // 2) MACD cruza a linha de sinal para baixo sellSignal = ta.crossunder(close, ema9) and macdCrossunder // ----- Execução das ordens ----- // Identifica o menor e o maior preço dos últimos 'lookbackCandles' candles. // A função ta.lowest() e ta.highest() consideram, por padrão, a barra atual também. // Se você quiser EXCLUIR a barra atual, use low[1] / high[1] dentro do ta.lowest() / ta.highest(). lowestLow5 = ta.lowest(low, lookbackCandles) highestHigh5= ta.highest(high, lookbackCandles) // >>> Quando há sinal de COMPRA <<< if (buySignal) // Fecha posição vendida, se existir strategy.close("Sell") // Entra comprado strategy.entry("Buy", strategy.long) // STOP: abaixo do menor preço dos últimos 5 candles stopPrice = lowestLow5 // Risco = (preço de entrada) - (stop) // Note que strategy.position_avg_price só fica disponível a partir da barra seguinte. // Por isso, o exit costuma funcionar corretamente apenas na barra seguinte. // Para fins de teste, podemos usar 'close' como proxy do "entry" (ou aceitar essa limitação). // A forma "correta" de usar strategy.position_avg_price seria via calc_on_order_fills = true, // mas isso pode exigir algumas configurações adicionais. risk = strategy.position_avg_price - stopPrice // Take Profit = entrada + 2,5 * risco takeProfitPrice = strategy.position_avg_price + riskMultiplier * risk // Registra a saída (stop e alvo) vinculada à posição "Buy" strategy.exit("Exit Buy", "Buy", stop=stopPrice, limit=takeProfitPrice) // >>> Quando há sinal de VENDA <<< if (sellSignal) // Fecha posição comprada, se existir strategy.close("Buy") // Entra vendido strategy.entry("Sell", strategy.short) // STOP: acima do maior preço dos últimos 5 candles stopPrice = highestHigh5 // Risco = (stop) - (preço de entrada) risk = stopPrice - strategy.position_avg_price // Take Profit = entrada - 2,5 * risco takeProfitPrice = strategy.position_avg_price - riskMultiplier * risk // Registra a saída (stop e alvo) vinculada à posição "Sell" strategy.exit("Exit Sell", "Sell", stop=stopPrice, limit=takeProfitPrice) // ----- Plotagens visuais ----- plot(ema9, color=color.orange, linewidth=2, title="EMA 9") plot(macdLine, color=color.new(color.blue, 0), title="MACD") plot(signalLine, color=color.new(color.red, 0), title="Signal") plot(histLine, color=color.new(color.purple, 0), style=plot.style_histogram, title="Histogram") // Só para auxiliar na visualização, vamos plotar a linha do lowestLow5 e highestHigh5 plot(lowestLow5, color=color.new(color.lime, 70), style=plot.style_line, title="Lowest 5 bars") plot(highestHigh5, color=color.new(color.fuchsia,70),style=plot.style_line, title="Highest 5 bars")