diff --git a/docs/StrategyCombo-README.md b/docs/StrategyCombo-README.md new file mode 100644 index 0000000..491c0a1 --- /dev/null +++ b/docs/StrategyCombo-README.md @@ -0,0 +1,177 @@ +# Strategy Combination System + +## Overview + +The improved `TradingBox` strategy combination system provides sophisticated logic for combining multiple trading strategies with different purposes and behaviors. The system is designed around three distinct strategy types, each serving a specific role in the trading decision process. + +## Strategy Types + +### 1. Signal Strategies (`SignalType.Signal`) +- **Purpose**: Generate rare, precise entry signals when specific conditions are met +- **Behavior**: Sparse signal generation - only fire when opportunity is detected +- **Examples**: RSI Divergence, MACD Cross, Chandelier Exit +- **Weight**: High priority in final decision + +### 2. Trend Strategies (`SignalType.Trend`) +- **Purpose**: Identify overall market direction on every candlestick +- **Behavior**: Continuous output (Long/Short/Neutral for each candle) +- **Examples**: EMA Trend, SuperTrend, Moving Average Cross +- **Weight**: Supporting role, validates signal direction + +### 3. Context Strategies (`SignalType.Context`) +- **Purpose**: Provide market context to prevent trades in unfavorable conditions +- **Behavior**: Act as filters/guards (allow/block trades) +- **Examples**: Volatility filters, Volume filters, Time-based restrictions +- **Weight**: Veto power - can block otherwise valid signals + +## Combination Logic + +### Basic Flow +1. **Context Validation**: All context strategies must allow the trade (configurable) +2. **Signal Analysis**: Evaluate entry signals using majority voting +3. **Trend Analysis**: Determine overall market direction +4. **Final Decision**: Combine signal and trend with confidence scoring + +### Decision Matrix + +| Signal Direction | Trend Direction | Result | Confidence | +|-----------------|----------------|---------|------------| +| Long/Short | Same | Execute | High | +| Long/Short | Neutral/None | Execute | Medium | +| Long/Short | Opposite | Execute* | Low | +| None | Long/Short | Execute | Medium/Low | +| None | None | No Trade | N/A | + +*_Depends on `AllowSignalTrendOverride` configuration_ + +## Configuration Options + +The system uses `StrategyComboConfig` to customize behavior: + +```csharp +var config = new StrategyComboConfig +{ + // Trend agreement thresholds + TrendStrongAgreementThreshold = 0.66m, // 66% for strong trend + + // Signal agreement thresholds + SignalAgreementThreshold = 0.5m, // 50% majority for signals + + // Override behavior + AllowSignalTrendOverride = true, // Allow signals to override trends + + // Quality filters + MinimumConfidence = Confidence.Low, // Minimum confidence to trade + MinimumContextConfidence = Confidence.Medium, // Minimum context quality required + + // Defaults + DefaultExchange = TradingExchanges.Binance +}; +``` + +### Context Strategy Behavior + +Context strategies now work with **confidence levels** rather than allow/block decisions: + +- **High Confidence**: Ideal market conditions (e.g., low volatility) +- **Medium Confidence**: Normal market conditions +- **Low Confidence**: Elevated risk conditions (trade with caution) +- **No Confidence**: Poor conditions (blocks trading) + +All context strategies must meet the `MinimumContextConfidence` threshold for trades to proceed. + +## Usage Examples + +### Basic Usage (Default Configuration) +```csharp +var signal = TradingBox.GetSignal(candles, strategies, previousSignals); +``` + +### Advanced Usage (Custom Configuration) +```csharp +var config = new StrategyComboConfig +{ + TrendStrongAgreementThreshold = 0.75m, // Require 75% trend agreement + MinimumConfidence = Confidence.Medium, // Only trade medium+ confidence + MinimumContextConfidence = Confidence.High, // Only trade in ideal conditions + AllowSignalTrendOverride = false // Don't allow trend conflicts +}; + +var signal = TradingBox.GetSignal(candles, strategies, previousSignals, config); +``` + +### Typical Strategy Combinations + +#### Conservative Setup +- 1 Signal Strategy (RSI Divergence) +- 2 Trend Strategies (EMA Trend, SuperTrend) +- 1 Context Strategy (Volatility Filter) + +#### Aggressive Setup +- 2 Signal Strategies (MACD Cross, Chandelier Exit) +- 1 Trend Strategy (EMA Trend) +- No Context Strategies + +#### Scalping Setup +- 3 Signal Strategies (Quick signals) +- 1 Trend Strategy (Short-term trend) +- 2 Context Strategies (Volume + Time filters) + +## Key Improvements + +### 1. **Flexible Requirements** +- No longer requires ALL strategies to produce signals +- Different logic for different strategy types +- Configurable thresholds and behavior + +### 2. **Intelligent Voting** +- Majority voting for signals and trends +- Weighted decisions based on strategy type +- Handles neutral/conflicting signals gracefully + +### 3. **Confidence Scoring** +- Dynamic confidence based on agreement levels +- Considers signal-trend alignment +- Configurable minimum confidence thresholds + +### 4. **Context Awareness** +- Context strategies provide market condition quality through confidence levels +- Configurable minimum context confidence thresholds +- Simplified logic: all context strategies must meet minimum confidence +- No more complex unanimous vs. majority requirements + +### 5. **Trend Reversal Support** +- Signal strategies can override trend direction +- Useful for catching trend reversals +- Configurable override behavior + +## Best Practices + +### Strategy Selection +1. **Use 1-2 Signal strategies** for entry precision +2. **Use 1-3 Trend strategies** for direction confirmation +3. **Use 0-2 Context strategies** for risk management + +### Configuration Tuning +1. **Start with defaults** and adjust based on backtesting +2. **Higher thresholds** = fewer but higher quality signals +3. **Lower thresholds** = more signals but potentially more noise + +### Testing Recommendations +1. **Backtest different configurations** on historical data +2. **Monitor confidence distributions** in live trading +3. **Adjust thresholds** based on performance metrics + +## Migration from Old System + +The new system is backward compatible: +- Existing calls to `GetSignal()` work unchanged +- Old unanimous agreement logic is still available via configuration +- New overloads provide additional control when needed + +## Performance Considerations + +- Strategy evaluation is optimized for efficiency +- Signal caching prevents duplicate calculations +- Configurable quality filters reduce unnecessary trades +- Separate validation logic for different strategy types \ No newline at end of file diff --git a/docs/VolatilityControlledTradingScenario.md b/docs/VolatilityControlledTradingScenario.md new file mode 100644 index 0000000..6a613ad --- /dev/null +++ b/docs/VolatilityControlledTradingScenario.md @@ -0,0 +1,215 @@ +# Volatility-Controlled Trading Scenario + +## Overview + +This scenario combines the **STCStrategy** (Signal) with the **StDevContext** (Context) to create a sophisticated trading system that identifies trend reversals while respecting market volatility conditions. + +## Strategy Components + +### STCStrategy (Signal Type) +- **Purpose**: Detects trend reversals using Schaff Trend Cycle indicator +- **Signals**: + - Long when STC crosses above 25 (oversold recovery) + - Short when STC crosses below 75 (overbought decline) +- **Confidence**: Medium for all signals + +### StDevContext (Context Type) +- **Purpose**: Evaluates market volatility to determine trading conditions +- **Z-Score Ranges**: + - `|Z| ≤ 0.5`: **High Confidence** - Very stable conditions, ideal for trading + - `0.5 < |Z| ≤ 1.0`: **Medium Confidence** - Normal volatility, good for trading + - `1.0 < |Z| ≤ 1.5`: **Low Confidence** - Elevated volatility, trade with caution + - `|Z| > 1.5`: **No Confidence** - High volatility, avoid trading + +## Implementation + +### Basic Setup + +```csharp +// Initialize strategies +var stcStrategy = new STCStrategy( + name: "STC Reversal", + cyclePeriods: 10, // Cycle length for STC calculation + fastPeriods: 12, // Fast EMA period + slowPeriods: 26 // Slow EMA period +); + +var volatilityFilter = new StDevContext( + name: "Volatility Filter", + period: 20 // Period for standard deviation calculation +); + +// Set up strategies +var strategies = new HashSet { stcStrategy, volatilityFilter }; +``` + +### Configuration Options + +```csharp +// Conservative configuration (safer trading) +var conservativeConfig = new StrategyComboConfig +{ + MinimumContextConfidence = Confidence.High, // Only trade in very stable conditions + MinimumConfidence = Confidence.Medium, // Only trade medium+ confidence signals + AllowSignalTrendOverride = true // Allow reversal signals +}; + +// Aggressive configuration (more trading opportunities) +var aggressiveConfig = new StrategyComboConfig +{ + MinimumContextConfidence = Confidence.Low, // Trade in elevated volatility + MinimumConfidence = Confidence.Low, // Accept lower confidence signals + AllowSignalTrendOverride = true +}; + +// Balanced configuration (recommended starting point) +var balancedConfig = new StrategyComboConfig +{ + MinimumContextConfidence = Confidence.Medium, // Require normal volatility conditions + MinimumConfidence = Confidence.Medium, // Standard confidence requirements + AllowSignalTrendOverride = true // Allow trend reversals +}; +``` + +### Trading Logic + +```csharp +public Signal GetTradingSignal(HashSet candles, StrategyComboConfig config) +{ + // Update strategies with latest candle data + foreach (var strategy in strategies) + { + strategy.UpdateCandles(candles); + } + + // Get combined signal + var signal = TradingBox.GetSignal( + candles, + strategies, + new HashSet(), // Previous signals + config, + loopbackPeriod: 1 // Check only latest candle + ); + + return signal; +} +``` + +### Complete Example + +```csharp +public class VolatilityControlledTradingBot +{ + private readonly STCStrategy _stcStrategy; + private readonly StDevContext _volatilityFilter; + private readonly StrategyComboConfig _config; + + public VolatilityControlledTradingBot() + { + _stcStrategy = new STCStrategy("STC Reversal", 10, 12, 26); + _volatilityFilter = new StDevContext("Volatility Filter", 20); + + _config = new StrategyComboConfig + { + MinimumContextConfidence = Confidence.Medium, + MinimumConfidence = Confidence.Medium, + AllowSignalTrendOverride = true + }; + } + + public async Task AnalyzeMarket(List candles) + { + // Ensure we have enough data + if (candles.Count < 50) // Need sufficient history for both strategies + return null; + + var strategies = new HashSet { _stcStrategy, _volatilityFilter }; + + // Update strategies + foreach (var strategy in strategies) + { + strategy.UpdateCandles(candles.ToHashSet()); + } + + // Get trading signal + var signal = TradingBox.GetSignal( + candles.ToHashSet(), + strategies, + new HashSet(), + _config + ); + + // Log decision process + if (signal != null) + { + Console.WriteLine($"Trade Signal Generated:"); + Console.WriteLine($" Direction: {signal.Direction}"); + Console.WriteLine($" Confidence: {signal.Confidence}"); + Console.WriteLine($" Date: {signal.Date}"); + } + else + { + Console.WriteLine("No trade signal - conditions not met"); + } + + return signal; + } +} +``` + +## Loopback Period Recommendations + +### For this Scenario: +- **Loopback Period: 1-3 candles** + - STC reversals are typically captured immediately + - Volatility context is current market condition + - Short loopback prevents stale signals + +### Considerations: +- **Market Timeframe**: + - 5m-15m charts: Use loopback = 1 + - 1h-4h charts: Use loopback = 2-3 + - Daily charts: Use loopback = 1-2 + +## Expected Behavior + +### High Volatility Conditions (Z-Score > 1.5) +- StDevContext returns `Confidence.None` +- No trades executed regardless of STC signals +- Protects against whipsaw movements + +### Normal Volatility Conditions (|Z-Score| ≤ 1.0) +- StDevContext returns `Confidence.Medium` or `Confidence.High` +- STC signals are evaluated normally +- Trades executed when STC crosses thresholds + +### Low Volatility Conditions (|Z-Score| ≤ 0.5) +- StDevContext returns `Confidence.High` +- Ideal conditions for trend reversal trading +- Higher probability of successful STC signals + +## Performance Tuning + +### STC Parameters: +- **cyclePeriods**: 8-15 (shorter = more sensitive) +- **fastPeriods**: 9-15 (standard EMA settings) +- **slowPeriods**: 21-30 (standard EMA settings) + +### Volatility Parameters: +- **period**: 14-21 (standard volatility lookback) +- **Z-Score thresholds**: Adjust based on asset volatility characteristics + +## Risk Management + +1. **Position Sizing**: Reduce size when volatility confidence is low +2. **Stop Losses**: Tighter stops in high volatility periods +3. **Take Profits**: Quicker profit-taking when volatility increases +4. **Market Hours**: Consider time-based context strategies for optimal trading windows + +## Backtesting Recommendations + +1. Test different volatility thresholds on historical data +2. Evaluate performance across various market conditions +3. Monitor the distribution of context confidence levels +4. Analyze signal quality vs. market volatility correlation +5. Compare performance with and without volatility filtering \ No newline at end of file diff --git a/src/Managing.Domain/Shared/Helpers/TradingBox.cs b/src/Managing.Domain/Shared/Helpers/TradingBox.cs index 6301314..090fcb0 100644 --- a/src/Managing.Domain/Shared/Helpers/TradingBox.cs +++ b/src/Managing.Domain/Shared/Helpers/TradingBox.cs @@ -7,23 +7,82 @@ using static Managing.Common.Enums; namespace Managing.Domain.Shared.Helpers; +/// +/// Configuration for strategy combination logic +/// +public class StrategyComboConfig +{ + /// + /// Minimum percentage of trend strategies that must agree for strong trend (default: 66%) + /// + public decimal TrendStrongAgreementThreshold { get; set; } = 0.66m; + + /// + /// Minimum percentage of signal strategies that must agree (default: 50%) + /// + public decimal SignalAgreementThreshold { get; set; } = 0.5m; + + /// + /// Whether to allow signal strategies to override conflicting trends (default: true) + /// This is useful for trend reversal signals + /// + public bool AllowSignalTrendOverride { get; set; } = true; + + /// + /// Minimum confidence level to return a signal (default: Low) + /// + public Confidence MinimumConfidence { get; set; } = Confidence.Low; + + /// + /// Minimum confidence level required from context strategies (default: Medium) + /// Context strategies evaluate market conditions - higher requirements mean more conservative trading + /// + public Confidence MinimumContextConfidence { get; set; } = Confidence.Medium; + + /// + /// Default exchange to use when signals don't specify one + /// + public TradingExchanges DefaultExchange { get; set; } = TradingExchanges.Binance; +} + public static class TradingBox { + private static readonly StrategyComboConfig _defaultConfig = new(); + public static Signal GetSignal(HashSet newCandles, HashSet strategies, HashSet previousSignal, int? loopbackPeriod = 1) + { + return GetSignal(newCandles, strategies, previousSignal, _defaultConfig, loopbackPeriod); + } + + public static Signal GetSignal(HashSet newCandles, HashSet strategies, + HashSet previousSignal, StrategyComboConfig config, int? loopbackPeriod = 1) { var signalOnCandles = new HashSet(); var limitedCandles = newCandles.ToList().TakeLast(600).ToList(); + foreach (var strategy in strategies) { strategy.UpdateCandles(limitedCandles.ToHashSet()); var signals = strategy.Run(); - if (signals == null || signals.Count == 0) continue; + if (signals == null || signals.Count == 0) + { + // For trend and context strategies, lack of signal might be meaningful + // Signal strategies are expected to be sparse, so we continue + if (strategy.SignalType == SignalType.Signal) + { + continue; + } + + // For trend strategies, no signal might mean neutral trend + // For context strategies, no signal might mean no restrictions + // We'll let the ComputeSignals method handle these cases + continue; + } // Ensure limitedCandles is ordered chronologically var orderedCandles = limitedCandles.OrderBy(c => c.Date).ToList(); - var loopback = loopbackPeriod.HasValue && loopbackPeriod > 1 ? loopbackPeriod.Value : 1; var candleLoopback = orderedCandles.TakeLast(loopback).ToList(); @@ -49,63 +108,208 @@ public static class TradingBox } } - if (signalOnCandles.Count != strategies.Count) - return null; + // Remove the restrictive requirement that ALL strategies must produce signals + // Instead, let ComputeSignals handle the logic based on what we have + if (!signalOnCandles.Any()) + { + return null; // No signals from any strategy + } var data = newCandles.First(); return ComputeSignals(strategies, signalOnCandles, MiscExtensions.ParseEnum(data.Ticker), - data.Timeframe); + data.Timeframe, config); } public static Signal ComputeSignals(HashSet strategies, HashSet signalOnCandles, Ticker ticker, Timeframe timeframe) { - Signal signal = null; - if (strategies.Count > 1) - { - var trendSignal = signalOnCandles.Where(s => s.SignalType == SignalType.Trend).ToList(); - var signals = signalOnCandles.Where(s => s.SignalType == SignalType.Signal).ToList(); - var contextStrategiesCount = strategies.Count(s => s.SignalType == SignalType.Context); - var validContext = true; + return ComputeSignals(strategies, signalOnCandles, ticker, timeframe, _defaultConfig); + } - if (contextStrategiesCount > 0 && - signalOnCandles.Count(s => s.SignalType == SignalType.Context) != contextStrategiesCount) - { - validContext = false; - } - - if (signals.All(s => s.Direction == TradeDirection.Long) && - trendSignal.All(t => t.Direction == TradeDirection.Long) && validContext) - { - signal = new Signal( - ticker, - TradeDirection.Long, - Confidence.High, - signals.Last().Candle, - signals.Last().Date, - signals.Last().Exchange, - StrategyType.Composite, SignalType.Signal); - } - else if (signals.All(s => s.Direction == TradeDirection.Short) && - trendSignal.All(t => t.Direction == TradeDirection.Short) && validContext) - { - signal = new Signal( - ticker, - TradeDirection.Short, - Confidence.High, - signals.Last().Candle, - signals.Last().Date, - signals.Last().Exchange, - StrategyType.Composite, SignalType.Signal); - } - } - else + public static Signal ComputeSignals(HashSet strategies, HashSet signalOnCandles, Ticker ticker, + Timeframe timeframe, StrategyComboConfig config) + { + if (strategies.Count == 1) { - // Only one strategy, we just add the single signal to the bot - signal = signalOnCandles.Single(); + // Only one strategy, return the single signal + return signalOnCandles.Single(); } - return signal; + // Group signals by type for analysis + var signalStrategies = signalOnCandles.Where(s => s.SignalType == SignalType.Signal).ToList(); + var trendStrategies = signalOnCandles.Where(s => s.SignalType == SignalType.Trend).ToList(); + var contextStrategies = signalOnCandles.Where(s => s.SignalType == SignalType.Context).ToList(); + + // Context validation - evaluates market conditions based on confidence levels + if (!ValidateContextStrategies(strategies, contextStrategies, config)) + { + return null; // Context strategies are blocking the trade + } + + // Trend analysis - evaluate overall market direction + var trendDirection = EvaluateTrendDirection(trendStrategies, config); + + // Signal analysis - evaluate entry signals + var signalDirection = EvaluateSignalDirection(signalStrategies, config); + + // Determine final direction and confidence + var (finalDirection, confidence) = DetermineFinalSignal(signalDirection, trendDirection, signalStrategies, trendStrategies, config); + + if (finalDirection == TradeDirection.None || confidence < config.MinimumConfidence) + { + return null; // No valid signal or below minimum confidence + } + + // Create composite signal + var lastSignal = signalStrategies.LastOrDefault() ?? trendStrategies.LastOrDefault() ?? contextStrategies.LastOrDefault(); + + return new Signal( + ticker, + finalDirection, + confidence, + lastSignal?.Candle, + lastSignal?.Date ?? DateTime.UtcNow, + lastSignal?.Exchange ?? config.DefaultExchange, + StrategyType.Composite, + SignalType.Signal); + } + + /// + /// Validates context strategies based on confidence levels indicating market condition quality + /// + private static bool ValidateContextStrategies(HashSet allStrategies, List contextSignals, StrategyComboConfig config) + { + var contextStrategiesCount = allStrategies.Count(s => s.SignalType == SignalType.Context); + + if (contextStrategiesCount == 0) + { + return true; // No context strategies, no restrictions + } + + // Check if we have signals from all context strategies + if (contextSignals.Count != contextStrategiesCount) + { + return false; // Missing context information + } + + // All context strategies must meet minimum confidence requirements + // This ensures market conditions are suitable for trading + return contextSignals.All(s => s.Confidence >= config.MinimumContextConfidence); + } + + /// + /// Evaluates trend direction using majority voting with neutral handling + /// + private static TradeDirection EvaluateTrendDirection(List trendSignals, StrategyComboConfig config) + { + if (!trendSignals.Any()) + { + return TradeDirection.None; // No trend information available + } + + var longCount = trendSignals.Count(s => s.Direction == TradeDirection.Long); + var shortCount = trendSignals.Count(s => s.Direction == TradeDirection.Short); + var neutralCount = trendSignals.Count(s => s.Direction == TradeDirection.None); + + // Strong trend agreement using configurable threshold + var totalTrend = trendSignals.Count; + if (longCount > totalTrend * config.TrendStrongAgreementThreshold) + return TradeDirection.Long; + if (shortCount > totalTrend * config.TrendStrongAgreementThreshold) + return TradeDirection.Short; + + // Moderate trend agreement (> 50% but <= strong threshold) + if (longCount > shortCount && longCount > neutralCount) + return TradeDirection.Long; + if (shortCount > longCount && shortCount > neutralCount) + return TradeDirection.Short; + + // No clear trend or too many neutrals + return TradeDirection.None; + } + + /// + /// Evaluates signal direction using weighted majority voting + /// + private static TradeDirection EvaluateSignalDirection(List signalStrategies, StrategyComboConfig config) + { + if (!signalStrategies.Any()) + { + return TradeDirection.None; // No signal strategies + } + + // For signal strategies, we need stronger agreement since they're rare and should be precise + var longCount = signalStrategies.Count(s => s.Direction == TradeDirection.Long); + var shortCount = signalStrategies.Count(s => s.Direction == TradeDirection.Short); + + // Use configurable agreement threshold for signals + var totalSignals = signalStrategies.Count; + if (longCount > totalSignals * config.SignalAgreementThreshold) + return TradeDirection.Long; + if (shortCount > totalSignals * config.SignalAgreementThreshold) + return TradeDirection.Short; + + return TradeDirection.None; + } + + /// + /// Determines final signal direction and confidence based on signal and trend analysis + /// + private static (TradeDirection Direction, Confidence Confidence) DetermineFinalSignal( + TradeDirection signalDirection, + TradeDirection trendDirection, + List signalStrategies, + List trendStrategies, + StrategyComboConfig config) + { + // Priority 1: If we have signal strategies, they take precedence + if (signalDirection != TradeDirection.None) + { + // Signal strategies have fired - check if trend supports or conflicts + if (trendDirection == signalDirection) + { + // Perfect alignment - signal and trend agree + return (signalDirection, Confidence.High); + } + else if (trendDirection == TradeDirection.None) + { + // No trend information or neutral trend - medium confidence + return (signalDirection, Confidence.Medium); + } + else if (config.AllowSignalTrendOverride) + { + // Trend conflicts with signal but we allow override + // This could be a trend reversal signal + return (signalDirection, Confidence.Low); + } + else + { + // Trend conflicts and we don't allow override + return (TradeDirection.None, Confidence.None); + } + } + + // Priority 2: Only trend strategies available + if (trendDirection != TradeDirection.None) + { + // Calculate confidence based on trend strength + var totalTrend = trendStrategies.Count; + var majorityDirection = trendDirection == TradeDirection.Long + ? trendStrategies.Count(s => s.Direction == TradeDirection.Long) + : trendStrategies.Count(s => s.Direction == TradeDirection.Short); + + var agreementPercentage = (decimal)majorityDirection / totalTrend; + + if (agreementPercentage >= 0.8m) + return (trendDirection, Confidence.High); + else if (agreementPercentage >= config.TrendStrongAgreementThreshold) + return (trendDirection, Confidence.Medium); + else + return (trendDirection, Confidence.Low); + } + + // No valid signal found + return (TradeDirection.None, Confidence.None); } public static MoneyManagement GetBestMoneyManagement(List candles, List positions, diff --git a/src/Managing.Domain/Strategies/StDevContext.cs b/src/Managing.Domain/Strategies/StDevContext.cs index 23a3a3a..0f04535 100644 --- a/src/Managing.Domain/Strategies/StDevContext.cs +++ b/src/Managing.Domain/Strategies/StDevContext.cs @@ -33,16 +33,38 @@ public class StDevContext : Strategy return null; var lastCandle = stDevCandles.Last(); + var zScore = lastCandle.ZScore ?? 0; - if (lastCandle.ZScore is < 1.2 and > (-1.2)) + // Determine confidence based on Z-score ranges + // Lower absolute Z-score = more normal volatility = higher confidence for trading + // Higher absolute Z-score = more extreme volatility = lower confidence for trading + Confidence confidence; + + if (Math.Abs(zScore) <= 0.5) { - AddSignal(lastCandle, TradeDirection.None, Confidence.Medium); + // Very low volatility - ideal conditions for trading + confidence = Confidence.High; + } + else if (Math.Abs(zScore) <= 1.0) + { + // Normal volatility - good conditions for trading + confidence = Confidence.Medium; + } + else if (Math.Abs(zScore) <= 1.5) + { + // Elevated volatility - caution advised + confidence = Confidence.Low; } else { - Console.WriteLine("Bad zscore"); + // High volatility - trading not recommended + confidence = Confidence.None; } + // Context strategies always return TradeDirection.None + // The confidence level indicates the quality of market conditions + AddSignal(lastCandle, TradeDirection.None, confidence); + return Signals.Where(s => s.Confidence != Confidence.None).OrderBy(s => s.Date).ToList(); } catch (RuleException) diff --git a/src/Managing.Infrastructure.Messengers/Discord/DiscordService.cs b/src/Managing.Infrastructure.Messengers/Discord/DiscordService.cs index d2ffd16..ac3e4f0 100644 --- a/src/Managing.Infrastructure.Messengers/Discord/DiscordService.cs +++ b/src/Managing.Infrastructure.Messengers/Discord/DiscordService.cs @@ -6,7 +6,6 @@ using Managing.Application.Abstractions; using Managing.Application.Abstractions.Services; using Managing.Application.Trading; using Managing.Application.Trading.Commands; -using Managing.Application.Workers.Abstractions; using Managing.Common; using Managing.Core; using Managing.Domain.MoneyManagements; @@ -294,7 +293,7 @@ namespace Managing.Infrastructure.Messengers.Discord $"Open Price : {position.Open.Price} \n" + $"Closing Price : {position.Open.Price} \n" + $"Quantity :{position.Open.Quantity} \n" + - $"PNL : {position.ProfitAndLoss.Net} $"; + $"PNL : {position.ProfitAndLoss.Realized} $"; } private async Task ClosePosition(SocketMessageComponent component, string[] parameters) diff --git a/src/Managing.Web3Proxy/package-lock.json b/src/Managing.Web3Proxy/package-lock.json index 5465cff..a7237ee 100644 --- a/src/Managing.Web3Proxy/package-lock.json +++ b/src/Managing.Web3Proxy/package-lock.json @@ -4340,7 +4340,7 @@ }, "node_modules/get-tsconfig": { "version": "4.10.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -6598,7 +6598,7 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", - "dev": true, + "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -7526,7 +7526,7 @@ }, "node_modules/tsx": { "version": "4.19.3", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "esbuild": "~0.25.0", @@ -7646,7 +7646,7 @@ }, "node_modules/typescript": { "version": "5.8.2", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts index 5b122c8..08e5d4c 100644 --- a/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts +++ b/src/Managing.Web3Proxy/src/plugins/custom/gmx.ts @@ -212,13 +212,14 @@ export const openGmxPositionImpl = async ( marketAddress: marketInfo.marketTokenAddress, payTokenAddress: collateralToken.address, collateralTokenAddress: collateralToken.address, - allowedSlippageBps: 100, // 0.5% slippage + allowedSlippageBps: 50, // 0.5% slippage leverage: leverageBps, skipSimulation: true, referralCodeForTxn: encodeReferralCode("kaigen_ai"), stopLossPrice: stopLossPrice ? numberToBigint(stopLossPrice, 30) : undefined, takeProfitPrice: takeProfitPrice ? numberToBigint(takeProfitPrice, 30) : undefined, acceptablePriceImpactBuffer: 150, + limitPrice: limitPrice, }; if (direction === TradeDirection.Long) { diff --git a/src/Managing.WebApp/src/components/organism/CustomMoneyManagement/CustomMoneyManagement.tsx b/src/Managing.WebApp/src/components/organism/CustomMoneyManagement/CustomMoneyManagement.tsx index d3bce28..52fadc7 100644 --- a/src/Managing.WebApp/src/components/organism/CustomMoneyManagement/CustomMoneyManagement.tsx +++ b/src/Managing.WebApp/src/components/organism/CustomMoneyManagement/CustomMoneyManagement.tsx @@ -65,7 +65,7 @@ const CustomMoneyManagement: React.FC = ({ value={takeProfit} onChange={(e: any) => setTakeProfit(e.target.value)} step="0.01" - max="20" + max="100" type='number' className='input input-bordered' > @@ -77,7 +77,7 @@ const CustomMoneyManagement: React.FC = ({ value={stopLoss} onChange={(e: any) => setStopLoss(e.target.value)} step="0.01" - max="20" + max="100" type='number' className='input input-bordered' > diff --git a/src/Managing.WebApp/src/components/organism/Trading/TradeChart/TradeChart.tsx b/src/Managing.WebApp/src/components/organism/Trading/TradeChart/TradeChart.tsx index 2833513..fbc5d3f 100644 --- a/src/Managing.WebApp/src/components/organism/Trading/TradeChart/TradeChart.tsx +++ b/src/Managing.WebApp/src/components/organism/Trading/TradeChart/TradeChart.tsx @@ -169,6 +169,20 @@ const TradeChart = ({ chart.current = createChart(chartRef.current, { crosshair: { mode: CrosshairMode.Normal, + vertLine: { + color: theme.accent, + width: 1, + style: LineStyle.Solid, + visible: true, + labelVisible: true, + }, + horzLine: { + color: theme.accent, + width: 1, + style: LineStyle.Solid, + visible: true, + labelVisible: true, + }, }, grid: { horzLines: { @@ -334,6 +348,7 @@ const TradeChart = ({ priceLineColor: theme.info, title: 'SuperTrend', pane: 0, + }) const superTrend = strategiesValues.SuperTrend.superTrend?.map((w) => { @@ -409,6 +424,7 @@ const TradeChart = ({ precision: 1, type: 'price', }, + crosshairMarkerVisible: true, }) paneCount++ @@ -453,6 +469,7 @@ const TradeChart = ({ precision: 6, type: 'price', }, + crosshairMarkerVisible: true, }) const macdData = strategiesValues.MacdCross.macd?.map((w) => { @@ -537,6 +554,7 @@ const TradeChart = ({ baseValue: {price: 0, type: 'price'}, title: 'ZScore', pane: paneCount, + crosshairMarkerVisible: true, }) const zScore = strategiesValues.StDev.stdDev?.map((w) => {