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 StochRsiTrendStrategy : Strategy { public List Signals { get; set; } public StochRsiTrendStrategy( string name, int period, int stochPeriod, int signalPeriod, int smoothPeriods) : base(name, StrategyType.StochRsiTrend) { Signals = new List(); StochPeriods = stochPeriod; SignalPeriods = signalPeriod; SmoothPeriods = smoothPeriods; Period = period; } public override List Run() { if (Candles.Count <= 10 * Period + 50) { return null; } try { var stochRsi = Candles .GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value) .RemoveWarmupPeriods().ToList(); var stochRsiCandles = MapStochRsiToCandle(stochRsi, Candles.TakeLast(Period.Value)); if (stochRsi.Count == 0) return null; var previousCandle = stochRsiCandles[0]; foreach (var currentCandle in stochRsiCandles.Skip(1)) { if (currentCandle.Signal < 20) { AddSignal(currentCandle, TradeDirection.Long, Confidence.None); } else if (currentCandle.Signal > 80) { AddSignal(currentCandle, TradeDirection.Short, Confidence.None); } previousCandle = currentCandle; } return Signals.OrderBy(s => s.Date).ToList(); } catch (RuleException) { return null; } } public override StrategiesResultBase GetStrategyValues() { return new StrategiesResultBase() { StochRsi = Candles.GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value) .ToList() }; } private List MapStochRsiToCandle(List ema, IEnumerable candles) { var emaList = new List(); foreach (var candle in candles) { var currentEma = ema.Find(candle.Date); if (currentEma != null) { emaList.Add(new CandleStochRsi() { Close = candle.Close, Open = candle.Open, Date = candle.Date, Ticker = candle.Ticker, Exchange = candle.Exchange, Signal = currentEma.Signal.Value, StochRsi = currentEma.StochRsi.Value }); } } return emaList; } private void AddSignal(CandleStochRsi 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 CandleStochRsi : Candle { public double Signal { get; internal set; } public double StochRsi { get; internal set; } } }