Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
364 changes: 245 additions & 119 deletions docs/building_strategies.md
Original file line number Diff line number Diff line change
@@ -1,123 +1,249 @@
# Building Strategies with OxiDiviner Forecasts
# Building Strategies with OxiDiviner

OxiDiviner provides a suite of powerful time series forecasting models. While these models can generate accurate predictions, translating these forecasts into actionable trading or investment strategies requires careful consideration, robust testing, and a clear understanding of how each model's output can be interpreted.

This guide provides an overview of how you might approach building strategies using various models available in OxiDiviner.
OxiDiviner provides a comprehensive suite of time series forecasting models for building sophisticated trading and investment strategies. This guide outlines how to effectively use the various models and their combinations for different strategic objectives.

**Disclaimer**: The information provided here is for educational purposes only and should not be considered financial advice. All trading strategies involve risk, and past performance is not indicative of future results. Always conduct thorough backtesting and risk assessment before deploying any strategy with real capital.

## General Principles for Strategy Development

Before diving into model-specific ideas, here are some universal principles:

1. **Signal Generation**:
* Clearly define how a model's forecast will translate into a buy, sell, or hold signal.
* This might involve setting thresholds (e.g., forecast > current price + X), looking at the direction of the forecast, or requiring confirmation from multiple models or indicators.

2. **Backtesting**:
* Rigorously test your strategy on historical data that the model was not trained on (out-of-sample testing).
* Employ techniques like walk-forward optimization to simulate real-world performance and adapt parameters over time.
* Evaluate strategies based on multiple metrics: total return, Sharpe ratio, Sortino ratio, maximum drawdown, win rate, etc.

3. **Parameter Optimization (using `OptimizerBuilder`)**:
* Most models and strategy rules have parameters that need tuning (e.g., lookback periods, forecast horizons, signal thresholds).
* OxiDiviner's `OptimizerBuilder` (supporting Grid Search, Random Search, and Bayesian Optimization) can be invaluable.
* **Crucially**, when optimizing for a strategy, the objective function should be a strategy performance metric (like Sharpe ratio from backtesting) rather than just model fit (like Mean Absolute Error).

4. **Risk Management**:
* Implement robust risk management rules for every strategy.
* This includes setting stop-losses, determining appropriate position sizes, managing portfolio-level risk, and considering diversification.

5. **Avoiding Overfitting**:
* Be cautious of creating strategies that are overly complex or too finely tuned to historical data. Simpler, more robust strategies often perform better in live markets.
* Use out-of-sample data for validation and be skeptical of exceptional backtest results.

6. **Transaction Costs & Slippage**:
* Always factor in realistic transaction costs (commissions, fees) and potential slippage when backtesting and evaluating strategies.

## Model-Specific Strategy Ideas

Here's how different OxiDiviner models can be leveraged for strategy building:

### 1. ARIMA (Autoregressive Integrated Moving Average) Models

* **Forecasting Strengths**: Captures trends, mean-reversion, and autocorrelation in time series. OxiDiviner's ARIMA includes robust coefficient validation and stationarity enforcement.
* **Potential Strategy Applications**:
* **Trend Following**:
* Signal: Buy if `forecast > current_price + threshold`; Sell/Short if `forecast < current_price - threshold`.
* Threshold needs optimization based on asset volatility and strategy goals.
* **Mean Reversion**:
* For stationary series, if price is significantly above/below the mean and forecasted to revert, signal a trade back towards the mean.
* **Directional Bias**: Use the forecasted direction as a filter or input for other indicators.
* **Volatility Breakouts (ARIMA on Volatility)**: If an ARIMA model applied to a volatility series forecasts a sharp increase, it could signal a potential price breakout.

### 2. Exponential Smoothing (ES) Models (e.g., Holt-Winters)

* **Forecasting Strengths**: Excellent for series with clear trend and seasonality. OxiDiviner's Holt-Winters features adaptive parameter initialization.
* **Potential Strategy Applications**:
* **Seasonal Pattern Trading**: Forecast seasonal peaks and troughs. Buy before anticipated seasonal upswings, sell before downswings.
* **Trend Confirmation**: Trade in the direction of the smoothed trend component extracted by the model.
* **Deseasonalized Trend Trading**: Remove seasonal effects using the model, then apply trend-following logic to the cleaner underlying trend.

