Estrategia 3Commas HA & MA
Utiliza velas Heikin Ashi y un par de medias móviles exponenciales. Una operación larga ocurre cuando una vela HA bajista es seguida por una alcista mientras la MA rápida está por encima de la MA lenta. Los cortos siguen la configuración opuesta. Las posiciones se cierran cuando el precio cruza la MA lenta o alcanza el stop de swing.
Detalles
- Criterios de entrada: Reversión de Heikin Ashi con confirmación de MA.
- Largo/Corto: Ambas direcciones.
- Criterios de salida: El precio cruza la MA lenta o stop.
- Stops: Máximo/mínimo del swing.
- Valores predeterminados:
MaFast= 9MaSlow= 18CandleType= TimeSpan.FromMinutes(1)
- Filtros:
- Categoría: Tendencia
- Dirección: Ambos
- Indicadores: Heikin Ashi, EMA
- Stops: Sí
- Complejidad: Intermedio
- Marco temporal: Intradía
- Estacionalidad: No
- Redes neuronales: No
- Divergencia: No
- Nivel de riesgo: Medio
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Heikin Ashi with moving averages.
/// </summary>
public class ThreeCommasHaMaStrategy : Strategy
{
private readonly StrategyParam<int> _maFast;
private readonly StrategyParam<int> _maSlow;
private readonly StrategyParam<DataType> _candleType;
private decimal _haOpenPrev;
private decimal _haClosePrev;
private decimal _stopPrice;
public int MaFast
{
get => _maFast.Value;
set => _maFast.Value = value;
}
public int MaSlow
{
get => _maSlow.Value;
set => _maSlow.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public ThreeCommasHaMaStrategy()
{
_maFast = Param(nameof(MaFast), 9)
.SetDisplay("MA Fast", "Fast moving average period", "MA");
_maSlow = Param(nameof(MaSlow), 18)
.SetDisplay("MA Slow", "Slow moving average period", "MA");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_haOpenPrev = 0m;
_haClosePrev = 0m;
_stopPrice = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var ma1 = new ExponentialMovingAverage { Length = MaFast };
var ma2 = new ExponentialMovingAverage { Length = MaSlow };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ma1, ma2, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, ma1);
DrawIndicator(area, ma2);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal ma1, decimal ma2)
{
if (candle.State != CandleStates.Finished)
return;
var haClose = (candle.OpenPrice + candle.HighPrice + candle.LowPrice + candle.ClosePrice) / 4m;
var haOpen = (_haOpenPrev == 0m && _haClosePrev == 0m) ? (candle.OpenPrice + candle.ClosePrice) / 2m : (_haOpenPrev + _haClosePrev) / 2m;
var haBull = haClose > haOpen;
var haBearPrev = _haClosePrev < _haOpenPrev;
var haBullPrev = _haClosePrev > _haOpenPrev;
if (haBearPrev && ma1 > ma2 && haBull && candle.ClosePrice > ma1 && Position <= 0)
{
_stopPrice = candle.LowPrice;
BuyMarket();
}
else if (haBullPrev && ma1 < ma2 && !haBull && candle.ClosePrice < ma1 && Position >= 0)
{
_stopPrice = candle.HighPrice;
SellMarket();
}
if (Position > 0 && candle.ClosePrice < ma2)
SellMarket();
else if (Position < 0 && candle.ClosePrice > ma2)
BuyMarket();
_haOpenPrev = haOpen;
_haClosePrev = haClose;
}
}
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 DataType, CandleStates
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class three_commas_ha_ma_strategy(Strategy):
def __init__(self):
super(three_commas_ha_ma_strategy, self).__init__()
self._ma_fast = self.Param("MaFast", 9) \
.SetDisplay("MA Fast", "Fast moving average period", "MA")
self._ma_slow = self.Param("MaSlow", 18) \
.SetDisplay("MA Slow", "Slow moving average period", "MA")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._ha_open_prev = 0.0
self._ha_close_prev = 0.0
self._stop_price = 0.0
@property
def ma_fast(self):
return self._ma_fast.Value
@property
def ma_slow(self):
return self._ma_slow.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(three_commas_ha_ma_strategy, self).OnReseted()
self._ha_open_prev = 0.0
self._ha_close_prev = 0.0
self._stop_price = 0.0
def OnStarted2(self, time):
super(three_commas_ha_ma_strategy, self).OnStarted2(time)
ma1 = ExponentialMovingAverage()
ma1.Length = self.ma_fast
ma2 = ExponentialMovingAverage()
ma2.Length = self.ma_slow
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ma1, ma2, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ma1)
self.DrawIndicator(area, ma2)
self.DrawOwnTrades(area)
def on_process(self, candle, ma1, ma2):
if candle.State != CandleStates.Finished:
return
ha_close = (candle.OpenPrice + candle.HighPrice + candle.LowPrice + candle.ClosePrice) / 4
ha_open = ((candle.OpenPrice + candle.ClosePrice) / 2 if (self._ha_open_prev == 0 and self._ha_close_prev == 0) else (self._ha_open_prev + self._ha_close_prev) / 2)
ha_bull = ha_close > ha_open
ha_bear_prev = self._ha_close_prev < self._ha_open_prev
ha_bull_prev = self._ha_close_prev > self._ha_open_prev
if ha_bear_prev and ma1 > ma2 and ha_bull and candle.ClosePrice > ma1 and self.Position <= 0:
self._stop_price = candle.LowPrice
self.BuyMarket()
elif ha_bull_prev and ma1 < ma2 and not ha_bull and candle.ClosePrice < ma1 and self.Position >= 0:
self._stop_price = candle.HighPrice
self.SellMarket()
if self.Position > 0 and candle.ClosePrice < ma2:
self.SellMarket()
elif self.Position < 0 and candle.ClosePrice > ma2:
self.BuyMarket()
self._ha_open_prev = ha_open
self._ha_close_prev = ha_close
def CreateClone(self):
return three_commas_ha_ma_strategy()