Fix graph

This commit is contained in:
2025-11-25 11:03:52 +07:00
parent 6376e13b07
commit 4b5c1c5ce0
6 changed files with 140 additions and 66 deletions

View File

@@ -17,7 +17,6 @@ using Managing.Domain.Trades;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using static Managing.Common.Enums;
using DailySnapshot = Managing.Api.Models.Responses.DailySnapshot;
@@ -831,9 +830,18 @@ public class DataController : ControllerBase
SlowPeriods = indicatorRequest.SlowPeriods,
SignalPeriods = indicatorRequest.SignalPeriods,
Multiplier = indicatorRequest.Multiplier,
StDev = indicatorRequest.StDev,
SmoothPeriods = indicatorRequest.SmoothPeriods,
StochPeriods = indicatorRequest.StochPeriods,
CyclePeriods = indicatorRequest.CyclePeriods
CyclePeriods = indicatorRequest.CyclePeriods,
KFactor = indicatorRequest.KFactor,
DFactor = indicatorRequest.DFactor,
TenkanPeriods = indicatorRequest.TenkanPeriods,
KijunPeriods = indicatorRequest.KijunPeriods,
SenkouBPeriods = indicatorRequest.SenkouBPeriods,
OffsetPeriods = indicatorRequest.OffsetPeriods,
SenkouOffset = indicatorRequest.SenkouOffset,
ChikouOffset = indicatorRequest.ChikouOffset
};
scenario.AddIndicator(indicator);

View File

@@ -71,40 +71,40 @@ public static class ScenarioHelpers
{
IIndicator result = indicator.Type switch
{
IndicatorType.StDev => new StDevContext(indicator.Name, indicator.Period.Value),
IndicatorType.StDev => new StDevContext(indicator.Name, indicator.Period ?? 14),
IndicatorType.RsiDivergence => new RsiDivergenceIndicatorBase(indicator.Name,
indicator.Period.Value),
indicator.Period ?? 14),
IndicatorType.RsiDivergenceConfirm => new RsiDivergenceConfirmIndicatorBase(indicator.Name,
indicator.Period.Value),
indicator.Period ?? 14),
IndicatorType.MacdCross => new MacdCrossIndicatorBase(indicator.Name,
indicator.FastPeriods.Value, indicator.SlowPeriods.Value, indicator.SignalPeriods.Value),
IndicatorType.EmaCross => new EmaCrossIndicatorBase(indicator.Name, indicator.Period.Value),
indicator.FastPeriods ?? 12, indicator.SlowPeriods ?? 26, indicator.SignalPeriods ?? 9),
IndicatorType.EmaCross => new EmaCrossIndicatorBase(indicator.Name, indicator.Period ?? 14),
IndicatorType.DualEmaCross => new DualEmaCrossIndicatorBase(indicator.Name,
indicator.FastPeriods.Value, indicator.SlowPeriods.Value),
indicator.FastPeriods ?? 12, indicator.SlowPeriods ?? 26),
IndicatorType.ThreeWhiteSoldiers => new ThreeWhiteSoldiersIndicatorBase(indicator.Name,
indicator.Period.Value),
indicator.Period ?? 14),
IndicatorType.SuperTrend => new SuperTrendIndicatorBase(indicator.Name,
indicator.Period.Value, indicator.Multiplier.Value),
indicator.Period ?? 14, indicator.Multiplier ?? 3.0),
IndicatorType.ChandelierExit => new ChandelierExitIndicatorBase(indicator.Name,
indicator.Period.Value, indicator.Multiplier.Value),
IndicatorType.EmaTrend => new EmaTrendIndicatorBase(indicator.Name, indicator.Period.Value),
indicator.Period ?? 14, indicator.Multiplier ?? 3.0),
IndicatorType.EmaTrend => new EmaTrendIndicatorBase(indicator.Name, indicator.Period ?? 14),
IndicatorType.StochRsiTrend => new StochRsiTrendIndicatorBase(indicator.Name,
indicator.Period.Value, indicator.StochPeriods.Value, indicator.SignalPeriods.Value,
indicator.SmoothPeriods.Value),
indicator.Period ?? 14, indicator.StochPeriods ?? 14, indicator.SignalPeriods ?? 9,
indicator.SmoothPeriods ?? 3),
IndicatorType.StochasticCross => new StochasticCrossIndicator(indicator.Name,
indicator.StochPeriods.Value, indicator.SignalPeriods.Value, indicator.SmoothPeriods.Value,
indicator.StochPeriods ?? 14, indicator.SignalPeriods ?? 3, indicator.SmoothPeriods ?? 3,
indicator.KFactor ?? 3.0, indicator.DFactor ?? 2.0),
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),
IndicatorType.Stc => new StcIndicatorBase(indicator.Name, indicator.CyclePeriods ?? 10,
indicator.FastPeriods ?? 12, indicator.SlowPeriods ?? 26),
IndicatorType.LaggingStc => new LaggingSTC(indicator.Name, indicator.CyclePeriods ?? 10,
indicator.FastPeriods ?? 12, indicator.SlowPeriods ?? 26),
IndicatorType.SuperTrendCrossEma => new SuperTrendCrossEma(indicator.Name,
indicator.Period.Value, indicator.Multiplier.Value),
indicator.Period ?? 14, indicator.Multiplier ?? 3.0),
IndicatorType.BollingerBandsPercentBMomentumBreakout => new BollingerBandsPercentBMomentumBreakout(
indicator.Name,
indicator.Period.Value, indicator.StDev.Value),
indicator.Period ?? 20, indicator.StDev ?? 2.0),
IndicatorType.BollingerBandsVolatilityProtection => new BollingerBandsVolatilityProtection(indicator.Name,
indicator.Period.Value, indicator.StDev.Value),
indicator.Period ?? 20, indicator.StDev ?? 2.0),
IndicatorType.IchimokuKumoTrend => new IchimokuKumoTrend(indicator.Name,
indicator.TenkanPeriods ?? 9,
indicator.KijunPeriods ?? 26,

View File

@@ -937,8 +937,9 @@ public static class TradingBox
var buildedIndicator = ScenarioHelpers.BuildIndicator(ScenarioHelpers.BaseToLight(indicator));
indicatorsValues[indicator.Type] = buildedIndicator.GetIndicatorValues(candles);
}
catch (Exception)
catch (Exception ex)
{
throw;
// Removed logging for performance in static method
// Consider adding logging back if error handling is needed
}