### 3. Ensemble Methods (`EnsembleBuilder`: SimpleAverage, WeightedAverage, Median, BestModel, Stacking)

* **Forecasting Strengths**: Combines forecasts from multiple models to improve robustness and potentially accuracy.
* **Potential Strategy Applications**:
* **Signal Robustness**:
* `SimpleAverage` or `Median`: Base signals on the average/median forecast to reduce reliance on any single model.
* `WeightedAverage`: Assign higher weights to models with better recent strategy performance.
* **Confirmation**: Require a consensus (e.g., 3 out of 5 models agree on direction) before generating a trade.
* **BestModel Switching**: Dynamically use signals from the model that has performed best in the most recent period (requires meta-level performance tracking).
* **Stacking**: Use forecasts from base OxiDiviner models as input features to a meta-learner (e.g., a regression model) that generates the final trading signal.

### 4. Kalman Filter Models

* **Forecasting Strengths**: Estimates hidden underlying states (level, trend, seasonality) from noisy data. Provides a "filtered" view.
* **Potential Strategy Applications**:
* **Trading the Underlying Trend**: Use the estimated trend state as a smoother, more reliable directional indicator.
* **Regime Change Detection**: Significant changes in estimated state variables (e.g., trend slope) can signal potential market regime shifts.
* **Filtered Price Series**: Input the filtered level (estimated true price) into other technical indicators to reduce noise.
* **Innovation Analysis**: Monitor prediction errors (innovations). Consistent biases might signal a need for model re-calibration or indicate a structural market change.

### 5. GARCH Models (Volatility Forecasting - often a component)

* **Forecasting Strengths**: Forecasts the conditional volatility (variance) of a time series.
* **Potential Strategy Applications**:
* **Volatility Targeting/Risk Parity**: Adjust position sizes inversely to forecasted volatility to maintain a stable risk profile.
* **Option Trading**:
* High forecasted volatility: Consider straddles, strangles.
* Low forecasted volatility: Consider credit spreads, iron condors.
* **Breakout Confirmation**: Rising forecasted volatility can confirm price breakouts.
* **Market Filters**: Reduce exposure or tighten stops if extreme volatility is predicted.

### 6. Gaussian Copula Models (and other Copula types)

* **Forecasting Strengths**: Models the dependency structure (e.g., correlation) between multiple assets, separately from their individual distributions.
* **Potential Strategy Applications**:
* **Advanced Pairs Trading/Statistical Arbitrage**: Trade based on forecasted deviations or reversions in the correlation or spread between assets.
* **Dynamic Portfolio Optimization**: Use the forecasted covariance matrix (from forecasted correlations and GARCH-based volatilities) as input for asset allocation.
* **Risk Management**: Stress-test portfolios using scenarios of changing dependency structures.

### 7. Regime-Switching Models (Markov Switching, Higher-Order, Duration-Dependent, Multivariate)

* **Forecasting Strengths**: Identifies distinct market regimes (e.g., bull/bear, high/low volatility) and forecasts the probability of being in each. OxiDiviner offers several advanced types.
* **Potential Strategy Applications**:
* **Strategy Switching/Parameter Adaptation**: Activate different strategies or parameter sets optimized for the currently identified regime.
* **Dynamic Asset Allocation**: Shift portfolio weights based on the regime (e.g., more equities in a "bull" regime). `Multivariate Regime-Switching Models` are especially useful for this.
* **Risk Overlay**: Reduce leverage or tighten stops when a "high-risk" regime is detected.
* **Utilizing Advanced Features**:
* `Higher-Order Models`: Base decisions on sequences of past regimes.
* `Duration-Dependent Models`: Trade based on the expected remaining duration of a regime or "regime fatigue."

## Example Workflow (Conceptual)

