using Managing.Core; using Managing.Domain.Candles; using Managing.Domain.Shared.Rules; using Managing.Domain.Strategies.Base; using Skender.Stock.Indicators; using static Managing.Common.Enums; namespace Managing.Domain.Strategies; public class MacdCrossStrategy : Strategy { public List Signals { get; set; } public MacdCrossStrategy(string name, int fastPeriods, int slowPeriods, int signalPeriods) : base(name, StrategyType.MacdCross) { Signals = new List(); FastPeriods = fastPeriods; SlowPeriods = slowPeriods; SignalPeriods = signalPeriods; } public override List Run() { if (Candles.Count <= 2 * (SlowPeriods + SignalPeriods)) { return null; } try { var macd = Candles.GetMacd(FastPeriods.Value, SlowPeriods.Value, SignalPeriods.Value).ToList(); var macdCandle = MapMacdToCandle(macd, Candles.TakeLast(SignalPeriods.Value)); if (macd.Count == 0) return null; var previousCandle = macdCandle[0]; foreach (var currentCandle in macdCandle.Skip(1)) { if (previousCandle.Histogram > 0 && currentCandle.Histogram < 0 && currentCandle.Macd < 0) { AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium); } if (previousCandle.Histogram < 0 && currentCandle.Histogram > 0 && currentCandle.Macd > 0) { AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium); } previousCandle = currentCandle; } return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList(); } catch (RuleException) { return null; } } public override StrategiesResultBase GetStrategyValues() { return new StrategiesResultBase() { Macd = Candles.GetMacd(FastPeriods.Value, SlowPeriods.Value, SignalPeriods.Value).ToList() }; } private List MapMacdToCandle(List macd, IEnumerable candles) { var macdList = new List(); foreach (var candle in candles) { var currentMacd = macd.Find(candle.Date); if (currentMacd != null) { macdList.Add(new CandleMacd() { Close = candle.Close, Open = candle.Open, Date = candle.Date, Ticker = candle.Ticker, Exchange = candle.Exchange, Macd = currentMacd.Macd.Value, Histogram = currentMacd.Histogram.Value }); } } return macdList; } private void AddSignal(CandleMacd candleSignal, TradeDirection direction, Confidence confidence) { var signal = new Signal(MiscExtensions.ParseEnum(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType); if (!Signals.Any(s => s.Identifier == signal.Identifier)) { Signals.AddItem(signal); } } private class CandleMacd : Candle { public double Macd { get; set; } public double Signal { get; set; } public double Histogram { get; set; } } }