Remove timeframe from strategy (#13)

This commit is contained in:
Oda
2025-02-26 17:24:59 +07:00
committed by GitHub
parent 298b666a0b
commit 4302bb8435
39 changed files with 299 additions and 288 deletions

View File

@@ -4,17 +4,20 @@ namespace Managing.Domain.Scenarios
{
public class Scenario
{
public Scenario(string name)
public Scenario(string name, int? loopbackPeriod = 1)
{
Name = name;
Strategies = new List<Strategy>();
LoopbackPeriod = loopbackPeriod;
}
public string Name { get; set; }
public List<Strategy> Strategies { get; set; }
public int? LoopbackPeriod { get; set; }
public void AddStrategy(Strategy strategy)
{
Strategies.Add(strategy);
}
}
}
}

View File

@@ -14,25 +14,25 @@ public static class ScenarioHelpers
{
IStrategy result = strategy.Type switch
{
StrategyType.StDev => new StDevContext(strategy.Name, strategy.Timeframe, strategy.Period.Value),
StrategyType.RsiDivergence => new RSIDivergenceStrategy(strategy.Name, strategy.Timeframe,
StrategyType.StDev => new StDevContext(strategy.Name, strategy.Period.Value),
StrategyType.RsiDivergence => new RSIDivergenceStrategy(strategy.Name,
strategy.Period.Value),
StrategyType.RsiDivergenceConfirm => new RSIDivergenceConfirmStrategy(strategy.Name, strategy.Timeframe,
StrategyType.RsiDivergenceConfirm => new RSIDivergenceConfirmStrategy(strategy.Name,
strategy.Period.Value),
StrategyType.MacdCross => new MacdCrossStrategy(strategy.Name, strategy.Timeframe,
StrategyType.MacdCross => new MacdCrossStrategy(strategy.Name,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value, strategy.SignalPeriods.Value),
StrategyType.EmaCross => new EmaCrossStrategy(strategy.Name, strategy.Timeframe, strategy.Period.Value),
StrategyType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersStrategy(strategy.Name, strategy.Timeframe,
StrategyType.EmaCross => new EmaCrossStrategy(strategy.Name, strategy.Period.Value),
StrategyType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersStrategy(strategy.Name,
strategy.Period.Value),
StrategyType.SuperTrend => new SuperTrendStrategy(strategy.Name, strategy.Timeframe,
StrategyType.SuperTrend => new SuperTrendStrategy(strategy.Name,
strategy.Period.Value, strategy.Multiplier.Value),
StrategyType.ChandelierExit => new ChandelierExitStrategy(strategy.Name, strategy.Timeframe,
StrategyType.ChandelierExit => new ChandelierExitStrategy(strategy.Name,
strategy.Period.Value, strategy.Multiplier.Value),
StrategyType.EmaTrend => new EmaTrendStrategy(strategy.Name, strategy.Timeframe, strategy.Period.Value),
StrategyType.StochRsiTrend => new StochRsiTrendStrategy(strategy.Name, strategy.Timeframe,
StrategyType.EmaTrend => new EmaTrendStrategy(strategy.Name, strategy.Period.Value),
StrategyType.StochRsiTrend => new StochRsiTrendStrategy(strategy.Name,
strategy.Period.Value, strategy.StochPeriods.Value, strategy.SignalPeriods.Value,
strategy.SmoothPeriods.Value),
StrategyType.Stc => new STCStrategy(strategy.Name, strategy.Timeframe, strategy.CyclePeriods.Value,
StrategyType.Stc => new STCStrategy(strategy.Name, strategy.CyclePeriods.Value,
strategy.FastPeriods.Value, strategy.SlowPeriods.Value),
_ => throw new NotImplementedException(),
};
@@ -46,7 +46,6 @@ public static class ScenarioHelpers
public static Strategy BuildStrategy(
StrategyType type,
Timeframe timeframe,
string name,
int? period = null,
int? fastPeriods = null,
@@ -57,7 +56,7 @@ public static class ScenarioHelpers
int? smoothPeriods = null,
int? cyclePeriods = null)
{
var strategy = new Strategy(name, timeframe, type);
var strategy = new Strategy(name, type);
switch (type)
{

View File

@@ -10,7 +10,7 @@ namespace Managing.Domain.Shared.Helpers;
public static class TradingBox
{
public static Signal GetSignal(HashSet<Candle> newCandles, HashSet<IStrategy> strategies,
HashSet<Signal> previousSignal)
HashSet<Signal> previousSignal, int? loopbackPeriod = 1)
{
var signalOnCandles = new HashSet<Signal>();
var limitedCandles = newCandles.ToList().TakeLast(600).ToList();
@@ -21,7 +21,9 @@ public static class TradingBox
if (signals == null || signals.Count == 0) continue;
foreach (var signal in signals.Where(s => s.Date == newCandles.Last().Date))
var candleLoopback = limitedCandles.TakeLast(loopbackPeriod ?? 1).ToList();
foreach (var signal in signals.Where(s => s.Date >= candleLoopback.FirstOrDefault()?.Date))
{
if (previousSignal.SingleOrDefault(s => s.Identifier == signal.Identifier) == null)
{
@@ -68,7 +70,6 @@ public static class TradingBox
signals.Last().Candle,
signals.Last().Date,
signals.Last().Exchange,
timeframe,
StrategyType.Composite, SignalType.Signal);
}
else if (signals.All(s => s.Direction == TradeDirection.Short) &&
@@ -81,7 +82,6 @@ public static class TradingBox
signals.Last().Candle,
signals.Last().Date,
signals.Last().Exchange,
timeframe,
StrategyType.Composite, SignalType.Signal);
}
}

View File

@@ -6,7 +6,7 @@ namespace Managing.Domain.Strategies.Base;
public abstract class EmaBaseStrategy : Strategy
{
protected EmaBaseStrategy(string name, Enums.Timeframe timeframe, Enums.StrategyType type) : base(name, timeframe, type)
protected EmaBaseStrategy(string name, Enums.StrategyType type) : base(name, type)
{
}
@@ -29,6 +29,7 @@ public abstract class EmaBaseStrategy : Strategy
});
}
}
return emaList;
}
@@ -36,4 +37,4 @@ public abstract class EmaBaseStrategy : Strategy
{
public double Ema { get; set; }
}
}
}

View File

@@ -9,7 +9,8 @@ namespace Managing.Domain.Strategies;
public class ChandelierExitStrategy : Strategy
{
public List<Signal> Signals { get; set; }
public ChandelierExitStrategy(string name, Timeframe timeframe, int period, double multiplier) : base(name, timeframe, StrategyType.ChandelierExit)
public ChandelierExitStrategy(string name, int period, double multiplier) : base(name, StrategyType.ChandelierExit)
{
Signals = new List<Signal>();
Period = period;
@@ -39,28 +40,29 @@ public class ChandelierExitStrategy : Strategy
private void GetSignals(ChandelierType chandelierType)
{
var chandelier = Candles.GetChandelier(Period.Value, Multiplier.Value, chandelierType).Where(s => s.ChandelierExit.HasValue).ToList();
var chandelier = Candles.GetChandelier(Period.Value, Multiplier.Value, chandelierType)
.Where(s => s.ChandelierExit.HasValue).ToList();
var chandelierCandle = MapChandelierToCandle(chandelier, Candles.TakeLast(MinimumHistory));
var previousCandle = chandelierCandle[0];
foreach (var currentCandle in chandelierCandle.Skip(1))
{
// Short
if (currentCandle.Close < previousCandle.ChandelierExit &&
if (currentCandle.Close < previousCandle.ChandelierExit &&
previousCandle.Close > previousCandle.ChandelierExit &&
currentCandle.Close < previousCandle.Open &&
chandelierType == ChandelierType.Short)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
}
// Long
if (currentCandle.Close > previousCandle.ChandelierExit &&
if (currentCandle.Close > previousCandle.ChandelierExit &&
previousCandle.Close < previousCandle.ChandelierExit &&
currentCandle.Close > currentCandle.Open &&
chandelierType == ChandelierType.Long)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
}
previousCandle = currentCandle;
@@ -90,7 +92,8 @@ public class ChandelierExitStrategy : Strategy
return superTrends;
}
private void AddSignal(CandleChandelier candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleChandelier candleSignal, TradeDirection direction,
Confidence confidence)
{
var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -99,7 +102,6 @@ public class ChandelierExitStrategy : Strategy
candleSignal,
candleSignal.Date,
candleSignal.Exchange,
timeframe,
Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
{
@@ -112,4 +114,4 @@ public class ChandelierExitStrategy : Strategy
{
public decimal ChandelierExit { get; internal set; }
}
}
}

View File

@@ -10,7 +10,7 @@ public class EmaCrossStrategy : EmaBaseStrategy
{
public List<Signal> Signals { get; set; }
public EmaCrossStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.EmaCross)
public EmaCrossStrategy(string name, int period) : base(name, StrategyType.EmaCross)
{
Signals = new List<Signal>();
Period = period;
@@ -37,13 +37,13 @@ public class EmaCrossStrategy : EmaBaseStrategy
if (previousCandle.Close > (decimal)currentCandle.Ema &&
currentCandle.Close < (decimal)currentCandle.Ema)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
}
if (previousCandle.Close < (decimal)currentCandle.Ema &&
currentCandle.Close > (decimal)currentCandle.Ema)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
}
previousCandle = currentCandle;
@@ -57,10 +57,10 @@ public class EmaCrossStrategy : EmaBaseStrategy
}
}
private void AddSignal(CandleEma candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleEma candleSignal, TradeDirection direction, Confidence confidence)
{
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType);
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
{
Signals.AddItem(signal);

View File

@@ -10,7 +10,7 @@ public class EmaTrendStrategy : EmaBaseStrategy
{
public List<Signal> Signals { get; set; }
public EmaTrendStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.EmaTrend)
public EmaTrendStrategy(string name, int period) : base(name, StrategyType.EmaTrend)
{
Signals = new List<Signal>();
Period = period;
@@ -36,11 +36,11 @@ public class EmaTrendStrategy : EmaBaseStrategy
{
if (currentCandle.Close > (decimal)currentCandle.Ema)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.None);
AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
}
else
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.None);
AddSignal(currentCandle, TradeDirection.Short, Confidence.None);
}
previousCandle = currentCandle;
@@ -54,12 +54,13 @@ public class EmaTrendStrategy : EmaBaseStrategy
}
}
public void AddSignal(CandleEma candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
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, timeframe, Type, SignalType);
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

@@ -10,8 +10,8 @@ public class MacdCrossStrategy : Strategy
{
public List<Signal> Signals { get; set; }
public MacdCrossStrategy(string name, Timeframe timeframe, int fastPeriods, int slowPeriods, int signalPeriods) :
base(name, timeframe, StrategyType.MacdCross)
public MacdCrossStrategy(string name, int fastPeriods, int slowPeriods, int signalPeriods) :
base(name, StrategyType.MacdCross)
{
Signals = new List<Signal>();
FastPeriods = fastPeriods;
@@ -39,12 +39,12 @@ public class MacdCrossStrategy : Strategy
{
if (previousCandle.Histogram > 0 && currentCandle.Histogram < 0 && currentCandle.Macd < 0)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
}
if (previousCandle.Histogram < 0 && currentCandle.Histogram > 0 && currentCandle.Macd > 0)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
}
previousCandle = currentCandle;
@@ -82,11 +82,11 @@ public class MacdCrossStrategy : Strategy
return macdList;
}
private void AddSignal(CandleMacd candleSignal, Timeframe timeframe, TradeDirection direction,
private void AddSignal(CandleMacd candleSignal, TradeDirection direction,
Confidence confidence)
{
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence,
candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType);
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
{
Signals.AddItem(signal);

View File

@@ -10,7 +10,7 @@ public class RSIDivergenceConfirmStrategy : Strategy
{
public List<Signal> Signals { get; set; }
public RSIDivergenceConfirmStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.RsiDivergenceConfirm)
public RSIDivergenceConfirmStrategy(string name, int period) : base(name, StrategyType.RsiDivergenceConfirm)
{
Period = period;
Signals = new List<Signal>();
@@ -88,7 +88,7 @@ public class RSIDivergenceConfirmStrategy : Strategy
// Price go down but RSI go up
if (currentCandle.Close < lowPrices.TakeLast(Period.Value).Min(p => p.Close))
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.None);
AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
}
}
else
@@ -163,7 +163,7 @@ public class RSIDivergenceConfirmStrategy : Strategy
// Price go up but RSI go down
if (currentCandle.Close > highPrices.TakeLast(Period.Value).Max(p => p.Close))
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.None);
AddSignal(currentCandle, TradeDirection.Short, Confidence.None);
}
}
else
@@ -199,31 +199,32 @@ public class RSIDivergenceConfirmStrategy : Strategy
{
var lastCandleOnPeriod = Candles.TakeLast(Period.Value).ToList();
var signalsOnPeriod = Signals.Where(s => s.Date >= lastCandleOnPeriod[0].Date
&& s.Date < currentCandle.Date
&& s.Direction == direction
&& s.Confidence == Confidence.None
&& s.Status != SignalStatus.Expired
&& s.Status != SignalStatus.PositionOpen).ToList();
&& s.Date < currentCandle.Date
&& s.Direction == direction
&& s.Confidence == Confidence.None
&& s.Status != SignalStatus.Expired
&& s.Status != SignalStatus.PositionOpen).ToList();
foreach (var signal in signalsOnPeriod)
{
if (direction == TradeDirection.Short && currentCandle.Close < signal.Candle.Open)
{
AddSignal(currentCandle, Timeframe, direction, Confidence.High);
AddSignal(currentCandle, direction, Confidence.High);
Signals.FirstOrDefault(s => s.Identifier == signal.Identifier).Status = SignalStatus.Expired;
}
if (direction == TradeDirection.Long && currentCandle.Close > signal.Candle.Open)
{
AddSignal(currentCandle, Timeframe, direction, Confidence.High);
AddSignal(currentCandle, direction, Confidence.High);
Signals.FirstOrDefault(s => s.Identifier == signal.Identifier).Status = SignalStatus.Expired;
}
}
}
private void AddSignal(CandleRsi candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleRsi candleSignal, TradeDirection direction, Confidence confidence)
{
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType);
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);
@@ -233,7 +234,6 @@ public class RSIDivergenceConfirmStrategy : Strategy
private List<CandleRsi> MapRsiToCandle(IReadOnlyCollection<RsiResult> rsiResult,
IEnumerable<Candle> candles)
{
return candles.Select(c => new CandleRsi()
{
Close = c.Close,
@@ -249,4 +249,4 @@ public class RSIDivergenceConfirmStrategy : Strategy
{
public double Rsi { get; set; }
}
}
}

View File

@@ -13,7 +13,7 @@ public class RSIDivergenceStrategy : Strategy
private const int UpperBand = 70;
private const int LowerBand = 30;
public RSIDivergenceStrategy(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.RsiDivergence)
public RSIDivergenceStrategy(string name, int period) : base(name, StrategyType.RsiDivergence)
{
Period = period;
Signals = new List<Signal>();
@@ -91,7 +91,7 @@ public class RSIDivergenceStrategy : Strategy
// Price go down but RSI go up
if (currentCandle.Close < lowPrices.TakeLast(Period.Value).Min(p => p.Close))
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long);
AddSignal(currentCandle, TradeDirection.Long);
}
}
else
@@ -164,7 +164,7 @@ public class RSIDivergenceStrategy : Strategy
// Price go up but RSI go down
if (currentCandle.Close > highPrices.TakeLast(Period.Value).Max(p => p.Close))
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short);
AddSignal(currentCandle, TradeDirection.Short);
}
}
else
@@ -194,9 +194,10 @@ public class RSIDivergenceStrategy : Strategy
}
}
private void AddSignal(CandleRsi candleSignal, Timeframe timeframe, TradeDirection direction)
private void AddSignal(CandleRsi candleSignal, TradeDirection direction)
{
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, Confidence.Low, candleSignal, candleSignal.Date, candleSignal.Exchange, timeframe, Type, SignalType);
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, Confidence.Low,
candleSignal, candleSignal.Date, candleSignal.Exchange, Type, SignalType);
if (Signals.Count(s => s.Identifier == signal.Identifier) < 1)
{
@@ -216,7 +217,6 @@ public class RSIDivergenceStrategy : Strategy
private List<CandleRsi> MapRsiToCandle(IReadOnlyCollection<RsiResult> rsiResult,
IEnumerable<Candle> candles)
{
return candles.Select(c => new CandleRsi()
{
Close = c.Close,
@@ -231,4 +231,4 @@ public class RSIDivergenceStrategy : Strategy
{
public double Rsi { get; set; }
}
}
}

View File

@@ -10,7 +10,7 @@ public class STCStrategy : Strategy
{
public List<Signal> Signals { get; set; }
public STCStrategy(string name, Timeframe timeframe, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, timeframe, StrategyType.Stc)
public STCStrategy(string name, int cyclePeriods, int fastPeriods, int slowPeriods) : base(name, StrategyType.Stc)
{
Signals = new List<Signal>();
FastPeriods = fastPeriods;
@@ -38,12 +38,12 @@ public class STCStrategy : Strategy
{
if (previousCandle.Stc > 75 && currentCandle.Stc <= 75)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
}
if (previousCandle.Stc < 25 && currentCandle.Stc >= 25)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
}
previousCandle = currentCandle;
@@ -76,10 +76,11 @@ public class STCStrategy : Strategy
});
}
}
return sctList;
}
private void AddSignal(CandleSct candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleSct candleSignal, TradeDirection direction, Confidence confidence)
{
var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -88,7 +89,6 @@ public class STCStrategy : Strategy
candleSignal,
candleSignal.Date,
candleSignal.Exchange,
timeframe,
Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
{
@@ -100,4 +100,4 @@ public class STCStrategy : Strategy
{
public double? Stc { get; internal set; }
}
}
}