1. **Select Asset(s) & Timeframe**: Define the market and period of interest.
2. **Choose OxiDiviner Model(s)**: Based on data characteristics and strategy goals.
3. **Define Strategy Logic**: How will forecasts from the chosen model(s) translate to signals? (e.g., If ARIMA forecast for tomorrow > today's close by 0.5%, then buy).
4. **Optimize Parameters (using `OptimizerBuilder`)**:
* Define a search space for model parameters AND strategy-specific parameters (e.g., the "0.5%" threshold above).
* Set the optimizer's objective function to a backtest performance metric (e.g., maximize Sharpe ratio).
5. **Backtest Rigorously**: Use the optimized parameters on out-of-sample data.
6. **Evaluate & Refine**: Analyze performance, drawdowns, and robustness. Iterate on model choice, strategy logic, or parameters if needed.

Building successful forecasting-based strategies is an iterative process of research, development, and rigorous testing. OxiDiviner aims to provide the robust modeling tools necessary for the forecasting component of this process.
## Core Strategy Components

### 1. Time Series Models
- **ARIMA Family**: For trend and mean-reversion strategies
- `ARModel`: Basic autoregressive patterns
- `ARMAModel`: Combined AR and MA effects
- `ARIMAModel`: Non-stationary series
- `SARIMAModel`: Seasonal patterns
- `VARModel`: Multi-asset relationships

- **Exponential Smoothing**: For adaptive trend following
- `SimpleESModel`: Basic trend following
- `HoltLinearModel`: Enhanced trend capture
- `HoltWintersModel`: Seasonal decomposition
- `ETSModel`: State space formulation

- **GARCH Models**: For volatility-based strategies
- `GARCHModel`: Basic volatility clustering
- `EGARCHModel`: Asymmetric volatility
- `GJRGARCHModel`: Leverage effects
- `GARCHMModel`: Risk premium strategies

### 2. Advanced Financial Models
- **Jump Diffusion**: For tail risk strategies
- `MertonJumpDiffusionModel`: Crash risk hedging
- `KouJumpDiffusionModel`: Asymmetric jump trading

- **Stochastic Volatility**: For volatility trading
- `HestonStochasticVolatilityModel`: Vol surface trading
- `SABRVolatilityModel`: Rates and FX strategies

### 3. Regime Detection
- **Markov Switching**: For regime-based allocation
- `MarkovSwitchingModel`: Basic regime trading
- `MultivariateMarkovSwitchingModel`: Cross-asset regimes
- `HigherOrderMarkovModel`: Complex regime patterns

### 4. Dependency Modeling
- **Copula Models**: For correlation trading
- `GaussianCopulaModel`: Linear dependencies
- `TCopulaModel`: Tail risk dependencies
- `ArchimedeanCopulaModel`: Specialized structures

## Strategy Building Blocks

### 1. Signal Generation
- **Trend Signals**:
```rust
// ARIMA trend detection
let mut model = ARIMAModel::new(2, 1, 2, true)?;
model.fit(&data)?;
let forecast = model.forecast(10)?;
let trend_signal = forecast.last() > data.last();
```

- **Volatility Signals**:
```rust
// GARCH volatility threshold
let mut model = GARCHModel::new(1, 1, None)?;
model.fit(&returns)?;
let vol_forecast = model.forecast(1)?;
let high_vol = vol_forecast[0] > historical_vol * 1.5;
```

- **Regime Signals**:
```rust
// Markov regime detection
let mut model = MarkovSwitchingModel::new(2)?;
model.fit(&data)?;
let current_regime = model.most_likely_regime()?;
```

### 2. Portfolio Construction
- **Risk Parity**:
```rust
// Using GARCH for dynamic allocation
let mut allocations = vec![];
for asset in assets {
let vol = GARCHModel::new(1, 1, None)?.fit(&asset)?.forecast(1)?[0];
allocations.push(1.0 / vol);
}
```

- **Regime-Based Allocation**:
```rust
// Multi-asset regime allocation
let mut model = MultivariateMarkovSwitchingModel::new(2, asset_names)?;
model.fit(&data)?;
let regime = model.portfolio_regime_analysis()?;
```

### 3. Risk Management
- **Value at Risk**:
```rust
// Jump diffusion VaR
let mut model = MertonJumpDiffusionModel::new(0.05, 0.2, 2.0, -0.01, 0.05)?;
model.fit(&data)?;
let var_95 = model.calculate_var(portfolio_value, 0.95, 1.0/252.0)?;
```

- **Tail Risk Hedging**:
```rust
// Copula-based tail risk
let mut model = TCopulaModel::new(n_assets, 5.0)?;
model.fit(&returns)?;
let tail_dep = model.tail_dependence_coefficient(0, 1)?;
```

## Example Strategies

### 1. Adaptive Trend Following
```rust
use oxidiviner::prelude::*;

// Combine ETS and GARCH
let mut trend_model = ETSModel::new()?;
let mut vol_model = GARCHModel::new(1, 1, None)?;

// Fit models
trend_model.fit(&price_data)?;
vol_model.fit(&returns_data)?;

// Generate signals
let trend = trend_model.forecast(1)?[0];
let vol = vol_model.forecast(1)?[0];

// Position sizing
let position_size = if trend > current_price {
1.0 / vol // Long position, inverse vol sizing
} else {
0.0 // Flat
};
```

### 2. Regime-Switching Portfolio
```rust
// Multi-asset regime model
let mut regime_model = MultivariateMarkovSwitchingModel::new(2, assets)?;
regime_model.fit(&returns)?;

// Get regime analysis
let analysis = regime_model.portfolio_regime_analysis()?;

// Regime-based allocation
let allocations = match analysis.current_regime {
0 => vec![0.6, 0.3, 0.1], // Risk-on regime
1 => vec![0.2, 0.6, 0.2], // Risk-off regime
_ => vec![1.0/3.0; 3], // Neutral
};
```

### 3. Options Volatility Trading
```rust
// SABR volatility surface
let mut model = SABRVolatilityModel::new(
forward, 0.2, 0.4, 0.6, -0.3, 1.0/252.0
)?;

// Analyze vol surface
let surface_point = model.implied_volatility(strike, expiry)?;
let vol_signal = surface_point.sabr_implied_vol > surface_point.implied_volatility;
```

### 4. Cross-Asset Arbitrage
```rust
// Copula-based pairs trading
let mut copula = GaussianCopulaModel::new(2)?;
copula.fit(&pair_returns)?;

// Generate spread distribution
let scenarios = copula.simulate(1000)?;
let spread_zscore = (current_spread - mean) / std_dev;
```

## Implementation Best Practices

### 1. Model Selection
- Start with simpler models (AR, MA, ES) before complex ones
- Use information criteria (AIC, BIC) for model order selection
- Consider ensemble methods for robustness
- Validate using both in-sample and out-of-sample metrics

### 2. Risk Management
- Always implement position sizing
- Use stop-losses and take-profits
- Monitor portfolio-level risk
- Consider correlation risk
- Implement circuit breakers

### 3. Performance Monitoring
- Track Sharpe ratio, Sortino ratio, and maximum drawdown
- Monitor hit rate and profit factor
- Analyze regime-dependent performance
- Track transaction costs and slippage

### 4. Production Implementation
- Use proper error handling
- Implement logging and monitoring
- Plan for regular model retraining
- Set up alerts for abnormal conditions

## Strategy Validation Framework

### 1. Backtesting
```rust
use oxidiviner::core::validation::backtest;

let bt_results = backtest(&model, &data, 252, 10)?;
println!("Hit rate: {}%", bt_results.hit_rate * 100.0);
println!("Profit factor: {}", bt_results.profit_factor);
```

### 2. Cross-Validation
```rust
use oxidiviner::core::validation::cross_validate;

let cv_results = cross_validate(&model, &data, 5, 10)?;
println!("CV Sharpe: {}", cv_results.sharpe_ratio);
```

### 3. Stress Testing
```rust
// Regime-based stress testing
let stress_scenarios = vec![
("Bear Market", -0.3, 0.4),
("Bull Market", 0.2, 0.2),
("Crisis", -0.5, 0.6),
];

for (scenario, ret, vol) in stress_scenarios {
let stress_pnl = strategy.simulate_scenario(ret, vol)?;
println!("{}: ${:.2}", scenario, stress_pnl);
}
```

## Conclusion

Building successful strategies with OxiDiviner requires:
1. Understanding the strengths of each model type
2. Proper signal generation and validation
3. Robust risk management
4. Comprehensive testing and monitoring
5. Careful production implementation
Loading
Loading