* Add synthApi * Put confidence for Synth proba * Update the code * Update readme * Fix bootstraping * fix github build * Update the endpoints for scenario * Add scenario and update backtest modal * Update bot modal * Update interfaces for synth * add synth to backtest * Add Kelly criterion and better signal * Update signal confidence * update doc * save leaderboard and prediction * Update nswag to generate ApiClient in the correct path * Unify the trading modal * Save miner and prediction * Update messaging and block new signal until position not close when flipping off * Rename strategies to indicators * Update doc * Update chart + add signal name * Fix signal direction * Update docker webui * remove crypto npm * Clean
129 lines
4.1 KiB
C#
129 lines
4.1 KiB
C#
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 ChandelierExitIndicator : Indicator
|
|
{
|
|
public List<Signal> Signals { get; set; }
|
|
|
|
public ChandelierExitIndicator(string name, int period, double multiplier) : base(name,
|
|
IndicatorType.ChandelierExit)
|
|
{
|
|
Signals = new List<Signal>();
|
|
Period = period;
|
|
Multiplier = multiplier;
|
|
MinimumHistory = 1 + Period.Value;
|
|
}
|
|
|
|
public override List<Signal> Run()
|
|
{
|
|
if (Candles.Count <= MinimumHistory)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
GetSignals(ChandelierType.Long);
|
|
GetSignals(ChandelierType.Short);
|
|
|
|
return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList();
|
|
}
|
|
catch (RuleException)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public override IndicatorsResultBase GetIndicatorValues()
|
|
{
|
|
return new IndicatorsResultBase()
|
|
{
|
|
ChandelierLong = Candles.GetChandelier(Period.Value, Multiplier.Value, ChandelierType.Long).ToList(),
|
|
ChandelierShort = Candles.GetChandelier(Period.Value, Multiplier.Value, ChandelierType.Short).ToList()
|
|
};
|
|
}
|
|
|
|
private void GetSignals(ChandelierType chandelierType)
|
|
{
|
|
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 &&
|
|
previousCandle.Close > previousCandle.ChandelierExit &&
|
|
currentCandle.Close < previousCandle.Open &&
|
|
chandelierType == ChandelierType.Short)
|
|
{
|
|
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
|
|
}
|
|
|
|
// Long
|
|
if (currentCandle.Close > previousCandle.ChandelierExit &&
|
|
previousCandle.Close < previousCandle.ChandelierExit &&
|
|
currentCandle.Close > currentCandle.Open &&
|
|
chandelierType == ChandelierType.Long)
|
|
{
|
|
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
|
|
}
|
|
|
|
previousCandle = currentCandle;
|
|
}
|
|
}
|
|
|
|
private List<CandleChandelier> MapChandelierToCandle(List<ChandelierResult> superTrend, IEnumerable<Candle> candles)
|
|
{
|
|
var superTrends = new List<CandleChandelier>();
|
|
foreach (var candle in candles)
|
|
{
|
|
var currentChandelier = superTrend.Find(candle.Date);
|
|
if (currentChandelier != null)
|
|
{
|
|
superTrends.Add(new CandleChandelier()
|
|
{
|
|
Close = candle.Close,
|
|
Open = candle.Open,
|
|
Date = candle.Date,
|
|
Ticker = candle.Ticker,
|
|
Exchange = candle.Exchange,
|
|
ChandelierExit = (decimal)currentChandelier.ChandelierExit.Value,
|
|
});
|
|
}
|
|
}
|
|
|
|
return superTrends;
|
|
}
|
|
|
|
private void AddSignal(CandleChandelier candleSignal, TradeDirection direction,
|
|
Confidence confidence)
|
|
{
|
|
var signal = new Signal(
|
|
MiscExtensions.ParseEnum<Ticker>(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 CandleChandelier : Candle
|
|
{
|
|
public decimal ChandelierExit { get; internal set; }
|
|
}
|
|
} |