View File

@@ -1,37 +1,26 @@
using Managing.Core;
using System.ComponentModel.DataAnnotations;
using Managing.Core;
using Managing.Domain.Candles;
using System.ComponentModel.DataAnnotations;
using static Managing.Common.Enums;
namespace Managing.Domain.Strategies
{
public class Signal : ValueObject
{
[Required]
public SignalStatus Status { get; set; }
[Required]
public TradeDirection Direction { get; }
[Required]
public Confidence Confidence { get; private set; }
[Required]
public Timeframe Timeframe { get; }
[Required]
public DateTime Date { get; private set; }
[Required]
public Candle Candle { get; }
[Required]
public string Identifier { get; }
[Required]
public Ticker Ticker { get; }
[Required]
public TradingExchanges Exchange { get; set; }
[Required]
public StrategyType StrategyType { get; set; }
[Required]
public SignalType SignalType { get; set; }
[Required] public SignalStatus Status { get; set; }
[Required] public TradeDirection Direction { get; }
[Required] public Confidence Confidence { get; private set; }
[Required] public Timeframe Timeframe { get; }
[Required] public DateTime Date { get; private set; }
[Required] public Candle Candle { get; }
[Required] public string Identifier { get; }
[Required] public Ticker Ticker { get; }
[Required] public TradingExchanges Exchange { get; set; }
[Required] public StrategyType StrategyType { get; set; }
[Required] public SignalType SignalType { get; set; }
public Signal(Ticker ticker, TradeDirection direction, Confidence confidence, Candle candle, DateTime date,
TradingExchanges exchange, Timeframe timeframe, StrategyType strategyType, SignalType signalType)
TradingExchanges exchange, StrategyType strategyType, SignalType signalType)
{
Direction = direction;
Confidence = confidence;
@@ -40,10 +29,9 @@ namespace Managing.Domain.Strategies
Ticker = ticker;
Exchange = exchange;
Status = SignalStatus.WaitingForPosition;
Timeframe = timeframe;
StrategyType = strategyType;
Identifier = $"{StrategyType}-{direction}-{ticker}-{Timeframe}-{candle?.Close}-{date:yyyyMMdd-HHmmss}";
Identifier = $"{StrategyType}-{direction}-{ticker}-{candle?.Close}-{date:yyyyMMdd-HHmmss}";
SignalType = signalType;
}
@@ -59,4 +47,4 @@ namespace Managing.Domain.Strategies
yield return Date;
}
}
}
}

