Add command for adding indicators
This commit is contained in:
415
.cursor/commands/build-indicator.md
Normal file
415
.cursor/commands/build-indicator.md
Normal file
@@ -0,0 +1,415 @@
|
||||
# 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
|
||||
```
|
||||
|
||||
### 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
|
||||
}
|
||||
|
||||
// Implementation methods...
|
||||
}
|
||||
```
|
||||
|
||||
**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 ScenarioHelpers.cs:**
|
||||
- Add case to `BuildIndicator()` method: `IndicatorType.{EnumName} => new {IndicatorName}(indicator.Name, {parameters})`
|
||||
- Add case to `GetSignalType()` method: `IndicatorType.{EnumName} => SignalType.{Type}`
|
||||
- Add parameters to `BuildIndicator()` overload if needed
|
||||
|
||||
**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}]`
|
||||
|
||||
### Step 5: Test and Validate
|
||||
|
||||
**Compile Check:**
|
||||
```bash
|
||||
dotnet build
|
||||
```
|
||||
|
||||
**Basic Validation:**
|
||||
- Verify indicator appears in GeneticService configurations
|
||||
- Check that BuildIndicator methods work correctly
|
||||
- Ensure proper SignalType assignment
|
||||
|
||||
**Integration Test:**
|
||||
- Create a simple backtest using the new indicator
|
||||
- Verify signals are generated correctly
|
||||
- Check parameter handling and validation
|
||||
|
||||
## 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 1.0-3.0
|
||||
- **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
|
||||
- `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 */ }
|
||||
```
|
||||
|
||||
**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
|
||||
- [ ] BuildIndicator methods updated
|
||||
- [ ] GeneticService configurations updated
|
||||
- [ ] Compiles without errors
|
||||
Reference in New Issue
Block a user