342 lines
11 KiB
Markdown
342 lines
11 KiB
Markdown
# RandomStrategy Documentation
|
|
|
|
## Overview
|
|
|
|
The `IncRandomStrategy` is a testing strategy that generates random entry and exit signals with configurable probability and confidence levels. It's designed to test the incremental strategy framework and signal processing system while providing a baseline for performance comparisons.
|
|
|
|
## Class: `IncRandomStrategy`
|
|
|
|
### Purpose
|
|
- **Testing Framework**: Validates incremental strategy system functionality
|
|
- **Performance Baseline**: Provides minimal processing overhead for benchmarking
|
|
- **Signal Testing**: Tests signal generation and processing pipelines
|
|
|
|
### Key Features
|
|
- **Minimal Processing**: Extremely fast updates (0.006ms)
|
|
- **Configurable Randomness**: Adjustable signal probabilities and confidence levels
|
|
- **Reproducible Results**: Optional random seed for consistent testing
|
|
- **Real-time Compatible**: Processes minute-level data with timeframe aggregation
|
|
|
|
## Configuration Parameters
|
|
|
|
```python
|
|
params = {
|
|
"entry_probability": 0.05, # 5% chance of entry signal per bar
|
|
"exit_probability": 0.1, # 10% chance of exit signal per bar
|
|
"min_confidence": 0.6, # Minimum signal confidence
|
|
"max_confidence": 0.9, # Maximum signal confidence
|
|
"timeframe": "1min", # Operating timeframe
|
|
"signal_frequency": 1, # Signal every N bars
|
|
"random_seed": 42 # Optional seed for reproducibility
|
|
}
|
|
```
|
|
|
|
## Real-time Usage Example
|
|
|
|
### Basic Implementation
|
|
|
|
```python
|
|
from cycles.IncStrategies.random_strategy import IncRandomStrategy
|
|
import pandas as pd
|
|
from datetime import datetime, timedelta
|
|
|
|
# Initialize strategy
|
|
strategy = IncRandomStrategy(
|
|
weight=1.0,
|
|
params={
|
|
"entry_probability": 0.1, # 10% chance per bar
|
|
"exit_probability": 0.15, # 15% chance per bar
|
|
"min_confidence": 0.7,
|
|
"max_confidence": 0.9,
|
|
"timeframe": "5min", # 5-minute bars
|
|
"signal_frequency": 3, # Signal every 3 bars
|
|
"random_seed": 42 # Reproducible for testing
|
|
}
|
|
)
|
|
|
|
# Simulate real-time minute data stream
|
|
def simulate_live_data():
|
|
"""Simulate live minute-level OHLCV data"""
|
|
base_price = 100.0
|
|
timestamp = datetime.now()
|
|
|
|
while True:
|
|
# Generate realistic OHLCV data
|
|
price_change = (random.random() - 0.5) * 2 # ±1 price movement
|
|
close = base_price + price_change
|
|
high = close + random.random() * 0.5
|
|
low = close - random.random() * 0.5
|
|
open_price = base_price
|
|
volume = random.randint(1000, 5000)
|
|
|
|
yield {
|
|
'timestamp': timestamp,
|
|
'open': open_price,
|
|
'high': high,
|
|
'low': low,
|
|
'close': close,
|
|
'volume': volume
|
|
}
|
|
|
|
base_price = close
|
|
timestamp += timedelta(minutes=1)
|
|
|
|
# Process real-time data
|
|
for minute_data in simulate_live_data():
|
|
# Strategy handles timeframe aggregation (1min -> 5min)
|
|
result = strategy.update_minute_data(
|
|
timestamp=pd.Timestamp(minute_data['timestamp']),
|
|
ohlcv_data=minute_data
|
|
)
|
|
|
|
# Check if a complete 5-minute bar was formed
|
|
if result is not None:
|
|
print(f"Complete 5min bar at {minute_data['timestamp']}")
|
|
|
|
# Get signals
|
|
entry_signal = strategy.get_entry_signal()
|
|
exit_signal = strategy.get_exit_signal()
|
|
|
|
# Process entry signals
|
|
if entry_signal.signal_type == "ENTRY":
|
|
print(f"🟢 ENTRY Signal - Confidence: {entry_signal.confidence:.2f}")
|
|
print(f" Price: ${entry_signal.price:.2f}")
|
|
print(f" Metadata: {entry_signal.metadata}")
|
|
# execute_buy_order(entry_signal)
|
|
|
|
# Process exit signals
|
|
if exit_signal.signal_type == "EXIT":
|
|
print(f"🔴 EXIT Signal - Confidence: {exit_signal.confidence:.2f}")
|
|
print(f" Price: ${exit_signal.price:.2f}")
|
|
print(f" Metadata: {exit_signal.metadata}")
|
|
# execute_sell_order(exit_signal)
|
|
|
|
# Monitor strategy state
|
|
if strategy.is_warmed_up:
|
|
state = strategy.get_current_state_summary()
|
|
print(f"Strategy State: {state}")
|
|
```
|
|
|
|
### Integration with Trading System
|
|
|
|
```python
|
|
class LiveTradingSystem:
|
|
def __init__(self):
|
|
self.strategy = IncRandomStrategy(
|
|
weight=1.0,
|
|
params={
|
|
"entry_probability": 0.08,
|
|
"exit_probability": 0.12,
|
|
"min_confidence": 0.75,
|
|
"max_confidence": 0.95,
|
|
"timeframe": "15min",
|
|
"random_seed": None # True randomness for live trading
|
|
}
|
|
)
|
|
self.position = None
|
|
self.orders = []
|
|
|
|
def process_market_data(self, timestamp, ohlcv_data):
|
|
"""Process incoming market data"""
|
|
# Update strategy with new data
|
|
result = self.strategy.update_minute_data(timestamp, ohlcv_data)
|
|
|
|
if result is not None: # Complete timeframe bar
|
|
self._check_signals()
|
|
|
|
def _check_signals(self):
|
|
"""Check for trading signals"""
|
|
entry_signal = self.strategy.get_entry_signal()
|
|
exit_signal = self.strategy.get_exit_signal()
|
|
|
|
# Handle entry signals
|
|
if entry_signal.signal_type == "ENTRY" and self.position is None:
|
|
self._execute_entry(entry_signal)
|
|
|
|
# Handle exit signals
|
|
if exit_signal.signal_type == "EXIT" and self.position is not None:
|
|
self._execute_exit(exit_signal)
|
|
|
|
def _execute_entry(self, signal):
|
|
"""Execute entry order"""
|
|
order = {
|
|
'type': 'BUY',
|
|
'price': signal.price,
|
|
'confidence': signal.confidence,
|
|
'timestamp': signal.metadata.get('timestamp'),
|
|
'strategy': 'random'
|
|
}
|
|
|
|
print(f"Executing BUY order: {order}")
|
|
self.orders.append(order)
|
|
self.position = order
|
|
|
|
def _execute_exit(self, signal):
|
|
"""Execute exit order"""
|
|
if self.position:
|
|
order = {
|
|
'type': 'SELL',
|
|
'price': signal.price,
|
|
'confidence': signal.confidence,
|
|
'timestamp': signal.metadata.get('timestamp'),
|
|
'entry_price': self.position['price'],
|
|
'pnl': signal.price - self.position['price']
|
|
}
|
|
|
|
print(f"Executing SELL order: {order}")
|
|
self.orders.append(order)
|
|
self.position = None
|
|
|
|
# Usage
|
|
trading_system = LiveTradingSystem()
|
|
|
|
# Connect to live data feed
|
|
for market_tick in live_market_feed:
|
|
trading_system.process_market_data(
|
|
timestamp=market_tick['timestamp'],
|
|
ohlcv_data=market_tick
|
|
)
|
|
```
|
|
|
|
### Backtesting Example
|
|
|
|
```python
|
|
import pandas as pd
|
|
|
|
def backtest_random_strategy(historical_data):
|
|
"""Backtest RandomStrategy on historical data"""
|
|
|
|
strategy = IncRandomStrategy(
|
|
weight=1.0,
|
|
params={
|
|
"entry_probability": 0.05,
|
|
"exit_probability": 0.08,
|
|
"min_confidence": 0.8,
|
|
"max_confidence": 0.95,
|
|
"timeframe": "1h",
|
|
"random_seed": 123 # Reproducible results
|
|
}
|
|
)
|
|
|
|
signals = []
|
|
positions = []
|
|
current_position = None
|
|
|
|
# Process historical data
|
|
for timestamp, row in historical_data.iterrows():
|
|
ohlcv_data = {
|
|
'open': row['open'],
|
|
'high': row['high'],
|
|
'low': row['low'],
|
|
'close': row['close'],
|
|
'volume': row['volume']
|
|
}
|
|
|
|
# Update strategy (assuming data is already in target timeframe)
|
|
result = strategy.update_minute_data(timestamp, ohlcv_data)
|
|
|
|
if result is not None and strategy.is_warmed_up:
|
|
entry_signal = strategy.get_entry_signal()
|
|
exit_signal = strategy.get_exit_signal()
|
|
|
|
# Record signals
|
|
if entry_signal.signal_type == "ENTRY":
|
|
signals.append({
|
|
'timestamp': timestamp,
|
|
'type': 'ENTRY',
|
|
'price': entry_signal.price,
|
|
'confidence': entry_signal.confidence
|
|
})
|
|
|
|
if current_position is None:
|
|
current_position = {
|
|
'entry_time': timestamp,
|
|
'entry_price': entry_signal.price,
|
|
'confidence': entry_signal.confidence
|
|
}
|
|
|
|
if exit_signal.signal_type == "EXIT" and current_position:
|
|
signals.append({
|
|
'timestamp': timestamp,
|
|
'type': 'EXIT',
|
|
'price': exit_signal.price,
|
|
'confidence': exit_signal.confidence
|
|
})
|
|
|
|
# Close position
|
|
pnl = exit_signal.price - current_position['entry_price']
|
|
positions.append({
|
|
'entry_time': current_position['entry_time'],
|
|
'exit_time': timestamp,
|
|
'entry_price': current_position['entry_price'],
|
|
'exit_price': exit_signal.price,
|
|
'pnl': pnl,
|
|
'duration': timestamp - current_position['entry_time']
|
|
})
|
|
current_position = None
|
|
|
|
return pd.DataFrame(signals), pd.DataFrame(positions)
|
|
|
|
# Run backtest
|
|
# historical_data = pd.read_csv('historical_data.csv', index_col='timestamp', parse_dates=True)
|
|
# signals_df, positions_df = backtest_random_strategy(historical_data)
|
|
# print(f"Generated {len(signals_df)} signals and {len(positions_df)} completed trades")
|
|
```
|
|
|
|
## Performance Characteristics
|
|
|
|
### Timing Benchmarks
|
|
- **Update Time**: ~0.006ms per data point
|
|
- **Signal Generation**: ~0.048ms per signal
|
|
- **Memory Usage**: <1MB constant
|
|
- **Throughput**: >100,000 updates/second
|
|
|
|
## Testing and Validation
|
|
|
|
### Unit Tests
|
|
```python
|
|
def test_random_strategy():
|
|
"""Test RandomStrategy functionality"""
|
|
strategy = IncRandomStrategy(
|
|
params={
|
|
"entry_probability": 1.0, # Always generate signals
|
|
"exit_probability": 1.0,
|
|
"random_seed": 42
|
|
}
|
|
)
|
|
|
|
# Test data
|
|
test_data = {
|
|
'open': 100.0,
|
|
'high': 101.0,
|
|
'low': 99.0,
|
|
'close': 100.5,
|
|
'volume': 1000
|
|
}
|
|
|
|
timestamp = pd.Timestamp('2024-01-01 10:00:00')
|
|
|
|
# Process data
|
|
result = strategy.update_minute_data(timestamp, test_data)
|
|
|
|
# Verify signals
|
|
entry_signal = strategy.get_entry_signal()
|
|
exit_signal = strategy.get_exit_signal()
|
|
|
|
assert entry_signal.signal_type == "ENTRY"
|
|
assert exit_signal.signal_type == "EXIT"
|
|
assert 0.6 <= entry_signal.confidence <= 0.9
|
|
assert 0.6 <= exit_signal.confidence <= 0.9
|
|
|
|
# Run test
|
|
test_random_strategy()
|
|
print("✅ RandomStrategy tests passed")
|
|
```
|
|
|
|
## Use Cases
|
|
|
|
1. **Framework Testing**: Validate incremental strategy system
|
|
2. **Performance Benchmarking**: Baseline for strategy comparison
|
|
3. **Signal Pipeline Testing**: Test signal processing and execution
|
|
4. **Load Testing**: High-frequency signal generation testing
|
|
5. **Integration Testing**: Verify trading system integration |