View File

@@ -10,7 +10,7 @@ public class StDevContext : Strategy
{
public List<Signal> Signals { get; set; }
public StDevContext(string name, Timeframe timeframe, int period) : base(name, timeframe, StrategyType.StDev)
public StDevContext(string name, int period) : base(name, StrategyType.StDev)
{
Signals = new List<Signal>();
Period = period;
@@ -35,7 +35,7 @@ public class StDevContext : Strategy
if (lastCandle.ZScore is < 1.2 and > (-1.2))
{
AddSignal(lastCandle, Timeframe, TradeDirection.None, Confidence.Medium);
AddSignal(lastCandle, TradeDirection.None, Confidence.Medium);
}
else
{
@@ -72,10 +72,12 @@ public class StDevContext : Strategy
});
}
}
return sctList;
}
private void AddSignal(CandleStDev candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleStDev candleSignal, TradeDirection direction,
Confidence confidence)
{
var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -84,7 +86,6 @@ public class StDevContext : Strategy
candleSignal,
candleSignal.Date,
candleSignal.Exchange,
timeframe,
Type, SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
{
@@ -99,4 +100,4 @@ public class StDevContext : Strategy
public double? StdDevSma { get; internal set; }
public double? Mean { get; internal set; }
}
}
}

View File

@@ -12,11 +12,10 @@ public class StochRsiTrendStrategy : Strategy
public StochRsiTrendStrategy(
string name,
Timeframe timeframe,
int period,
int stochPeriod,
int signalPeriod,
int smoothPeriods) : base(name, timeframe, StrategyType.StochRsiTrend)
int smoothPeriods) : base(name, StrategyType.StochRsiTrend)
{
Signals = new List<Signal>();
StochPeriods = stochPeriod;
@@ -34,7 +33,9 @@ public class StochRsiTrendStrategy : Strategy
try
{
var stochRsi = Candles.GetStochRsi(Period.Value, StochPeriods.Value, SignalPeriods.Value, SmoothPeriods.Value).RemoveWarmupPeriods().ToList();
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)
@@ -45,11 +46,11 @@ public class StochRsiTrendStrategy : Strategy
{
if (currentCandle.Signal < 20)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.None);
AddSignal(currentCandle, TradeDirection.Long, Confidence.None);
}
else if (currentCandle.Signal > 80)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.None);
AddSignal(currentCandle, TradeDirection.Short, Confidence.None);
}
previousCandle = currentCandle;
@@ -83,10 +84,11 @@ public class StochRsiTrendStrategy : Strategy
});
}
}
return emaList;
}
private void AddSignal(CandleStochRsi candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleStochRsi candleSignal, TradeDirection direction, Confidence confidence)
{
var signal = new Signal(
MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker),
@@ -95,7 +97,6 @@ public class StochRsiTrendStrategy : Strategy
candleSignal,
candleSignal.Date,
candleSignal.Exchange,
timeframe,
Type,
SignalType);
if (!Signals.Any(s => s.Identifier == signal.Identifier))
@@ -109,4 +110,4 @@ public class StochRsiTrendStrategy : Strategy
public double Signal { get; internal set; }
public double StochRsi { get; internal set; }
}
}
}

