initial: import DOLPHIN baseline 2026-04-21 from dolphinng5_predict working tree
Includes core prod + GREEN/BLUE subsystems: - prod/ (BLUE harness, configs, scripts, docs) - nautilus_dolphin/ (GREEN Nautilus-native impl + dvae/ preserved) - adaptive_exit/ (AEM engine + models/bucket_assignments.pkl) - Observability/ (EsoF advisor, TUI, dashboards) - external_factors/ (EsoF producer) - mc_forewarning_qlabs_fork/ (MC regime/envelope) Excludes runtime caches, logs, backups, and reproducible artifacts per .gitignore.
This commit is contained in:
293
nautilus_dolphin/CRITICAL_PRICE_UPDATE.md
Executable file
293
nautilus_dolphin/CRITICAL_PRICE_UPDATE.md
Executable file
@@ -0,0 +1,293 @@
|
||||
# CRITICAL UPDATE: Actual Price Data Integration
|
||||
|
||||
**Date**: 2026-02-18
|
||||
**Status**: COMPLETE
|
||||
**Priority**: CRITICAL
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The eigenvalue JSON files **DO contain actual price data** in `pricing_data.current_prices`. The system has been updated to use these **REAL prices** instead of synthetic/generated prices.
|
||||
|
||||
---
|
||||
|
||||
## Price Data Structure in JSON Files
|
||||
|
||||
```json
|
||||
{
|
||||
"scan_number": 22284,
|
||||
"timestamp": "2026-01-01T16:00:05.291658",
|
||||
"windows": { ... },
|
||||
"pricing_data": {
|
||||
"current_prices": {
|
||||
"BTCUSDT": 87967.06,
|
||||
"ETHUSDT": 2985.16,
|
||||
"BNBUSDT": 857.94,
|
||||
...
|
||||
},
|
||||
"price_changes": {
|
||||
"BTCUSDT": 1.1367892858475202e-05,
|
||||
...
|
||||
},
|
||||
"volatility": {
|
||||
"BTCUSDT": 0.04329507905570856,
|
||||
...
|
||||
},
|
||||
"per_asset_correlation": { ... }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### 1. `nautilus/data_adapter.py`
|
||||
|
||||
**Changes**:
|
||||
- Added `_extract_prices()` method to get actual prices from `pricing_data.current_prices`
|
||||
- Added `_extract_price_changes()` method
|
||||
- Added `_extract_volatility()` method
|
||||
- Added `_extract_regime_data()` method for regime signals
|
||||
- Updated `generate_bars()` to use **ACTUAL prices** instead of synthetic
|
||||
- Updated `get_signal_metadata()` to include actual price in signals
|
||||
- Updated metadata to indicate `price_source: 'actual_from_json'`
|
||||
|
||||
**Key Code**:
|
||||
```python
|
||||
def _extract_prices(self, data: dict) -> Dict[str, float]:
|
||||
"""Extract ACTUAL current prices from scan data."""
|
||||
prices = {}
|
||||
pricing_data = data.get('pricing_data', {})
|
||||
current_prices = pricing_data.get('current_prices', {})
|
||||
|
||||
for asset, price in current_prices.items():
|
||||
if isinstance(price, (int, float)):
|
||||
prices[asset] = float(price)
|
||||
return prices
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. `signal_generator/generator.py`
|
||||
|
||||
**Changes**:
|
||||
- Added `_extract_prices()` method using actual price data
|
||||
- Updated `_extract_vel_div()` to compute from window tracking data
|
||||
- Added `_extract_volatility()` method
|
||||
- Added `_extract_price_changes()` method
|
||||
- Updated `_generate_signals_from_scan()` to include actual price in signals
|
||||
|
||||
**Key Code**:
|
||||
```python
|
||||
def _generate_signals_from_scan(self, scan_data: Dict) -> List[Dict]:
|
||||
# Get ACTUAL prices and vel_div
|
||||
prices = self._extract_prices(scan_data)
|
||||
vel_div_data = self._extract_vel_div(scan_data)
|
||||
|
||||
for asset, vel_div in vel_div_data.items():
|
||||
if vel_div < self.VEL_DIV_THRESHOLD:
|
||||
price = prices.get(asset, 0.0) # ACTUAL price
|
||||
|
||||
signal = {
|
||||
'timestamp': timestamp,
|
||||
'asset': asset,
|
||||
'direction': self.SIGNAL_DIRECTION,
|
||||
'vel_div': vel_div,
|
||||
'strength': strength,
|
||||
'price': price, # ACTUAL price from JSON
|
||||
'volatility': vol,
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. `signal_generator/enricher.py`
|
||||
|
||||
**Changes**:
|
||||
- Added `_extract_price_data()` method to get actual price, price_change, volatility
|
||||
- Updated `_compute_direction_confirm()` to use **actual price changes** from `pricing_data.price_changes`
|
||||
- Added momentum threshold check (0.75bps)
|
||||
- Updated `enrich()` to use actual price data for direction confirmation
|
||||
|
||||
**Key Code**:
|
||||
```python
|
||||
def _extract_price_data(self, scan_data: Dict, asset: str) -> Dict[str, Any]:
|
||||
"""Extract ACTUAL price data for asset."""
|
||||
pricing_data = scan_data.get('pricing_data', {})
|
||||
return {
|
||||
'price': pricing_data.get('current_prices', {}).get(asset, 0.0),
|
||||
'price_change': pricing_data.get('price_changes', {}).get(asset, 0.0),
|
||||
'volatility': pricing_data.get('volatility', {}).get(asset, 0.1),
|
||||
}
|
||||
|
||||
def _compute_direction_confirm(self, signal, price_data, asset_data) -> bool:
|
||||
"""Compute direction confirmation using ACTUAL price changes."""
|
||||
price_change = price_data.get('price_change', 0.0)
|
||||
change_bps = abs(price_change) * 10000
|
||||
|
||||
if change_bps < self.MOMENTUM_THRESHOLD_BPS: # 0.75bps
|
||||
return False
|
||||
|
||||
if signal['direction'] == 'SHORT':
|
||||
return price_change < 0
|
||||
else:
|
||||
return price_change > 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. `nautilus/strategy.py`
|
||||
|
||||
**Changes**:
|
||||
- Updated `_execute_entry()` to use **actual price from signal** when available
|
||||
- Falls back to quote tick only for live trading
|
||||
- Logs price source for transparency
|
||||
|
||||
**Key Code**:
|
||||
```python
|
||||
def _execute_entry(self, signal_data: dict):
|
||||
# Get price: Use ACTUAL price from signal (validation) or quote (live)
|
||||
signal_price = signal_data.get('price')
|
||||
if signal_price and signal_price > 0:
|
||||
price = float(signal_price)
|
||||
price_source = "signal" # ACTUAL from eigenvalue JSON
|
||||
else:
|
||||
quote = self.cache.quote_tick(instrument_id)
|
||||
price = float(quote.bid if direction == 'SHORT' else quote.ask)
|
||||
price_source = "quote" # Live market data
|
||||
|
||||
self.log.info(
|
||||
f"Entry order: {asset} {direction}, price=${price:.2f} "
|
||||
f"(source: {price_source})"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Impact
|
||||
|
||||
### Before (Synthetic Prices)
|
||||
```python
|
||||
# Generated synthetic prices from vel_div
|
||||
drift = -vel_div_value * 0.01
|
||||
noise = random.gauss(0, abs(vel_div_value) * 0.005)
|
||||
price = base_price * (1 + drift + noise) # SYNTHETIC!
|
||||
```
|
||||
|
||||
### After (Actual Prices)
|
||||
```python
|
||||
# Extract ACTUAL prices from JSON
|
||||
prices = pricing_data.get('current_prices', {})
|
||||
price = prices.get('BTCUSDT') # 87967.06 - ACTUAL!
|
||||
```
|
||||
|
||||
### Benefits
|
||||
1. **Accurate Validation**: VBT and Nautilus use identical prices
|
||||
2. **Real P&L Calculation**: Based on actual market prices
|
||||
3. **Proper Slippage**: Measured against real prices
|
||||
4. **Faithful Backtests**: Reflects actual historical conditions
|
||||
|
||||
---
|
||||
|
||||
## Price Flow Architecture
|
||||
|
||||
```
|
||||
eigenvalue JSON
|
||||
├── pricing_data.current_prices ──────┐
|
||||
├── pricing_data.price_changes ───────┤
|
||||
└── pricing_data.volatility ──────────┤
|
||||
▼
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ SignalGenerator │
|
||||
│ - _extract_prices() → ACTUAL prices │
|
||||
│ - _extract_vel_div() → velocity divergence │
|
||||
│ - signal['price'] = actual_price │
|
||||
└────────────────────┬────────────────────────────┘
|
||||
│ signal with ACTUAL price
|
||||
▼
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ RedisSignalPublisher │
|
||||
│ - Publish signal with price │
|
||||
└────────────────────┬────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ SignalBridgeActor │
|
||||
│ - Consume from Redis │
|
||||
│ - Publish to Nautilus bus │
|
||||
└────────────────────┬────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ DolphinExecutionStrategy │
|
||||
│ - signal_data['price'] → ACTUAL price │
|
||||
│ - Use for position sizing & order entry │
|
||||
│ - Fallback to quote only if no signal price │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- [x] Data adapter extracts actual prices from JSON
|
||||
- [x] Signal generator includes actual price in signals
|
||||
- [x] Enricher uses actual price changes for direction confirmation
|
||||
- [x] Strategy uses signal price (actual) when available
|
||||
- [x] OHLC bars constructed from actual prices
|
||||
- [x] Trade P&L calculated from actual prices
|
||||
- [x] Comparator validates entry/exit prices within 0.1%
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
### Unit Test
|
||||
```python
|
||||
def test_actual_price_extraction():
|
||||
adapter = JSONEigenvalueDataAdapter(eigenvalues_dir)
|
||||
scan_data = adapter.load_scan_file(sample_file)
|
||||
|
||||
prices = adapter._extract_prices(scan_data)
|
||||
assert 'BTCUSDT' in prices
|
||||
assert prices['BTCUSDT'] > 0 # Actual price, not synthetic
|
||||
assert isinstance(prices['BTCUSDT'], float)
|
||||
```
|
||||
|
||||
### Integration Test
|
||||
```python
|
||||
def test_signal_contains_actual_price():
|
||||
generator = SignalGenerator(eigenvalues_dir)
|
||||
scan_data = generator._load_scan_file(sample_file)
|
||||
signals = generator._generate_signals_from_scan(scan_data)
|
||||
|
||||
for signal in signals:
|
||||
assert 'price' in signal
|
||||
assert signal['price'] > 0 # ACTUAL price
|
||||
assert signal['price_source'] == 'actual_json'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migration Notes
|
||||
|
||||
For existing deployments:
|
||||
1. No configuration changes required
|
||||
2. Price source automatically detected (signal vs quote)
|
||||
3. Backward compatible - falls back to quotes if no signal price
|
||||
|
||||
---
|
||||
|
||||
## Documentation Updates
|
||||
|
||||
- [x] `data_adapter.py` - Docstrings updated
|
||||
- [x] `generator.py` - Comments added
|
||||
- [x] `enricher.py` - Documentation updated
|
||||
- [x] `strategy.py` - Logging includes price source
|
||||
- [x] This document created
|
||||
|
||||
---
|
||||
|
||||
**CRITICAL**: Both VBT and Nautilus now use **identical actual prices** from `pricing_data.current_prices`, ensuring accurate validation comparison.
|
||||
Reference in New Issue
Block a user