519 lines
21 KiB
Markdown
519 lines
21 KiB
Markdown
# build-indicator
|
|
|
|
## When to Use
|
|
|
|
Use this command when you need to:
|
|
- Create new technical indicators based on pattern descriptions
|
|
- Add signal, trend, or context indicators to the trading system
|
|
- Update all related files and configurations automatically
|
|
- Follow the established indicator architecture and conventions
|
|
|
|
## Prerequisites
|
|
|
|
- Clear indicator specification with Type, Label, Core Logic, Triggers, and Parameters
|
|
- Understanding of indicator categories (Signal/Trend/Context)
|
|
- Access to existing indicator implementations for reference
|
|
- Knowledge of the indicator's mathematical calculations
|
|
|
|
## Execution Steps
|
|
|
|
### Step 1: Parse Indicator Specification
|
|
|
|
Analyze the indicator description and extract:
|
|
|
|
**Required Information:**
|
|
- **Type**: Signal/Trend/Context (determines folder location)
|
|
- **Label**: Indicator name (e.g., "Stochastic Filtered")
|
|
- **Core Logic**: Technical description of what the indicator does
|
|
- **Trigger Conditions**: When to generate signals (for Signal indicators)
|
|
- **Parameters**: Configuration values with defaults
|
|
- **Signal Type**: Long/Short for Signal indicators, Confidence levels for Context
|
|
|
|
**Example Format:**
|
|
```
|
|
Type: Signal
|
|
Label: Stochastic Filtered
|
|
Core Logic: Generates signals by filtering %K / %D crossovers to occur only within extreme overbought (above 80) or oversold (below 20) zones.
|
|
Trigger a Long when → The %K line crosses above the %D line (bullish momentum shift). The crossover occurs in the oversold zone (both %K and %D lines are below 20).
|
|
Trigger a Short when → The %K line crosses below the %D line (bearish momentum shift). The crossover occurs in the overbought zone (both %K and %D lines are above 80).
|
|
Parameters:
|
|
%K Period (default: 14)
|
|
%K Slowing (default: 3)
|
|
%D Period (default: 3)
|
|
Oversold Threshold: 20
|
|
Overbought Threshold: 80
|
|
```
|
|
|
|
**Bollinger Bands Example:**
|
|
```
|
|
Type: Context
|
|
Label: Bollinger Bands Volatility Protection
|
|
Core Logic: Uses the Bandwidth (distance between Upper and Lower bands) to measure market volatility and apply veto filters during extreme conditions.
|
|
Context Confidence Levels: Block signals when bandwidth is extremely high (>0.15) or low (<0.02), validate when normal (0.02-0.15).
|
|
Parameters:
|
|
Period (default: 20)
|
|
StDev (default: 2.0)
|
|
```
|
|
|
|
### Step 2: Determine Implementation Details
|
|
|
|
**Check Existing Indicators:**
|
|
- Search codebase: `grep -r "Get{IndicatorType}" src/Managing.Domain/Indicators/`
|
|
- Look for similar Skender.Stock.Indicators usage patterns
|
|
- Check if candle mapping logic can be shared with existing indicators
|
|
|
|
**Class Name Convention:**
|
|
- Signal indicators: `{IndicatorName}.cs` (e.g., `StochasticFiltered.cs`)
|
|
- Trend indicators: `{IndicatorName}.cs` (e.g., `EmaTrend.cs`)
|
|
- Context indicators: `{IndicatorName}.cs` (e.g., `StDev.cs`)
|
|
|
|
**Inheritance Strategy:**
|
|
- Default: Extend `IndicatorBase` directly
|
|
- Shared Mapping: Extend from existing shared base class if mappings overlap
|
|
- New Shared Base: Create base class only if multiple indicators will share the same mapping
|
|
|
|
**Class Name Pattern:**
|
|
- For signal/trend indicators: Class name = `{IndicatorName}` (inherits from `IndicatorBase` or shared base)
|
|
- For context indicators: Class name = `{IndicatorName}` (inherits from `IndicatorBase` or shared base)
|
|
|
|
**Location:**
|
|
- Signal → `src/Managing.Domain/Indicators/Signals/`
|
|
- Trend → `src/Managing.Domain/Indicators/Trends/`
|
|
- Context → `src/Managing.Domain/Indicators/Context/`
|
|
|
|
**Enum Name:**
|
|
- Convert label to PascalCase: `StochasticFiltered`
|
|
- Add to `IndicatorType` enum in `src/Managing.Common/Enums.cs`
|
|
|
|
### Step 3: Implement Indicator Class
|
|
|
|
Create the indicator class following the established pattern. Check if other indicators use similar candle mappings - if so, consider creating or extending a base class.
|
|
|
|
**Check for Existing Candle Mappings:**
|
|
- Search for similar indicator types that might share candle mappings
|
|
- If another indicator uses the same Skender.Stock.Indicators result type, consider extending an existing base class or creating a shared base class
|
|
- Only create a new base class if no other indicator shares the same candle mapping pattern
|
|
|
|
**Base Structure:**
|
|
```csharp
|
|
using Managing.Core;
|
|
using Managing.Domain.Candles;
|
|
using Managing.Domain.Indicators;
|
|
using Managing.Domain.Shared.Rules;
|
|
using Managing.Domain.Strategies.Base;
|
|
using Skender.Stock.Indicators;
|
|
using static Managing.Common.Enums;
|
|
|
|
namespace Managing.Domain.Strategies.{TypeFolder};
|
|
|
|
public class {IndicatorName} : IndicatorBase
|
|
{
|
|
public List<LightSignal> Signals { get; set; }
|
|
|
|
public {IndicatorName}(string name, {parameters}) :
|
|
base(name, IndicatorType.{EnumName})
|
|
{
|
|
Signals = new List<LightSignal>();
|
|
// Initialize parameters (e.g., Period, Multiplier, StDev)
|
|
}
|
|
|
|
// Implementation methods...
|
|
}
|
|
```
|
|
|
|
**For Bollinger Bands (use shared base):**
|
|
```csharp
|
|
public class {IndicatorName} : BollingerBandsBase
|
|
{
|
|
public {IndicatorName}(string name, int period, double stdev) :
|
|
base(name, IndicatorType.{EnumName}, period, stdev)
|
|
{
|
|
}
|
|
|
|
// Only implement ProcessBollingerBandsSignals method
|
|
}
|
|
```
|
|
|
|
**Shared Base Class Pattern (use only if mapping is shared):**
|
|
If another indicator uses the same candle result mapping, extend from a shared base class:
|
|
|
|
```csharp
|
|
public class {SharedBaseName}Base : IndicatorBase
|
|
{
|
|
// Shared candle mapping logic here
|
|
protected List<{CandleResultType}> Map{Indicator}ToCandle(List<{SkenderResult}> results, IEnumerable<Candle> candles)
|
|
{
|
|
// Shared mapping implementation
|
|
}
|
|
}
|
|
|
|
public class {IndicatorName} : {SharedBaseName}Base
|
|
{
|
|
// Indicator-specific logic only
|
|
}
|
|
```
|
|
|
|
**Key Methods to Implement:**
|
|
1. `Run(HashSet<Candle> candles)` - Main calculation logic
|
|
2. `Run(HashSet<Candle> candles, IndicatorsResultBase preCalculatedValues)` - Optimized version
|
|
3. `GetIndicatorValues(HashSet<Candle> candles)` - Return calculated values
|
|
4. Private processing methods for signal generation
|
|
|
|
**Signal Generation Pattern:**
|
|
```csharp
|
|
private void ProcessSignals(List<{Indicator}Result> results, HashSet<Candle> candles)
|
|
{
|
|
var mappedData = Map{Indicator}ToCandle(results, candles);
|
|
|
|
if (mappedData.Count == 0) return;
|
|
|
|
var previousCandle = mappedData[0];
|
|
foreach (var currentCandle in mappedData.Skip(1))
|
|
{
|
|
// Check trigger conditions
|
|
if (/* Long condition */)
|
|
{
|
|
AddSignal(currentCandle, TradeDirection.Long, Confidence.Medium);
|
|
}
|
|
|
|
if (/* Short condition */)
|
|
{
|
|
AddSignal(currentCandle, TradeDirection.Short, Confidence.Medium);
|
|
}
|
|
|
|
previousCandle = currentCandle;
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 4: Update Configuration Files
|
|
|
|
**Update Enums.cs:**
|
|
```csharp
|
|
public enum IndicatorType
|
|
{
|
|
// ... existing indicators
|
|
StochasticFiltered,
|
|
// ... continue
|
|
}
|
|
```
|
|
|
|
**Update IndicatorBase.cs:**
|
|
- Add any new parameter properties needed (e.g., `StDev` for Bollinger Bands)
|
|
|
|
**Update LightIndicator.cs:**
|
|
- Add any new parameter properties with proper Id attributes for Orleans serialization
|
|
- Update `LightToBase()` method to copy new properties
|
|
|
|
**Update IndicatorRequest.cs:**
|
|
- Add any new parameter properties to match LightIndicator
|
|
|
|
**Update DataController.cs:**
|
|
- Add any new parameter properties to the `MapScenarioRequestToScenario()` method's `IndicatorBase` initialization
|
|
- This ensures API requests with indicator parameters are properly mapped to domain objects
|
|
|
|
**Update ScenarioHelpers.cs:**
|
|
- Add case to `BuildIndicator()` method: `IndicatorType.{EnumName} => new {IndicatorName}(indicator.Name, {parameters})`
|
|
- Add case to `GetSignalType()` method: `IndicatorType.{EnumName} => SignalType.{Type}`
|
|
- Add parameter validation in `BuildIndicator()` method switch statement
|
|
- Add new parameters to `BuildIndicator()` method signature if needed
|
|
- Update `BaseToLight()` method to copy all LightIndicator properties
|
|
|
|
**Update BacktestJobService.cs:**
|
|
- Update LightIndicator creation in bundle job creation to include all new properties
|
|
- Ensure all indicator parameters are properly mapped from requests
|
|
|
|
**Update DataController.cs:**
|
|
- Update `MapScenarioRequestToScenario()` method to include all new parameters in the `IndicatorBase` initialization
|
|
- Ensure all properties from `IndicatorRequest` are properly mapped to `IndicatorBase` (Period, StDev, KFactor, DFactor, TenkanPeriods, etc.)
|
|
|
|
**Update GeneticService.cs:**
|
|
- Add default values to `DefaultIndicatorValues`: `[IndicatorType.{EnumName}] = new() { {param_mappings} }`
|
|
- Add parameter ranges to `IndicatorParameterRanges`: `[IndicatorType.{EnumName}] = new() { {param_ranges} }`
|
|
- Add parameter mapping to `IndicatorParamMapping`: `[IndicatorType.{EnumName}] = [{param_names}]`
|
|
- Update `TradingBotChromosome.GetSelectedIndicators()` to handle new parameters
|
|
|
|
**Update Frontend Files:**
|
|
|
|
*CustomScenario.tsx:*
|
|
- Add new parameters to indicator type definitions
|
|
- Update parameter input handling (float vs int parsing)
|
|
- Add default values for new parameters
|
|
|
|
*TradeChart.tsx (if applicable):*
|
|
- Add visualization logic for new indicator bands/lines
|
|
- Use appropriate colors and styles for differentiation
|
|
|
|
### Step 5: Test and Validate
|
|
|
|
**Compile Check:**
|
|
```bash
|
|
# Backend compilation
|
|
dotnet build
|
|
|
|
# Frontend compilation
|
|
cd src/Managing.WebApp && npm run build
|
|
```
|
|
|
|
**Basic Validation:**
|
|
- Verify indicator appears in GeneticService configurations
|
|
- Check that BuildIndicator methods work correctly
|
|
- Ensure proper SignalType assignment
|
|
- Verify LightIndicator serialization works (Orleans Id attributes)
|
|
- Check parameter validation in ScenarioHelpers.BuildIndicator
|
|
- Confirm frontend parameter handling works correctly
|
|
|
|
**Integration Test:**
|
|
- Create a simple backtest using the new indicator
|
|
- Verify signals are generated correctly
|
|
- Check parameter handling and validation
|
|
- Test frontend scenario creation with new parameters
|
|
- Verify chart visualization displays correctly (if applicable)
|
|
|
|
## Available Skender.Stock.Indicators
|
|
|
|
The following indicators are available from the [Skender.Stock.Indicators](https://dotnet.stockindicators.dev/) library and can be used as the basis for custom trading indicators:
|
|
|
|
### Trend Indicators
|
|
- **EMA (Exponential Moving Average)**: `GetEma(period)` - Smooths price data with exponential weighting
|
|
- **SMA (Simple Moving Average)**: `GetSma(period)` - Arithmetic mean of prices over period
|
|
- **WMA (Weighted Moving Average)**: `GetWma(period)` - Weighted average favoring recent prices
|
|
- **HMA (Hull Moving Average)**: `GetHma(period)` - Responsive moving average using WMA
|
|
- **DEMA (Double Exponential Moving Average)**: `GetDema(period)` - Two EMAs for reduced lag
|
|
- **TEMA (Triple Exponential Moving Average)**: `GetTema(period)` - Three EMAs for further lag reduction
|
|
- **VWMA (Volume Weighted Moving Average)**: `GetVwma(period)` - Volume-weighted price average
|
|
|
|
### Momentum Oscillators
|
|
- **RSI (Relative Strength Index)**: `GetRsi(period)` - Momentum oscillator (0-100)
|
|
- **Stochastic Oscillator**: `GetStoch(kPeriod, kSlowing, dPeriod)` - %K and %D lines
|
|
- **Stochastic RSI**: `GetStochRsi(rsiPeriod, stochPeriod, signalPeriod, smoothPeriod)` - Stochastic of RSI
|
|
- **Williams %R**: `GetWilliamsR(period)` - Momentum oscillator (-100 to 0)
|
|
- **CCI (Commodity Channel Index)**: `GetCci(period)` - Mean deviation from average price
|
|
- **MFI (Money Flow Index)**: `GetMfi(period)` - Volume-weighted RSI
|
|
- **AO (Awesome Oscillator)**: `GetAo()` - MACD of median price
|
|
- **KVO (Klinger Volume Oscillator)**: `GetKvo(fastPeriod, slowPeriod, signalPeriod)` - Volume oscillator
|
|
|
|
### Trend Following
|
|
- **MACD (Moving Average Convergence Divergence)**: `GetMacd(fastPeriod, slowPeriod, signalPeriod)` - Trend momentum indicator
|
|
- **SuperTrend**: `GetSuperTrend(period, multiplier)` - ATR-based trailing stop
|
|
- **Chandelier Exit**: `GetChandelier(period, multiplier, type)` - ATR-based exit levels
|
|
- **Parabolic SAR**: `GetParabolicSar(accelerationStep, maxAcceleration)` - Trailing stop and reversal
|
|
- **ADX (Average Directional Index)**: `GetAdx(period)` - Trend strength indicator
|
|
- **DMI (Directional Movement Index)**: `GetDmi(period)` - Trend direction and strength
|
|
- **PSAR (Parabolic SAR)**: `GetPsar(accelerationStep, maxAcceleration)` - Dynamic support/resistance
|
|
|
|
### Volatility Indicators
|
|
- **ATR (Average True Range)**: `GetAtr(period)` - Volatility measurement
|
|
- **Bollinger Bands**: `GetBollingerBands(period, standardDeviations)` - Price volatility bands
|
|
- **Standard Deviation**: `GetStdDev(period)` - Statistical volatility measure
|
|
- **TR (True Range)**: `GetTr()` - Maximum price movement range
|
|
|
|
### Volume Indicators
|
|
- **OBV (On Balance Volume)**: `GetObv()` - Cumulative volume based on price direction
|
|
- **CMF (Chaikin Money Flow)**: `GetCmf(period)` - Volume-weighted price trend
|
|
- **ADL (Accumulation/Distribution Line)**: `GetAdl()` - Volume-based price accumulation
|
|
- **EMV (Ease of Movement)**: `GetEmv(period)` - Price movement relative to volume
|
|
- **NVI (Negative Volume Index)**: `GetNvi()` - Volume-based trend indicator
|
|
|
|
### Cycle Indicators
|
|
- **STC (Schaff Trend Cycle)**: `GetStc(cyclePeriod, fastPeriod, slowPeriod)` - Cycle oscillator (0-100)
|
|
- **DPO (Detrended Price Oscillator)**: `GetDpo(period)` - Removes trend from price
|
|
- **EPMA (Endpoint Moving Average)**: `GetEpma(period)` - End-point moving average
|
|
|
|
### Support/Resistance
|
|
- **Pivot Points**: `GetPivotPoints(period)` - Traditional pivot levels
|
|
- **Fibonacci Retracements**: `GetFibonacciRetracements()` - Fibonacci ratio levels
|
|
|
|
### Candlestick Patterns
|
|
- **Doji**: `GetDoji()` - Doji candlestick patterns
|
|
- **Hammer**: `GetHammer()` - Hammer patterns
|
|
- **Engulfing**: `GetEngulfing()` - Bullish/bearish engulfing
|
|
- **Marubozu**: `GetMarubozu()` - Marubozu patterns
|
|
- **And many more...**
|
|
|
|
### Usage Examples
|
|
|
|
```csharp
|
|
// Basic usage
|
|
var ema = candles.GetEma(20).ToList();
|
|
var macd = candles.GetMacd(12, 26, 9).ToList();
|
|
var rsi = candles.GetRsi(14).ToList();
|
|
var stoch = candles.GetStoch(14, 3, 3).ToList();
|
|
var superTrend = candles.GetSuperTrend(10, 3.0).ToList();
|
|
|
|
// Chain indicators (indicator of indicators)
|
|
var rsiOfObv = candles.GetObv().GetRsi(14).ToList();
|
|
var smaOfRsi = candles.GetRsi(14).GetSma(9).ToList();
|
|
```
|
|
|
|
For complete documentation and examples, visit: [Skender.Stock.Indicators Guide](https://dotnet.stockindicators.dev/guide/)
|
|
|
|
### Finding the Right Method
|
|
|
|
When implementing a new indicator, search the [Skender documentation](https://dotnet.stockindicators.dev/indicators/) for your indicator concept:
|
|
|
|
1. **Identify the core calculation**: What mathematical formula does your indicator use?
|
|
2. **Find the Skender equivalent**: Search for methods like `Get{IndicatorName}()`
|
|
3. **Check parameters**: Most indicators follow common patterns:
|
|
- `period`: Lookback period (typically 5-300)
|
|
- `fastPeriod`/`slowPeriod`: For dual moving averages
|
|
- `signalPeriod`: For signal line calculations
|
|
- `multiplier`: ATR multipliers (typically 1.0-5.0)
|
|
4. **Verify result structure**: Check what properties the result object contains
|
|
|
|
### Parameter Guidelines
|
|
|
|
**Common Ranges by Indicator Type:**
|
|
- **Moving Averages**: Period 5-300 (shorter = responsive, longer = smooth)
|
|
- **Oscillators**: Period 5-50 (RSI: 14, Stoch: 14, CCI: 20)
|
|
- **Trend Following**: Period 10-50, Multiplier 1.0-5.0
|
|
- **Volatility**: Period 5-50, Standard Deviations (StDev) 1.0-3.0 (Bollinger Bands)
|
|
- **Volume**: Period 5-50 (OBV uses no period)
|
|
|
|
**Testing Parameters:**
|
|
- Start with industry standard defaults
|
|
- Test multiple parameter combinations
|
|
- Consider timeframe: Shorter timeframes may need smaller periods
|
|
|
|
### Result Object Patterns
|
|
|
|
Different indicators return different result objects. Common patterns:
|
|
|
|
**Single Value Results:**
|
|
- `EmaResult`: `{ Date, Ema }`
|
|
- `RsiResult`: `{ Date, Rsi }`
|
|
- `AtrResult`: `{ Date, Atr }`
|
|
- `ObvResult`: `{ Date, Obv }`
|
|
|
|
**Dual Value Results:**
|
|
- `StochResult`: `{ Date, PercentK, PercentD, Oscillator }`
|
|
- `MacdResult`: `{ Date, Macd, Signal, Histogram }`
|
|
- `StochRsiResult`: `{ Date, Rsi, StochRsi, Signal }`
|
|
|
|
**Triple+ Value Results:**
|
|
- `BollingerBandsResult`: `{ Date, Sma, UpperBand, LowerBand }`
|
|
- `SuperTrendResult`: `{ Date, SuperTrend, UpperBand, LowerBand }`
|
|
- `ChandelierResult`: `{ Date, ChandelierExit }`
|
|
|
|
**Candlestick Results:**
|
|
- `CandleResult`: `{ Date, Price, Match, Candle }` (for pattern recognition)
|
|
|
|
When creating your `Candle{Indicator}` mapping class, include all relevant result properties plus the base Candle properties (Close, Open, Date, Ticker, Exchange).
|
|
|
|
### Quick Reference - Currently Used Indicators
|
|
|
|
**In This Codebase:**
|
|
- `GetEma(period)` → `EmaResult` - Used in EMA Trend, EMA Cross, Dual EMA Cross
|
|
- `GetMacd(fast, slow, signal)` → `MacdResult` - Used in MACD Cross
|
|
- `GetRsi(period)` → `RsiResult` - Used in RSI Divergence variants
|
|
- `GetStoch(kPeriod, kSlowing, dPeriod)` → `StochResult` - Used in Stochastic Filtered
|
|
- `GetStochRsi(rsiPeriod, stochPeriod, signalPeriod, smoothPeriod)` → `StochRsiResult` - Used in Stoch RSI Trend
|
|
- `GetSuperTrend(period, multiplier)` → `SuperTrendResult` - Used in SuperTrend, SuperTrend Cross EMA
|
|
- `GetStc(cyclePeriod, fastPeriod, slowPeriod)` → `StcResult` - Used in STC, Lagging STC
|
|
- `GetStdDev(period)` → `StdDevResult` - Used in StDev Context
|
|
- `GetChandelier(period, multiplier, type)` → `ChandelierResult` - Used in Chandelier Exit
|
|
- `GetBollingerBands(period, stdev)` → `BollingerBandsResult` - Used in Bollinger Bands indicators
|
|
- `GetAdx(period)` → `AdxResult` - Used in SuperTrend Cross EMA
|
|
|
|
**Available But Unused:**
|
|
- `GetBollingerBands(period, stdDev)` → `BollingerBandsResult`
|
|
- `GetAtr(period)` → `AtrResult`
|
|
- `GetObv()` → `ObvResult`
|
|
- `GetCci(period)` → `CciResult`
|
|
- `GetMfi(period)` → `MfiResult`
|
|
- And many more... (see full list above)
|
|
|
|
## Common Patterns
|
|
|
|
### Signal Indicator Pattern
|
|
- Uses `TradeDirection.Long`/`Short` with `Confidence` levels
|
|
- Implements crossover or threshold-based logic
|
|
- Returns filtered signals only when conditions are met
|
|
|
|
### Trend Indicator Pattern
|
|
- Uses `TradeDirection.Long`/`Short` for trend direction
|
|
- Continuous assessment rather than discrete signals
|
|
- Lower confidence levels for trend indicators
|
|
|
|
### Context Indicator Pattern
|
|
- Uses `Confidence.None`/`Low`/`Medium`/`High` for veto power
|
|
- Acts as filter for other indicators
|
|
- No directional signals, only context assessment
|
|
|
|
### Shared Base Class Pattern
|
|
**When to Use:**
|
|
- Multiple indicators use the same Skender.Stock.Indicators result type
|
|
- Indicators share identical candle mapping logic
|
|
- Common signal processing patterns exist
|
|
|
|
**Example:**
|
|
```csharp
|
|
public abstract class StochasticBase : IndicatorBase
|
|
{
|
|
protected List<CandleStoch> MapStochToCandle(List<StochResult> stochResults, IEnumerable<Candle> candles)
|
|
{
|
|
// Shared mapping logic for all Stochastic-based indicators
|
|
}
|
|
}
|
|
|
|
public class StochasticFiltered : StochasticBase { /* Specific logic */ }
|
|
public class AnotherStochasticIndicator : StochasticBase { /* Specific logic */ }
|
|
```
|
|
|
|
**Bollinger Bands Example (Implemented):**
|
|
```csharp
|
|
public abstract class BollingerBandsBase : IndicatorBase
|
|
{
|
|
protected double Stdev { get; set; }
|
|
|
|
protected BollingerBandsBase(string name, IndicatorType type, int period, double stdev)
|
|
: base(name, type)
|
|
{
|
|
Stdev = stdev;
|
|
Period = period;
|
|
}
|
|
|
|
protected virtual IEnumerable<CandleBollingerBands> MapBollingerBandsToCandle(
|
|
IEnumerable<BollingerBandsResult> bbResults, IEnumerable<Candle> candles)
|
|
{
|
|
// Shared Bollinger Bands mapping logic with all properties
|
|
// (Sma, UpperBand, LowerBand, PercentB, ZScore, Width)
|
|
}
|
|
}
|
|
|
|
public class BollingerBandsPercentBMomentumBreakout : BollingerBandsBase { /* %B momentum logic */ }
|
|
public class BollingerBandsVolatilityProtection : BollingerBandsBase { /* Volatility protection logic */ }
|
|
```
|
|
|
|
**When NOT to Use:**
|
|
- Indicators have different result types (Stoch vs StochRsi)
|
|
- Mapping logic differs significantly
|
|
- Only one indicator uses a particular pattern
|
|
|
|
## Error Handling
|
|
|
|
**Common Issues:**
|
|
- Missing parameters in constructor
|
|
- Incorrect SignalType assignment
|
|
- Wrong folder location (Signals/Trends/Context)
|
|
- Missing enum updates
|
|
- Parameter range mismatches
|
|
|
|
**Validation Checklist:**
|
|
- [ ] Checked for existing indicators with similar candle mappings
|
|
- [ ] Used appropriate base class (IndicatorBase or shared base if mappings overlap)
|
|
- [ ] Constructor parameters match IIndicator interface
|
|
- [ ] SignalType correctly assigned
|
|
- [ ] Enum added to IndicatorType
|
|
- [ ] IndicatorBase.cs properties added if needed
|
|
- [ ] LightIndicator.cs properties added with proper Id attributes
|
|
- [ ] IndicatorRequest.cs properties added
|
|
- [ ] ScenarioHelpers.cs BuildIndicator and BaseToLight methods updated
|
|
- [ ] BacktestJobService.cs LightIndicator mapping updated
|
|
- [ ] DataController.cs MapScenarioRequestToScenario method updated
|
|
- [ ] GeneticService.cs configurations updated (defaults, ranges, mappings)
|
|
- [ ] Frontend CustomScenario.tsx updated for new parameters
|
|
- [ ] Frontend TradeChart.tsx updated for visualization if needed
|
|
- [ ] Compiles without errors (backend and frontend)
|
|
- [ ] TypeScript types properly aligned
|