View File

@@ -8,16 +8,14 @@ namespace Managing.Domain.Strategies
{
public class Strategy : IStrategy
{
public Strategy(string name, Timeframe timeframe, StrategyType type)
public Strategy(string name, StrategyType type)
{
Name = name;
Timeframe = timeframe;
Type = type;
SignalType = ScenarioHelpers.GetSignalType(type);
}
public string Name { get; set; }
public Timeframe Timeframe { get; set; }
[JsonIgnore] public FixedSizeQueue<Candle> Candles { get; set; }
public StrategyType Type { get; set; }
public SignalType SignalType { get; set; }

View File

@@ -10,7 +10,7 @@ public class SuperTrendStrategy : Strategy
{
public List<Signal> Signals { get; set; }
public SuperTrendStrategy(string name, Timeframe timeframe, int period, double multiplier) : base(name, timeframe, StrategyType.SuperTrend)
public SuperTrendStrategy(string name, int period, double multiplier) : base(name, StrategyType.SuperTrend)
{
Signals = new List<Signal>();
Period = period;
@@ -27,7 +27,8 @@ public class SuperTrendStrategy : Strategy
try
{
var superTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue).ToList();
var superTrend = Candles.GetSuperTrend(Period.Value, Multiplier.Value).Where(s => s.SuperTrend.HasValue)
.ToList();
var superTrendCandle = MapSuperTrendToCandle(superTrend, Candles.TakeLast(MinimumHistory));
if (superTrendCandle.Count == 0)
@@ -39,13 +40,13 @@ public class SuperTrendStrategy : Strategy
// Short
if (currentCandle.Close < previousCandle.SuperTrend && previousCandle.Close > previousCandle.SuperTrend)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Short, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
}
// Long
if (currentCandle.Close > previousCandle.SuperTrend && previousCandle.Close < previousCandle.SuperTrend)
{
AddSignal(currentCandle, Timeframe, TradeDirection.Long, Confidence.Medium);
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
}
previousCandle = currentCandle;
@@ -84,10 +85,11 @@ public class SuperTrendStrategy : Strategy
return superTrends;
}
private void AddSignal(CandleSuperTrend candleSignal, Timeframe timeframe, TradeDirection direction, Confidence confidence)
private void AddSignal(CandleSuperTrend candleSignal, TradeDirection direction, Confidence confidence)
{
var signal = new Signal(MiscExtensions.ParseEnum<Ticker>(candleSignal.Ticker), direction, confidence, candleSignal, candleSignal.Date,
candleSignal.Exchange, timeframe, Type, SignalType);
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);
@@ -101,4 +103,4 @@ public class SuperTrendStrategy : Strategy
public decimal? LowerBand { get; internal set; }
public decimal? UpperBand { get; internal set; }
}
}
}

View File

@@ -7,8 +7,8 @@ namespace Managing.Domain.Strategies
{
public class ThreeWhiteSoldiersStrategy : Strategy
{
public ThreeWhiteSoldiersStrategy(string name, Timeframe timeframe, int period)
: base(name, timeframe, StrategyType.ThreeWhiteSoldiers)
public ThreeWhiteSoldiersStrategy(string name, int period)
: base(name, StrategyType.ThreeWhiteSoldiers)
{
Period = period;
}