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.Signals; public class StcIndicator : Indicator { public List Signals { get; set; } public StcIndicator(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, IndicatorType.Stc) { Signals = new List(); FastPeriods = fastPeriods; SlowPeriods = slowPeriods; CyclePeriods = cyclePeriods; } public override List Run() { if (Candles.Count <= 2 * (SlowPeriods + CyclePeriods)) { return null; } try { if (FastPeriods != null) { var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList(); if (CyclePeriods != null) { var stcCandles = MapStcToCandle(stc, Candles.TakeLast(CyclePeriods.Value)); if (stc.Count == 0) return null; var previousCandle = stcCandles[0]; foreach (var currentCandle in stcCandles.Skip(1)) { if (previousCandle.Stc > 75 && currentCandle.Stc <= 75) { AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium); } if (previousCandle.Stc < 25 && currentCandle.Stc >= 25) { 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 IndicatorsResultBase GetIndicatorValues() { if (FastPeriods != null && SlowPeriods != null) { var stc = Candles.GetStc(FastPeriods.Value, FastPeriods.Value, SlowPeriods.Value).ToList(); return new IndicatorsResultBase { Stc = stc }; } return null; } private List MapStcToCandle(List stc, IEnumerable candles) { var sctList = new List(); foreach (var candle in candles) { var currentSct = stc.Find(candle.Date); if (currentSct != null) { sctList.Add(new CandleSct() { Close = candle.Close, Open = candle.Open, Date = candle.Date, Ticker = candle.Ticker, Exchange = candle.Exchange, Stc = currentSct.Stc }); } } return sctList; } private void AddSignal(CandleSct candleSignal, TradeDirection direction, Confidence confidence) { var signal = new Signal( MiscExtensions.ParseEnum(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType, Name); if (!Signals.Any(s => s.Identifier == signal.Identifier)) { Signals.AddItem(signal); } } private class CandleSct : Candle { public double? Stc { get; internal set; } } }