Add new strat DualEmaCross

This commit is contained in:
2025-06-02 21:28:56 +07:00
parent de9f77d5ba
commit 7fce1fa59e
22 changed files with 264 additions and 62 deletions

View File

@@ -0,0 +1,74 @@
using Managing.Core;
using Managing.Domain.Shared.Rules;
using Managing.Domain.Strategies.Base;
using Skender.Stock.Indicators;
using static Managing.Common.Enums;
namespace Managing.Domain.Strategies.Trends;
public class EmaTrendStrategy : EmaBaseStrategy
{
public List<Signal> Signals { get; set; }
public EmaTrendStrategy(string name, int period) : base(name, StrategyType.EmaTrend)
{
Signals = new List<Signal>();
Period = period;
}
public override List<Signal> Run()
{
if (Candles.Count <= 2 * Period)
{
return null;
}
try
{
var ema = Candles.GetEma(Period.Value).ToList();
var emaCandles = MapEmaToCandle(ema, Candles.TakeLast(Period.Value));
if (ema.Count == 0)
return null;
var previousCandle = emaCandles[0];
foreach (var currentCandle in emaCandles.Skip(1))
{
if (currentCandle.Close > (decimal)currentCandle.Ema)
{
AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
}
else
{
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()
{
Ema = Candles.GetEma(Period.Value).ToList()
};
}
public void AddSignal(CandleEma candleSignal, TradeDirection direction, Confidence confidence)
{
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
{
Signals.AddItem(signal);
}
}
}

View File

@@ -0,0 +1,123 @@
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.Trends;
public class StochRsiTrendStrategy : Strategy
{
public List<Signal> Signals { get; set; }
public StochRsiTrendStrategy(
string name,
int period,
int stochPeriod,
int signalPeriod,
int smoothPeriods) : base(name, StrategyType.StochRsiTrend)
{
Signals = new List<Signal>();
StochPeriods = stochPeriod;
SignalPeriods = signalPeriod;
SmoothPeriods = smoothPeriods;
Period = period;
}
public override List<Signal> 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<CandleStochRsi> MapStochRsiToCandle(List<StochRsiResult> ema, IEnumerable<Candle> candles)
{
var emaList = new List<CandleStochRsi>();
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<Ticker>(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; }
}
}