redesign fully scaffolded and web login works
This commit is contained in:
142
gateway/knowledge/indicators/indicator-development.md
Normal file
142
gateway/knowledge/indicators/indicator-development.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Indicator Development Guide
|
||||
|
||||
Custom indicators in Dexorder are Python functions that process OHLCV data and return signals or values.
|
||||
|
||||
## Indicator Structure
|
||||
|
||||
```python
|
||||
def my_indicator(df, **params):
|
||||
"""
|
||||
Calculate custom indicator
|
||||
|
||||
Args:
|
||||
df: DataFrame with columns [open, high, low, close, volume]
|
||||
**params: Indicator parameters
|
||||
|
||||
Returns:
|
||||
Series or DataFrame with indicator values
|
||||
"""
|
||||
# Implementation
|
||||
return result
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Simple Moving Average
|
||||
```python
|
||||
def sma(df, period=20):
|
||||
return df['close'].rolling(window=period).mean()
|
||||
```
|
||||
|
||||
### Exponential Moving Average
|
||||
```python
|
||||
def ema(df, period=20):
|
||||
return df['close'].ewm(span=period, adjust=False).mean()
|
||||
```
|
||||
|
||||
### RSI (Relative Strength Index)
|
||||
```python
|
||||
def rsi(df, period=14):
|
||||
delta = df['close'].diff()
|
||||
gain = delta.where(delta > 0, 0).rolling(window=period).mean()
|
||||
loss = -delta.where(delta < 0, 0).rolling(window=period).mean()
|
||||
rs = gain / loss
|
||||
return 100 - (100 / (1 + rs))
|
||||
```
|
||||
|
||||
### MACD
|
||||
```python
|
||||
def macd(df, fast=12, slow=26, signal=9):
|
||||
ema_fast = df['close'].ewm(span=fast).mean()
|
||||
ema_slow = df['close'].ewm(span=slow).mean()
|
||||
macd_line = ema_fast - ema_slow
|
||||
signal_line = macd_line.ewm(span=signal).mean()
|
||||
histogram = macd_line - signal_line
|
||||
|
||||
return pd.DataFrame({
|
||||
'macd': macd_line,
|
||||
'signal': signal_line,
|
||||
'histogram': histogram
|
||||
})
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Data Handling
|
||||
- Always validate input DataFrame has required columns
|
||||
- Handle NaN values appropriately
|
||||
- Use `.copy()` to avoid modifying original data
|
||||
- Consider edge cases (not enough data, etc.)
|
||||
|
||||
### Performance
|
||||
- Vectorize operations when possible (avoid loops)
|
||||
- Use pandas/numpy built-in functions
|
||||
- Cache expensive calculations
|
||||
- Test on large datasets
|
||||
|
||||
### Parameters
|
||||
- Provide sensible defaults
|
||||
- Document parameter ranges
|
||||
- Validate parameter values
|
||||
- Consider optimization bounds
|
||||
|
||||
### Testing
|
||||
```python
|
||||
def test_indicator():
|
||||
# Create sample data
|
||||
df = pd.DataFrame({
|
||||
'close': [100, 102, 101, 103, 105]
|
||||
})
|
||||
|
||||
# Test calculation
|
||||
result = my_indicator(df, param=10)
|
||||
|
||||
# Validate output
|
||||
assert not result.isna().all()
|
||||
assert len(result) == len(df)
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Look-Ahead Bias
|
||||
Never use future data:
|
||||
```python
|
||||
# WRONG - uses future data
|
||||
df['signal'] = df['close'].shift(-1) > df['close']
|
||||
|
||||
# CORRECT - only past data
|
||||
df['signal'] = df['close'] > df['close'].shift(1)
|
||||
```
|
||||
|
||||
### Repainting
|
||||
Indicator values should not change for closed bars:
|
||||
```python
|
||||
# Ensure calculations are based on closed candles
|
||||
# Avoid using unstable data sources
|
||||
```
|
||||
|
||||
### Overfitting
|
||||
- Don't optimize on same data you test on
|
||||
- Use separate train/validation/test sets
|
||||
- Walk-forward analysis for robustness
|
||||
- Simple is often better than complex
|
||||
|
||||
## Integration with Strategies
|
||||
|
||||
Indicators are used in strategy signals:
|
||||
```python
|
||||
def my_strategy(df):
|
||||
# Calculate indicators
|
||||
df['rsi'] = rsi(df, period=14)
|
||||
df['sma_fast'] = sma(df, period=20)
|
||||
df['sma_slow'] = sma(df, period=50)
|
||||
|
||||
# Generate signals
|
||||
df['signal'] = 0
|
||||
df.loc[(df['rsi'] < 30) & (df['sma_fast'] > df['sma_slow']), 'signal'] = 1
|
||||
df.loc[(df['rsi'] > 70) & (df['sma_fast'] < df['sma_slow']), 'signal'] = -1
|
||||
|
||||
return df
|
||||
```
|
||||
|
||||
Store indicators in your git repository under `indicators/` directory.
|
||||
Reference in New Issue
Block a user