Trading bot grain (#33)
* Trading bot Grain * Fix a bit more of the trading bot * Advance on the tradingbot grain * Fix build * Fix db script * Fix user login * Fix a bit backtest * Fix cooldown and backtest * start fixing bot start * Fix startup * Setup local db * Fix build and update candles and scenario * Add bot registry * Add reminder * Updateing the grains * fix bootstraping * Save stats on tick * Save bot data every tick * Fix serialization * fix save bot stats * Fix get candles * use dict instead of list for position * Switch hashset to dict * Fix a bit * Fix bot launch and bot view * add migrations * Remove the tolist * Add agent grain * Save agent summary * clean * Add save bot * Update get bots * Add get bots * Fix stop/restart * fix Update config * Update scanner table on new backtest saved * Fix backtestRowDetails.tsx * Fix agentIndex * Update agentIndex * Fix more things * Update user cache * Fix * Fix account load/start/restart/run
This commit is contained in:
@@ -30,7 +30,7 @@ public class LightScenario
|
||||
{
|
||||
var lightScenario = new LightScenario(scenario.Name, scenario.LoopbackPeriod)
|
||||
{
|
||||
Indicators = scenario.Indicators?.Select(LightIndicator.FromIndicator).ToList() ??
|
||||
Indicators = scenario.Indicators?.Select(LightIndicator.BaseToLight).ToList() ??
|
||||
new List<LightIndicator>()
|
||||
};
|
||||
return lightScenario;
|
||||
@@ -43,15 +43,8 @@ public class LightScenario
|
||||
{
|
||||
var scenario = new Scenario(Name, LoopbackPeriod)
|
||||
{
|
||||
Indicators = Indicators?.Select(li => li.ToIndicator()).ToList() ?? new List<Indicator>()
|
||||
Indicators = Indicators?.Select(li => li.LightToBase()).ToList()
|
||||
};
|
||||
return scenario;
|
||||
}
|
||||
|
||||
public void AddIndicator(LightIndicator indicator)
|
||||
{
|
||||
if (Indicators == null)
|
||||
Indicators = new List<LightIndicator>();
|
||||
Indicators.Add(indicator);
|
||||
}
|
||||
}
|
||||
@@ -10,23 +10,19 @@ namespace Managing.Domain.Scenarios
|
||||
public Scenario(string name, int? loopbackPeriod = 1)
|
||||
{
|
||||
Name = name;
|
||||
Indicators = new List<Indicator>();
|
||||
Indicators = new List<IndicatorBase>();
|
||||
LoopbackPeriod = loopbackPeriod;
|
||||
}
|
||||
|
||||
[Id(0)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Id(1)]
|
||||
public List<Indicator> Indicators { get; set; }
|
||||
|
||||
[Id(2)]
|
||||
public int? LoopbackPeriod { get; set; }
|
||||
|
||||
[Id(3)]
|
||||
public User User { get; set; }
|
||||
[Id(0)] public string Name { get; set; }
|
||||
|
||||
public void AddIndicator(Indicator indicator)
|
||||
[Id(1)] public List<IndicatorBase> Indicators { get; set; }
|
||||
|
||||
[Id(2)] public int? LoopbackPeriod { get; set; }
|
||||
|
||||
[Id(3)] public User User { get; set; }
|
||||
|
||||
public void AddIndicator(IndicatorBase indicator)
|
||||
{
|
||||
Indicators.Add(indicator);
|
||||
}
|
||||
|
||||
@@ -1,52 +1,97 @@
|
||||
using Managing.Core.FixedSizedQueue;
|
||||
using Managing.Domain.Candles;
|
||||
using Managing.Domain.Strategies;
|
||||
using Managing.Domain.Strategies;
|
||||
using Managing.Domain.Strategies.Context;
|
||||
using Managing.Domain.Strategies.Signals;
|
||||
using Managing.Domain.Strategies.Trends;
|
||||
using Newtonsoft.Json;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Domain.Scenarios;
|
||||
|
||||
public static class ScenarioHelpers
|
||||
{
|
||||
public static IEnumerable<IIndicator> GetIndicatorsFromScenario(Scenario scenario)
|
||||
/// <summary>
|
||||
/// Compares two lists of indicators and returns a list of changes (added, removed, modified).
|
||||
/// </summary>
|
||||
/// <param name="oldIndicators">The previous list of indicators</param>
|
||||
/// <param name="newIndicators">The new list of indicators</param>
|
||||
/// <returns>A list of change descriptions</returns>
|
||||
public static List<string> CompareIndicators(List<LightIndicator> oldIndicators, List<LightIndicator> newIndicators)
|
||||
{
|
||||
var strategies = new List<IIndicator>();
|
||||
foreach (var strategy in scenario.Indicators)
|
||||
var changes = new List<string>();
|
||||
|
||||
// Create dictionaries for easier comparison using Type as key
|
||||
var oldIndicatorDict = oldIndicators.ToDictionary(i => i.Type, i => i);
|
||||
var newIndicatorDict = newIndicators.ToDictionary(i => i.Type, i => i);
|
||||
|
||||
// Find removed indicators
|
||||
var removedTypes = oldIndicatorDict.Keys.Except(newIndicatorDict.Keys);
|
||||
foreach (var removedType in removedTypes)
|
||||
{
|
||||
var result = BuildIndicator(strategy);
|
||||
strategies.Add(result);
|
||||
var indicator = oldIndicatorDict[removedType];
|
||||
changes.Add($"➖ **Removed Indicator:** {removedType} ({indicator.GetType().Name})");
|
||||
}
|
||||
|
||||
return strategies;
|
||||
// Find added indicators
|
||||
var addedTypes = newIndicatorDict.Keys.Except(oldIndicatorDict.Keys);
|
||||
foreach (var addedType in addedTypes)
|
||||
{
|
||||
var indicator = newIndicatorDict[addedType];
|
||||
changes.Add($"➕ **Added Indicator:** {addedType} ({indicator.GetType().Name})");
|
||||
}
|
||||
|
||||
// Find modified indicators (same type but potentially different configuration)
|
||||
var commonTypes = oldIndicatorDict.Keys.Intersect(newIndicatorDict.Keys);
|
||||
foreach (var commonType in commonTypes)
|
||||
{
|
||||
var oldIndicator = oldIndicatorDict[commonType];
|
||||
var newIndicator = newIndicatorDict[commonType];
|
||||
|
||||
// Compare indicators by serializing them (simple way to detect configuration changes)
|
||||
var oldSerialized = JsonConvert.SerializeObject(oldIndicator, Formatting.None);
|
||||
var newSerialized = JsonConvert.SerializeObject(newIndicator, Formatting.None);
|
||||
|
||||
if (oldSerialized != newSerialized)
|
||||
{
|
||||
changes.Add($"🔄 **Modified Indicator:** {commonType} ({newIndicator.GetType().Name})");
|
||||
}
|
||||
}
|
||||
|
||||
// Add summary if there are changes
|
||||
if (changes.Any())
|
||||
{
|
||||
var summary =
|
||||
$"📊 **Indicator Changes:** {addedTypes.Count()} added, {removedTypes.Count()} removed, {commonTypes.Count(c => JsonConvert.SerializeObject(oldIndicatorDict[c]) != JsonConvert.SerializeObject(newIndicatorDict[c]))} modified";
|
||||
changes.Insert(0, summary);
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public static IIndicator BuildIndicator(Indicator indicator, int size = 600)
|
||||
public static IIndicator BuildIndicator(LightIndicator indicator)
|
||||
{
|
||||
IIndicator result = indicator.Type switch
|
||||
{
|
||||
IndicatorType.StDev => new StDevContext(indicator.Name, indicator.Period.Value),
|
||||
IndicatorType.RsiDivergence => new RsiDivergenceIndicator(indicator.Name,
|
||||
IndicatorType.RsiDivergence => new RsiDivergenceIndicatorBase(indicator.Name,
|
||||
indicator.Period.Value),
|
||||
IndicatorType.RsiDivergenceConfirm => new RsiDivergenceConfirmIndicator(indicator.Name,
|
||||
IndicatorType.RsiDivergenceConfirm => new RsiDivergenceConfirmIndicatorBase(indicator.Name,
|
||||
indicator.Period.Value),
|
||||
IndicatorType.MacdCross => new MacdCrossIndicator(indicator.Name,
|
||||
IndicatorType.MacdCross => new MacdCrossIndicatorBase(indicator.Name,
|
||||
indicator.FastPeriods.Value, indicator.SlowPeriods.Value, indicator.SignalPeriods.Value),
|
||||
IndicatorType.EmaCross => new EmaCrossIndicator(indicator.Name, indicator.Period.Value),
|
||||
IndicatorType.DualEmaCross => new DualEmaCrossIndicator(indicator.Name,
|
||||
IndicatorType.EmaCross => new EmaCrossIndicatorBase(indicator.Name, indicator.Period.Value),
|
||||
IndicatorType.DualEmaCross => new DualEmaCrossIndicatorBase(indicator.Name,
|
||||
indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
|
||||
IndicatorType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersIndicator(indicator.Name,
|
||||
IndicatorType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersIndicatorBase(indicator.Name,
|
||||
indicator.Period.Value),
|
||||
IndicatorType.SuperTrend => new SuperTrendIndicator(indicator.Name,
|
||||
IndicatorType.SuperTrend => new SuperTrendIndicatorBase(indicator.Name,
|
||||
indicator.Period.Value, indicator.Multiplier.Value),
|
||||
IndicatorType.ChandelierExit => new ChandelierExitIndicator(indicator.Name,
|
||||
IndicatorType.ChandelierExit => new ChandelierExitIndicatorBase(indicator.Name,
|
||||
indicator.Period.Value, indicator.Multiplier.Value),
|
||||
IndicatorType.EmaTrend => new EmaTrendIndicator(indicator.Name, indicator.Period.Value),
|
||||
IndicatorType.StochRsiTrend => new StochRsiTrendIndicator(indicator.Name,
|
||||
IndicatorType.EmaTrend => new EmaTrendIndicatorBase(indicator.Name, indicator.Period.Value),
|
||||
IndicatorType.StochRsiTrend => new StochRsiTrendIndicatorBase(indicator.Name,
|
||||
indicator.Period.Value, indicator.StochPeriods.Value, indicator.SignalPeriods.Value,
|
||||
indicator.SmoothPeriods.Value),
|
||||
IndicatorType.Stc => new StcIndicator(indicator.Name, indicator.CyclePeriods.Value,
|
||||
IndicatorType.Stc => new StcIndicatorBase(indicator.Name, indicator.CyclePeriods.Value,
|
||||
indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
|
||||
IndicatorType.LaggingStc => new LaggingSTC(indicator.Name, indicator.CyclePeriods.Value,
|
||||
indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
|
||||
@@ -55,11 +100,10 @@ public static class ScenarioHelpers
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
result.Candles = new FixedSizeQueue<Candle>(size);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Indicator BuildIndicator(
|
||||
public static IIndicator BuildIndicator(
|
||||
IndicatorType type,
|
||||
string name,
|
||||
int? period = null,
|
||||
@@ -71,7 +115,7 @@ public static class ScenarioHelpers
|
||||
int? smoothPeriods = null,
|
||||
int? cyclePeriods = null)
|
||||
{
|
||||
var indicator = new Indicator(name, type);
|
||||
IIndicator indicator = null;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user