A estratégia AMA Trader v2.1 é uma conversão do consultor especialista MetaTrader 4 AMA_TRADER_v2_1.mq4 que combina rajadas de média móvel adaptativa (AMA) de Kaufman com um filtro Heiken Ashi com suavização dupla e verificações de impulso RSI.
Lógica principal
Filtro de tendência adaptativo – Um mecanismo AMA personalizado reproduz o indicador original, incluindo as constantes rápidas/lentas, a taxa de eficiência e o parâmetro de potência. O algoritmo observa picos de impulso onde o valor AMA salta mais de AmaThreshold etapas de preço em comparação com a barra anterior.
Confirmação de Heiken Ashi – As velas de preço são suavizadas duas vezes: primeiro por uma média móvel configurável nos preços brutos OHLC, depois por uma segunda média móvel nos buffers de Heiken Ashi. Uma barra suavizada de alta (fechada acima da aberta) permite negociações longas, enquanto uma barra de baixa permite vendas curtas.
RSI Verificação de Momentum – Um RSI clássico com período configurável confirma o momentum: os longos exigem que o RSI recue de um valor anterior enquanto permanece abaixo de 70, os vendidos exigem um salto enquanto o oscilador permanece acima de 30.
Gerenciamento de posição – A estratégia abre uma única posição por vez, aplica distâncias opcionais de stop-loss e take-profit (em etapas de preço) e pode rastrear o stop quando o preço se move na direção da negociação. Quando RSI cruza os extremos 70/30, um fechamento parcial opcional é executado antes que ocorra uma saída completa no próximo cruzamento.
Parâmetros
Nome
Padrão
Descrição
CandleType
Velas de 15 minutos
Prazo para todos os cálculos.
TradeVolume
0,1
Volume base de ordens de mercado.
AmaLength
9
Lookback usado pela média móvel adaptativa.
AmaFastPeriod
2
Constante rápida em barras para suavização AMA.
AmaSlowPeriod
30
Constante lenta em barras para suavização AMA.
AmaPower
2
Expoente aplicado à constante de suavização (corresponde a G no código MQ4).
AmaThreshold
2 etapas
Alteração mínima da AMA (em etapas de preço) para acionar um sinal.
FirstMaMethod
Suavizado
Primeiro método de suavização para construção Heiken Ashi.
FirstMaPeriod
6
Comprimento da primeira média móvel de suavização.
SecondMaMethod
Linear Ponderado
Segundo método de suavização aplicado aos buffers Heiken Ashi.
SecondMaPeriod
2
Comprimento da segunda média móvel de suavização.
RsiPeriod
14
RSI período usado pelo filtro de impulso.
PartialClosePercent
70%
Parte da posição ativa a ser fechada quando RSI cruza um extremo. Defina como 0 para desativar.
StopLossSteps
50
Distância de stop-loss expressa em etapas de preço do instrumento. Defina como 0 para desativar.
TakeProfitSteps
100
Distância de lucro expressa em etapas de preço. Defina como 0 para desativar.
TrailingSteps
30
Distância do trailing stop em etapas de preço. Defina como 0 para desativar o rastreamento.
Regras de negociação
Entrada longa – Quando o salto AMA é positivo e excede AmaThreshold, a última vela Heiken Ashi suavizada é de alta e RSI está recuando (valor anterior maior que o valor atual) enquanto permanece em ou abaixo de 70.
Entrada curta – Quando o salto da AMA é negativo além de AmaThreshold, a vela Heiken Ashi suavizada é de baixa e RSI está subindo (valor anterior menor que o atual) enquanto permanece em 30 ou acima.
Fechamento parcial – Se ativado, fecha PartialClosePercent da posição quando RSI cruza acima de 70 (comprados) ou abaixo de 30 (vendidos).
Saída Total – Feche a posição inteira no extremo oposto RSI, em stop-loss, take-profit ou quando o trailing stop for atingido.
A implementação usa o StockSharp API de alto nível: uma assinatura de vela alimenta a calculadora AMA personalizada, o pipeline de suavização Heiken Ashi e o indicador RSI. Todos os comentários no código-fonte estão em inglês, refletindo os requisitos das diretrizes de conversão.
using System;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class AmaTraderV21Strategy : Strategy
{
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast; private decimal _prevSlow; private bool _hasPrev;
private int _cooldown;
public int FastPeriod { get => _fastPeriod.Value; set => _fastPeriod.Value = value; }
public int SlowPeriod { get => _slowPeriod.Value; set => _slowPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public AmaTraderV21Strategy()
{
_fastPeriod = Param(nameof(FastPeriod), 10).SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30).SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame()).SetDisplay("Candle Type", "Candle timeframe", "General");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var fast = new ExponentialMovingAverage { Length = FastPeriod };
var slow = new ExponentialMovingAverage { Length = SlowPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, slow, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev) { _prevFast = fast; _prevSlow = slow; _hasPrev = true; return; }
if (_cooldown > 0) { _cooldown--; _prevFast = fast; _prevSlow = slow; return; }
if (_prevFast <= _prevSlow && fast > slow && Position <= 0)
{ if (Position < 0) BuyMarket(); BuyMarket(); _cooldown = 140; }
else if (_prevFast >= _prevSlow && fast < slow && Position >= 0)
{ if (Position > 0) SellMarket(); SellMarket(); _cooldown = 140; }
_prevFast = fast; _prevSlow = slow;
}
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
_cooldown = 0;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
from datatype_extensions import *
class ama_trader_v21_strategy(Strategy):
"""
AMA Trader V2.1: dual EMA crossover strategy.
"""
def __init__(self):
super(ama_trader_v21_strategy, self).__init__()
self._fast_period = self.Param("FastPeriod", 10) \
.SetDisplay("Fast EMA", "Fast EMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetDisplay("Slow EMA", "Slow EMA period", "Indicators")
self._candle_type = self.Param("CandleType", tf(5)) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def FastPeriod(self): return self._fast_period.Value
@FastPeriod.setter
def FastPeriod(self, v): self._fast_period.Value = v
@property
def SlowPeriod(self): return self._slow_period.Value
@SlowPeriod.setter
def SlowPeriod(self, v): self._slow_period.Value = v
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, v): self._candle_type.Value = v
def OnReseted(self):
super(ama_trader_v21_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(ama_trader_v21_strategy, self).OnStarted2(time)
self._has_prev = False
fast = ExponentialMovingAverage()
fast.Length = self.FastPeriod
slow = ExponentialMovingAverage()
slow.Length = self.SlowPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(fast, slow, self.ProcessCandle).Start()
def ProcessCandle(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_fast = fast
self._prev_slow = slow
self._has_prev = True
return
if self._prev_fast <= self._prev_slow and fast > slow and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_fast >= self._prev_slow and fast < slow and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
"""!! REQUIRED!! Creates a new instance of the strategy."""
return ama_trader_v21_strategy()