View File

@@ -66,9 +66,18 @@ const BacktestRowDetails: React.FC<IBacktestRowDetailsProps> = ({
slowPeriods: indicator.slowPeriods,
signalPeriods: indicator.signalPeriods,
multiplier: indicator.multiplier,
stDev: indicator.stDev,
smoothPeriods: indicator.smoothPeriods,
stochPeriods: indicator.stochPeriods,
cyclePeriods: indicator.cyclePeriods
cyclePeriods: indicator.cyclePeriods,
kFactor: indicator.kFactor,
dFactor: indicator.dFactor,
tenkanPeriods: indicator.tenkanPeriods,
kijunPeriods: indicator.kijunPeriods,
senkouBPeriods: indicator.senkouBPeriods,
offsetPeriods: indicator.offsetPeriods,
senkouOffset: indicator.senkouOffset,
chikouOffset: indicator.chikouOffset
})) || [],
loopbackPeriod: backtest.config.scenario.loopbackPeriod
} : undefined
@@ -76,7 +85,6 @@ const BacktestRowDetails: React.FC<IBacktestRowDetailsProps> = ({
return await dataClient.data_GetCandlesWithIndicators(request);
},
enabled: !backtest.candles || backtest.candles.length === 0, // Only run query if no candles exist
staleTime: 5 * 60 * 1000, // 5 minutes
gcTime: 10 * 60 * 1000, // 10 minutes (formerly cacheTime)
});

View File

