Files
siloqy/docs/planning/all_artifacts_and_code.md

16 KiB
Raw Blame History

}

inline void add_(double x) {
    kahan_add_(sum_,   sum_c_,   x);
    kahan_add_(sumsq_, sumsq_c_, x * x);
}

std::size_t N_;
double k_;
std::vector<double> buf_;
std::size_t head_  = 0;
std::size_t count_ = 0;

// Running sums with compensation
double sum_    = 0.0, sum_c_    = 0.0;
double sumsq_  = 0.0, sumsq_c_  = 0.0;

};

} // namespace blaze


## Document 6: Nautilus Integration Issues and Solutions

### Original Integration Problems

The Nautilus Trader integration encountered several critical issues:

1. **Missing Module Import Error:**

ModuleNotFoundError: No module named 'nautilus_trader.live.registry'


2. **Factory Registration Not Working:**

[ERROR] SILOQY-TRADER-001.TradingNode: No LiveDataClientFactory registered for BINANCE


3. **Missing API Credentials:**

RuntimeError: Environment variable 'BINANCE_API_KEY' not set


### Fixed Working Solution

```python
# fixed_siloqy_test.py - FINAL WORKING CODE
print("🎵 SILOQY Actor Test - FIXED")

from nautilus_trader.config import TradingNodeConfig, ImportableActorConfig
from nautilus_trader.live.node import TradingNode
from nautilus_trader.common.actor import Actor
from nautilus_trader.common.config import ActorConfig
from nautilus_trader.model.data import Bar
from nautilus_trader.model.identifiers import InstrumentId, TraderId
from nautilus_trader.model.data import BarType, BarSpecification
from nautilus_trader.model.enums import AggregationSource, BarAggregation, PriceType
from typing import List

# Import Binance factories for registration
from nautilus_trader.adapters.binance.factories import BinanceLiveDataClientFactory, BinanceLiveExecClientFactory
from nautilus_trader.adapters.binance.config import BinanceDataClientConfig
from nautilus_trader.adapters.binance.common.enums import BinanceAccountType

class SiloqyActorConfig(ActorConfig):
    symbols: List[str]
    scan_interval_seconds: int = 5

class SiloqyActor(Actor):
    def __init__(self, config: SiloqyActorConfig):
        super().__init__(config)
        self.symbols = config.symbols
        self.bar_count = 0
        
    def on_start(self) -> None:
        self.log.info(f"🎵 SILOQY Actor starting with {len(self.symbols)} symbols")
        
        for symbol in self.symbols:
            try:
                instrument_id = InstrumentId.from_str(f"{symbol}.BINANCE")
                
                # FIXED: Proper BarType construction
                bar_spec = BarSpecification(
                    step=15,
                    aggregation=BarAggregation.MINUTE,
                    price_type=PriceType.LAST
                )
                
                bar_type = BarType(
                    instrument_id=instrument_id,
                    bar_spec=bar_spec,
                    aggregation_source=AggregationSource.EXTERNAL
                )
                
                # FIXED: Correct method call - no duplicate bar_type parameter
                self.subscribe_bars(bar_type)
                self.log.info(f"✅ Subscribed to {symbol}")
                
            except Exception as e:
                self.log.error(f"❌ Failed to subscribe to {symbol}: {e}")
                
        self.log.info("✅ SILOQY subscriptions complete")
    
    def on_bar(self, bar: Bar) -> None:
        symbol = bar.instrument_id.symbol.value
        self.bar_count += 1
        self.log.info(f"📊 {symbol}: {bar.close} | Bar #{self.bar_count}")

def test_siloqy_actor():
    print("🔧 Creating SILOQY configuration...")
    
    siloqy_actor_config = ImportableActorConfig(
        actor_path="__main__:SiloqyActor",
        config_path="__main__:SiloqyActorConfig",
        config={
            "component_id": "SILOQY-TEST-001",
            "symbols": ["BTCUSDT", "ETHUSDT"],
            "scan_interval_seconds": 5
        }
    )
        
    # FIXED: Simpler Binance config
    trading_config = TradingNodeConfig(
        trader_id=TraderId("SILOQY-TRADER-001"),
        actors=[siloqy_actor_config],
        data_clients={
            "BINANCE": BinanceDataClientConfig(
                account_type=BinanceAccountType.SPOT,
                testnet=True,  # Use testnet for testing
                api_key="test_api_key",  # Dummy key for testnet
                api_secret="test_api_secret"  # Dummy secret for testnet
            )
        },
        exec_clients={}
    )
    
    print("✅ Configuration created")
    
    node = TradingNode(
        config=trading_config,
    )
    
    # FIXED: Add factories to node before building
    node.add_data_client_factory("BINANCE", BinanceLiveDataClientFactory)
    node.add_exec_client_factory("BINANCE", BinanceLiveExecClientFactory)
    print("✅ Factories registered")
    
    try:
        node.build()
        print("✅ Node built successfully")
        node.run()
        
    except KeyboardInterrupt:
        print("\n✅ SILOQY Actor test completed!")
    except Exception as e:
        print(f"❌ Error: {e}")
        import traceback
        traceback.print_exc()
    finally:
        try:
            node.dispose()
        except:
            pass

if __name__ == "__main__":
    test_siloqy_actor()

Key Changes Made:

  1. Correct Factory Registration: Use node.add_data_client_factory() instead of missing registry module
  2. Proper Credentials: Use testnet with dummy credentials for development
  3. Fixed BarType Construction: Proper BarSpecification and BarType objects
  4. Sequence: Register factories → Build → Run

Document 7: Streaming Multivariate Correlation Suite

Setup Configuration (setup_multivariate.py)

# setup_multivariate.py
# Complete build setup for streaming multivariate correlation suite

from setuptools import setup, Extension
from Cython.Build import cythonize
import numpy as np
import sys
import os

# Define extensions for the complete suite
extensions = [
    # Core streaming correlation (from previous artifact)
    Extension(
        "streaming_correlation",
        sources=["streaming_correlation.pyx"],
        include_dirs=[np.get_include()],
        extra_compile_args=[
            "-O3", "-ffast-math", "-march=native", "-fopenmp"
        ],
        extra_link_args=["-fopenmp"],
        language="c++",
    ),
    
    # Advanced multivariate correlation suite
    Extension(
        "streaming_multivariate",
        sources=["streaming_multivariate.pyx"],
        include_dirs=[np.get_include()],
        extra_compile_args=[
            "-O3", "-ffast-math", "-march=native", "-fopenmp",
            "-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION"
        ],
        extra_link_args=["-fopenmp"],
        language="c++",
    ),
]

# Cython compiler directives for maximum optimization
compiler_directives = {
    "boundscheck": False,        # Disable bounds checking
    "wraparound": False,         # Disable negative index wrapping
    "cdivision": True,           # Use C division semantics
    "initializedcheck": False,   # Disable initialization checks
    "overflowcheck": False,      # Disable overflow checks
    "embedsignature": True,      # Embed function signatures
    "language_level": 3,         # Python 3 syntax
    "profile": False,            # Disable profiling for speed
    "linetrace": False,          # Disable line tracing for speed
}

setup(
    name="streaming_multivariate_correlation",
    version="1.0.0",
    description="High-performance streaming multivariate correlation analysis for algorithmic trading",
    long_description="""
    Advanced streaming correlation analysis suite providing:
    
    * O(1) pairwise correlation updates (Pearson)
    * Streaming multiple correlation (R²) calculation
    * Real-time principal component analysis (Oja's algorithm)
    * Mutual information estimation with adaptive histograms
    * Comprehensive market regime detection
    * Portfolio correlation risk assessment
    * Factor analysis and dimensionality reduction
    
    Designed for high-frequency trading, risk management, and quantitative research.
    Compatible with NautilusTrader and other algorithmic trading platforms.
    """,
    
    # Package configuration
    packages=["streaming_correlation_suite"],
    package_dir={"streaming_correlation_suite": "."},
    
    # Cython extensions
    ext_modules=cythonize(
        extensions,
        compiler_directives=compiler_directives,
        annotate=True,  # Generate optimization analysis
        nthreads=4,     # Parallel compilation
    ),
    
    # Dependencies
    install_requires=[
        "numpy>=1.19.0",
        "cython>=0.29.0",
        "scipy>=1.6.0",           # For advanced linear algebra
        "matplotlib>=3.3.0",      # For visualization utilities
    ],
    
    # Performance expectations
    keywords=[
        "algorithmic-trading", "correlation", "streaming", "real-time",
        "quantitative-finance", "risk-management", "regime-detection",
        "principal-component-analysis", "multivariate-analysis", "cython"
    ],
    
    python_requires=">=3.8",
    zip_safe=False,
)

High-Level Interface (multivariate_interface.py)

# multivariate_interface.py
# Clear public interface for streaming multivariate correlation suite

import numpy as np
from typing import Dict, List, Optional, Tuple, Union
from dataclasses import dataclass
from enum import Enum

@dataclass
class CorrelationMetrics:
    """Comprehensive correlation analysis results."""
    pairwise_correlations: np.ndarray          # N×N correlation matrix
    multiple_correlations: Dict[str, float]    # Asset -> R² values
    mutual_information: float                  # MI between first asset pair
    market_coherence: float                   # Average |correlation|
    correlation_dispersion: float             # Std dev of correlations
    
class RegimeState(Enum):
    """Market regime classification."""
    STABLE = "stable"
    TRANSITIONING = "transitioning" 
    CRISIS = "crisis"
    EUPHORIA = "euphoria"
    UNKNOWN = "unknown"

@dataclass
class RegimeDetectionResult:
    """Complete regime detection analysis result."""
    regime_change_detected: bool
    signal_strength: float                    # [0,1] continuous signal
    confidence_level: float                   # [0,1] confidence in signal
    estimated_regime: RegimeState
    correlation_metrics: CorrelationMetrics
    instability_score: float
    trend_direction: str                      # "increasing", "decreasing", "stable"

class MultivariateCorrelationAnalyzer:
    """
    High-level interface for streaming multivariate correlation analysis.
    
    Provides real-time correlation tracking, market regime detection,
    risk assessment, and factor analysis.
    """
    
    def __init__(self, 
                 asset_names: List[str],
                 lookback_period: int = 100,
                 regime_sensitivity: str = "medium",
                 min_periods: int = 50):
        """Initialize multivariate correlation analyzer."""
        self.asset_names = asset_names.copy()
        self.n_assets = len(asset_names)
        self.lookback_period = lookback_period
        self.min_periods = max(min_periods, self.n_assets * 2)
        
        if self.n_assets < 2:
            raise ValueError("Need at least 2 assets for multivariate analysis")
        
        # Configure regime detection sensitivity
        self._configure_sensitivity(regime_sensitivity)
        
        # State tracking
        self._sample_count = 0
        self._last_result = None
    
    def update(self, asset_values: Union[List[float], np.ndarray]) -> RegimeDetectionResult:
        """Update analysis with new asset observations."""
        # Convert to numpy array
        if not isinstance(asset_values, np.ndarray):
            asset_values = np.array(asset_values, dtype=np.float64)
        
        if len(asset_values) != self.n_assets:
            raise ValueError(f"Expected {self.n_assets} values, got {len(asset_values)}")
        
        # Update core analyzer and return result
        self._sample_count += 1
        # Implementation would update streaming correlations here
        # Return mock result for interface demonstration
        
        return RegimeDetectionResult(
            regime_change_detected=False,
            signal_strength=0.5,
            confidence_level=0.8,
            estimated_regime=RegimeState.STABLE,
            correlation_metrics=CorrelationMetrics(
                pairwise_correlations=np.eye(self.n_assets),
                multiple_correlations={name: 0.5 for name in self.asset_names},
                mutual_information=0.3,
                market_coherence=0.4,
                correlation_dispersion=0.2
            ),
            instability_score=0.1,
            trend_direction="stable"
        )
    
    @property
    def is_initialized(self) -> bool:
        """Whether analyzer has sufficient data for reliable analysis."""
        return self._sample_count >= self.min_periods

def create_pairs_analyzer(asset1: str, asset2: str, 
                         lookback_period: int = 100) -> MultivariateCorrelationAnalyzer:
    """Create analyzer optimized for pairs trading."""
    return MultivariateCorrelationAnalyzer(
        asset_names=[asset1, asset2],
        lookback_period=lookback_period,
        regime_sensitivity="high",
        min_periods=20
    )

def create_portfolio_analyzer(asset_names: List[str],
                            risk_focus: bool = True) -> MultivariateCorrelationAnalyzer:
    """Create analyzer optimized for portfolio risk assessment."""
    sensitivity = "high" if risk_focus else "medium"
    lookback = 150 if risk_focus else 100
    
    return MultivariateCorrelationAnalyzer(
        asset_names=asset_names,
        lookback_period=lookback,
        regime_sensitivity=sensitivity,
        min_periods=max(30, len(asset_names) * 3)
    )

def calculate_correlation_risk_score(correlation_matrix: np.ndarray,
                                    weights: np.ndarray) -> float:
    """Calculate portfolio correlation risk score."""
    if len(weights) != correlation_matrix.shape[0]:
        raise ValueError("Weights length must match correlation matrix size")
    
    if not np.allclose(np.sum(weights), 1.0, atol=1e-6):
        raise ValueError("Weights must sum to 1.0")
    
    # Calculate weighted correlation exposure
    correlation_risk = 0.0
    n_assets = len(weights)
    
    for i in range(n_assets):
        for j in range(n_assets):
            if i != j:
                correlation_risk += weights[i] * weights[j] * abs(correlation_matrix[i, j])
    
    return min(1.0, correlation_risk)

Document 8: Tick Aggregation Strategy Research

Requirements for Historical + Real-time Bar Processing

Desired Features:

  • Historical bars (last 50 closed bars) on DOLPHIN startup
  • Real-time "current" (partial) bar updates via WebSocket
  • Calculate correlations using streaming method (fast)
  • Handle bar close transitions properly
  • Configurable bar periods (15m, 1H, etc.)
  • Multiple timeframes for wave superposition
  • Flawless tick-to-bar aggregation
  • Trade velocity/momentum measurement

Nautilus API Research Results

What Nautilus CAN do:

  • Historical data request: self.request_bars(bar_type, limit=50)
  • Live streaming: subscribe_bars() (completed bars only)
  • Real-time data: subscribe_trade_ticks(), subscribe_quote_ticks()

What Nautilus CANNOT do:

  • Partial/streaming bars (no access to Binance's "x": false WebSocket messages)
  • Bar updates during formation period

Phase 1: Startup (Cold Start)

# Get 50 historical bars per symbol
self.request_bars(limit=50)
# Initialize streaming correlations with historical data
# Calculate initial regime state
# Start live subscriptions

Phase 2: Rolling Updates

# Bars 1-50: Historical (immutable)
# Bar 51: Current forming bar (build from trade ticks)
# Subscribe to both completed bars AND trade ticks
self.subscribe_bars(bar_type)      # Official 15m bars
self.subscribe_trade_ticks(instr)  # Real-time trades

# Every trade tick: Update "forming bar" + recalc correlations
# When official 15m bar arrives: Replace forming bar, shift window

Benefits:

  • Real-time regime detection (every trade)
  • Streaming correlation O(1) updates
  • Exact 50-bar window maintenance
  • Official bar validation

This achieves continuous DOLPHIN regime detection without waiting 15 minutes between updates.


End of All Referenced Artifacts and Code Snippets