@@ -565,47 +565,6 @@ const TradeChart = ({
lowerBandSeries.setData(lowerBandData)
}
// Display Bollinger Bands on price chart for Volatility Protection
if (indicatorsValues?.BollingerBandsVolatilityProtection != null) {
const upperBandSeries = chart.current.addLineSeries({
color: '#FF6B6B', // Lighter red for volatility protection bands
lineWidth: 1,
priceLineVisible: false,
priceLineWidth: 1,
title: 'Volatility Protection Upper Band',
pane: 0,
lineStyle: LineStyle.Dotted,
})
const upperBandData = indicatorsValues.BollingerBandsVolatilityProtection.bollingerBands?.map((w) => {
return {
time: moment(w.date).unix(),
value: w.upperBand,
}
})
// @ts-ignore
upperBandSeries.setData(upperBandData)
const lowerBandSeries = chart.current.addLineSeries({
color: '#4ECDC4', // Teal for volatility protection bands
lineWidth: 1,
priceLineVisible: false,
priceLineWidth: 1,
title: 'Volatility Protection Lower Band',
pane: 0,
lineStyle: LineStyle.Dotted,
})
const lowerBandData = indicatorsValues.BollingerBandsVolatilityProtection.bollingerBands?.map((w) => {
return {
time: moment(w.date).unix(),
value: w.lowerBand,
}
})
// @ts-ignore
lowerBandSeries.setData(lowerBandData)
}
if (markers.length > 0) {
series1.current.setMarkers(markers)
}
@@ -674,6 +633,95 @@ const TradeChart = ({
paneCount++
}
// Display Bollinger Bands Volatility Protection Width on separate pane
if (indicatorsValues?.BollingerBandsVolatilityProtection != null) {
const volatilityWidthSeries = chart.current.addLineSeries({
color: '#8B5CF6', // Purple for volatility width
lineWidth: 2,
priceLineVisible: true,
priceLineWidth: 1,
title: 'Volatility Width (BB %)',
pane: paneCount,
priceFormat: {
minMove: 0.001,
precision: 3,
type: 'price',
},
})
const volatilityWidthData = indicatorsValues.BollingerBandsVolatilityProtection.bollingerBands?.map((w) => {
return {
time: moment(w.date).unix(),
value: w.width,
}
})
// @ts-ignore
volatilityWidthSeries.setData(volatilityWidthData)
// Add confidence range lines (0.02 - 0.10)
const confidenceMinLine = chart.current.addLineSeries({
color: '#16A34A', // Green for confidence range minimum
lineWidth: 1,
priceLineVisible: true,
priceLineWidth: 1,
title: 'Conf Min (2%)',
pane: paneCount,
lineStyle: LineStyle.Dashed,
priceFormat: {
minMove: 0.001,
precision: 3,
type: 'price',
},
})
const confidenceMaxLine = chart.current.addLineSeries({
color: '#16A34A', // Green for confidence range maximum
lineWidth: 1,
priceLineVisible: true,
priceLineWidth: 1,
title: 'Conf Max (10%)',
pane: paneCount,
lineStyle: LineStyle.Dashed,
priceFormat: {
minMove: 0.001,
precision: 3,
type: 'price',
},
})
// Create horizontal lines for confidence range
const bollingerBands = indicatorsValues.BollingerBandsVolatilityProtection.bollingerBands
if (bollingerBands && bollingerBands.length > 0) {
const confidenceMinData = [
{
time: moment(bollingerBands[0].date).unix(),
value: 0.02, // Confidence minimum threshold
},
{
time: moment(bollingerBands[bollingerBands.length - 1].date).unix(),
value: 0.02, // Confidence minimum threshold
}
]
// @ts-ignore
confidenceMinLine.setData(confidenceMinData)
const confidenceMaxData = [
{
time: moment(bollingerBands[0].date).unix(),
value: 0.10, // Confidence maximum threshold
},
{
time: moment(bollingerBands[bollingerBands.length - 1].date).unix(),
value: 0.10, // Confidence maximum threshold
}
]
// @ts-ignore
confidenceMaxLine.setData(confidenceMaxData)
}
paneCount++
}
if (indicatorsValues?.LaggingStc != null) {
const laggingStcSeries = chart.current.addBaselineSeries({
pane: paneCount,