Skip to content

AlgoGators/trade-ngin

Repository files navigation

trade-ngin

Build Status C++ License: GPL v3

πŸ“– Project Overview

trade-ngin is a high-performance, modular quantitative trading system built in C++ designed for professional algorithmic traders and financial institutions. The system supports systematic trading strategies across multiple asset classes with a focus on futures, equities, and options markets.

Core Capabilities

  • Multi-strategy portfolio management with dynamic capital allocation
  • Comprehensive risk management with position limits, drawdown control, and VaR constraints
  • High-performance backtesting engine with realistic execution simulation
  • Transaction cost analysis for strategy optimization
  • Modular architecture designed for extensibility and customization
  • Professional-grade performance with C++ efficiency

trade-ngin is designed to handle both backtesting and live trading seamlessly, with a unified codebase that maintains consistency between simulation and production environments.

πŸ“‚ Repository Structure & Organization

trade_ngin/
β”œβ”€β”€ apps/                       # Application executables
β”‚   β”œβ”€β”€ backtest/               # Backtesting applications
β”‚   β”‚   β”œβ”€β”€ bt_trend.cpp        # Trend following strategy backtest
β”‚   β”‚   └── CMakeLists.txt      # Build configuration for backtests
β”‚   └── CMakeLists.txt          # Build configuration for applications
β”œβ”€β”€ include/                    # Public header files
β”‚   └── trade_ngin/             # Main include directory
β”‚       β”œβ”€β”€ backtest/           # Backtesting components
β”‚       β”‚   β”œβ”€β”€ backtest_engine.hpp
β”‚       β”‚   β”œβ”€β”€ slippage_models.hpp
β”‚       β”‚   └── transaction_cost_analysis.hpp
β”‚       β”œβ”€β”€ core/               # Core system components
β”‚       β”‚   β”œβ”€β”€ config_base.hpp
β”‚       β”‚   β”œβ”€β”€ config_manager.hpp
β”‚       β”‚   β”œβ”€β”€ config_version.hpp
β”‚       β”‚   β”œβ”€β”€ error.hpp
β”‚       β”‚   β”œβ”€β”€ logger.hpp
β”‚       β”‚   β”œβ”€β”€ state_manager.hpp
β”‚       β”‚   └── types.hpp
β”‚       β”œβ”€β”€ data/               # Data management
β”‚       β”‚   β”œβ”€β”€ conversion_utils.hpp
β”‚       β”‚   β”œβ”€β”€ credential_store.hpp
β”‚       β”‚   β”œβ”€β”€ database_interface.hpp
β”‚       β”‚   β”œβ”€β”€ market_data_bus.hpp
β”‚       β”‚   └── postgres_database.hpp
β”‚       β”œβ”€β”€ execution/          # Order execution
β”‚       β”‚   └── execution_engine.hpp
β”‚       β”œβ”€β”€ instruments/        # Financial instruments
β”‚       β”‚   β”œβ”€β”€ equity.hpp
β”‚       β”‚   β”œβ”€β”€ futures.hpp
β”‚       β”‚   β”œβ”€β”€ instrument.hpp
β”‚       β”‚   └── option.hpp
β”‚       β”œβ”€β”€ optimization/       # Portfolio optimization
β”‚       β”‚   └── dynamic_optimizer.hpp
β”‚       β”œβ”€β”€ order/              # Order management
β”‚       β”‚   └── order_manager.hpp
β”‚       β”œβ”€β”€ portfolio/          # Portfolio management
β”‚       β”‚   └── portfolio_manager.hpp
β”‚       β”œβ”€β”€ risk/               # Risk management
β”‚       β”‚   └── risk_manager.hpp
β”‚       └── strategy/           # Strategy components
β”‚           β”œβ”€β”€ base_strategy.hpp
β”‚           β”œβ”€β”€ database_handler.hpp
β”‚           β”œβ”€β”€ regime_detector.hpp
β”‚           β”œβ”€β”€ strategy_interface.hpp
β”‚           β”œβ”€β”€ trend_following.hpp
β”‚           └── types.hpp
β”œβ”€β”€ src/                        # Implementation files
β”‚   β”œβ”€β”€ backtest/               # Backtesting implementations
β”‚   β”‚   β”œβ”€β”€ backtest_engine.cpp
β”‚   β”‚   β”œβ”€β”€ slippage_model.cpp
β”‚   β”‚   └── transaction_cost_analysis.cpp
β”‚   β”œβ”€β”€ core/                   # Core system implementations
β”‚   β”‚   β”œβ”€β”€ config_base.cpp
β”‚   β”‚   β”œβ”€β”€ config_manager.cpp
β”‚   β”‚   β”œβ”€β”€ config_version.cpp
β”‚   β”‚   β”œβ”€β”€ logger.cpp
β”‚   β”‚   └── state_manager.cpp
β”‚   β”œβ”€β”€ data/                   # Data management implementations
β”‚   β”‚   β”œβ”€β”€ conversion_utils.cpp
β”‚   β”‚   β”œβ”€β”€ credential_store.cpp
β”‚   β”‚   β”œβ”€β”€ market_data_bus.cpp
β”‚   β”‚   └── postgres_database.cpp
β”‚   β”œβ”€β”€ execution/              # Order execution implementations
β”‚   β”‚   └── execution_engine.cpp
β”‚   β”œβ”€β”€ instruments/            # Financial instruments implementations
β”‚   β”‚   β”œβ”€β”€ equity.cpp
β”‚   β”‚   β”œβ”€β”€ futures.cpp
β”‚   β”‚   └── option.cpp
β”‚   β”œβ”€β”€ optimization/           # Portfolio optimization implementations
β”‚   β”‚   └── dynamic_optimizer.cpp
β”‚   β”œβ”€β”€ order/                  # Order management implementations
β”‚   β”‚   └── order_manager.cpp
β”‚   β”œβ”€β”€ portfolio/              # Portfolio management implementations
β”‚   β”‚   └── portfolio_manager.cpp
β”‚   β”œβ”€β”€ risk/                   # Risk management implementations
β”‚   β”‚   └── risk_manager.cpp
β”‚   └── strategy/               # Strategy implementations
β”‚       β”œβ”€β”€ base_strategy.cpp
β”‚       β”œβ”€β”€ regime_detector.cpp
β”‚       └── trend_following.cpp
β”œβ”€β”€ tests/                      # Unit and integration tests
β”‚   β”œβ”€β”€ core/                   # Core component tests
β”‚   β”‚   β”œβ”€β”€ test_config_base.cpp
β”‚   β”‚   β”œβ”€β”€ test_config_manager.cpp
β”‚   β”‚   β”œβ”€β”€ test_config_version.cpp
β”‚   β”‚   β”œβ”€β”€ test_logger.cpp
β”‚   β”‚   β”œβ”€β”€ test_result.cpp
β”‚   β”‚   └── test_state_manager.cpp
β”‚   └── CMakeLists.txt          # Build configuration for tests
β”œβ”€β”€ CMakeLists.txt              # Main build configuration
└── config_template.json        # Template for configuration files

βš™οΈ System Architecture & Component Breakdown

trade-ngin follows a modular, component-based architecture with interfaces between system components. Here's a detailed breakdown of the major components:

Core System Components

Error Handling System (error.hpp)

  • Defines custom error codes via ErrorCode enum
  • Implements TradeError class extending std::runtime_error
  • Provides Result<T> template for error propagation throughout the system
  • Supports make_error<T>() for creating standardized error responses

Logging Framework (logger.hpp, logger.cpp)

  • Singleton implementation for system-wide logging
  • Configurable log levels (TRACE, DEBUG, INFO, WARNING, ERROR, FATAL)
  • Multiple output destinations (console, file, or both)
  • Automatic log rotation based on file size
  • Thread-safe implementation with mutex protection

State Management (state_manager.hpp, state_manager.cpp)

  • Tracks component states throughout the system
  • Supports state transitions with validation
  • Maintains component metrics and diagnostics
  • Enables system-wide health monitoring

Configuration Management

  • ConfigBase - Base class for serializable configurations
  • ConfigManager - Centralized configuration management
  • ConfigVersion - Version tracking and migration support
  • Environment-specific configuration overrides (dev, staging, prod, backtest)

Data Management Components

Database Interface

  • Abstract DatabaseInterface defining common database operations
  • PostgreSQL implementation via PostgresDatabase
  • Arrow-based data type support for efficient memory management
  • Query building and parameter sanitization

Market Data Bus

  • Publish-subscribe pattern for market data distribution
  • Event-based architecture with callback registration
  • Symbol and event type filtering
  • Thread-safe implementation

Data Conversion Utilities

  • Arrow table to/from domain objects conversion
  • Type-safe timestamp handling
  • Error handling with Result pattern

Financial Instruments

Instrument Interface

  • Abstract base class defining common instrument properties
  • Asset-specific implementations:
    • EquityInstrument - Stocks, ETFs
    • FuturesInstrument - Futures contracts
    • OptionInstrument - Options with Greeks calculation

Order Management

Order Manager

  • Order lifecycle management (creation, submission, cancellation)
  • Order book maintenance for status tracking
  • Validation and error handling
  • Commission calculation

Execution Engine

  • Algorithm-based order execution (TWAP, VWAP, PoV, etc.)
  • Execution metrics tracking and analysis
  • Position buffering to reduce unnecessary trading
  • Custom algorithm extensibility

Strategy Framework

Strategy Interface

  • Abstract interface for all trading strategies
  • Lifecycle management (init, start, stop, pause, resume)
  • Event handling (market data, executions, signals)
  • Position and risk management

Base Strategy

  • Common implementation of strategy interface
  • Position tracking and management
  • Signal generation and execution
  • Risk limit enforcement

Strategy Implementations

  • TrendFollowingStrategy - Multi-timeframe trend following using EMA crossovers
  • Extensible framework for adding new strategies
flowchart TD
    A[Receive market data] --> B{Enough history?}
    B -->|No| C[Store price in history]
    B -->|Yes| D[Calculate volatility]
    
    D --> E[Calculate EMA crossovers for multiple timeframes]
    E --> F[Generate raw forecasts]
    F --> G[Scale forecasts by volatility]
    G --> H[Combine forecasts with FDM]
    
    H --> I[Calculate position size based on volatility-targeting formula]
    I --> J{Use position buffering?}
    
    J -->|Yes| K[Apply position buffer to reduce trading]
    J -->|No| L[Use raw position]
    
    K --> M[Update position]
    L --> M
    
    M --> N[Emit position signal]
    
    subgraph Volatility Calculation
        D1[Calculate returns] --> D2[Calculate EWMA std deviation]
        D2 --> D3[Blend short and long-term volatility]
        D3 --> D4[Apply volatility regime multiplier]
    end
    
    D -.-> D1
    D4 -.-> D
    
    subgraph Position Sizing
        I1[Calculate target risk] --> I2[Apply IDM factor]
        I2 --> I3[Scale by forecast strength]
        I3 --> I4[Divide by price * volatility * point value]
    end
    
    I -.-> I1
    I4 -.-> I
Loading

Risk Management

  • Position-level and portfolio-level risk constraints
  • Value at Risk (VaR) calculation
  • Jump risk monitoring
  • Maximum drawdown limits
  • Leverage constraints
  • Correlation risk monitoring

Portfolio Management

  • Multi-strategy portfolio construction
  • Dynamic capital allocation
  • Position aggregation and netting
  • Portfolio-level optimizations and constraints

Backtesting Framework

Backtest Engine

  • Historical market data simulation
  • Event-driven architecture
  • Realistic execution modeling
  • Comprehensive performance metrics
  • Transaction cost analysis

Slippage Models

  • Volume-based slippage
  • Spread-based slippage
  • Custom slippage model extensibility

Transaction Cost Analysis

  • Execution quality evaluation
  • Implementation shortfall calculation
  • Benchmark comparison (VWAP, TWAP, arrival price)
  • Cost breakdown (spread, market impact, timing, delay)

Portfolio Optimization

Dynamic Optimizer

  • Position optimization considering transaction costs
  • Risk constraints enforcement
  • Tracking error minimization
  • Convex optimization techniques
classDiagram
    class ConfigBase {
        <<abstract>>
        +save_to_file(filepath) Result~void~
        +load_from_file(filepath) Result~void~
        +to_json() json
        +from_json(json) void
    }
    
    class StrategyConfig {
        +capital_allocation double
        +max_leverage double
        +position_limits map
        +max_drawdown double
        +trading_params map
        +to_json() json
        +from_json(json) void
    }
    
    class PortfolioConfig {
        +total_capital double
        +reserve_capital double
        +use_optimization bool
        +use_risk_management bool
        +to_json() json
        +from_json(json) void
    }

    class RiskConfig {
        +var_limit double
        +jump_risk_limit double
        +max_correlation double
        +to_json() json
        +from_json(json) void
    }
    
    class DynamicOptConfig {
        +tau double
        +capital double
        +max_iterations int
        +to_json() json
        +from_json(json) void
    }
    
    class BacktestConfig {
        +strategy_config StrategyConfig
        +portfolio_config PortfolioConfig
        +results_db_schema string
        +to_json() json
        +from_json(json) void
    }
    
    class DatabaseInterface {
        <<interface>>
        +connect() Result~void~
        +disconnect() void
        +is_connected() bool
        +get_market_data(...) Result~Table~
        +store_executions(...) Result~void~
        +store_positions(...) Result~void~
        +store_signals(...) Result~void~
        +get_symbols(...) Result~string[]~
    }
    
    class PostgresDatabase {
        -connection_string string
        -connection pqxx::connection
        +connect() Result~void~
        +disconnect() void
        +is_connected() bool
        +get_market_data(...) Result~Table~
    }
    
    class StrategyInterface {
        <<interface>>
        +initialize() Result~void~
        +start() Result~void~
        +stop() Result~void~
        +pause() Result~void~
        +resume() Result~void~
        +on_data(data) Result~void~
        +on_execution(report) Result~void~
        +on_signal(symbol, signal) Result~void~
        +get_positions() Position[]
    }
    
    class BaseStrategy {
        #id_ string
        #config_ StrategyConfig
        #positions_ map
        #state_ StrategyState
        +initialize() Result~void~
        +on_data(data) Result~void~
        +check_risk_limits() Result~void~
    }
    
    class TrendFollowingStrategy {
        -trend_config_ TrendFollowingConfig
        -price_history_ map
        -volatility_history_ map
        +on_data(data) Result~void~
        -calculate_ewma(...) vector~double~
        -get_raw_forecast(...) vector~double~
        -calculate_position(...) double
    }
    
    class Instrument {
        <<interface>>
        +get_symbol() string
        +get_type() AssetType
        +is_tradeable() bool
        +get_margin_requirement() double
        +round_price(price) double
    }
    
    class SlippageModel {
        <<interface>>
        +calculate_slippage(...) double
        +update(market_data) void
    }
    
    ConfigBase <|-- StrategyConfig
    ConfigBase <|-- PortfolioConfig
    ConfigBase <|-- RiskConfig
    ConfigBase <|-- DynamicOptConfig
    ConfigBase <|-- BacktestConfig
    
    DatabaseInterface <|-- PostgresDatabase
    
    StrategyInterface <|-- BaseStrategy
    BaseStrategy <|-- TrendFollowingStrategy
    
    SlippageModel <|-- VolumeSlippageModel
    SlippageModel <|-- SpreadSlippageModel
Loading

πŸ”„ Workflow & System Flow

Backtesting Workflow

  1. Initialization

    • Load configuration from files
    • Initialize database connection
    • Create strategy instances
    • Initialize portfolio manager
    • Configure risk management and optimization components
  2. Market Data Loading

    • Query historical data from database
    • Convert to internal Bar representation
    • Group data by timestamp for realistic simulation
  3. Strategy Processing

    • Feed market data to strategies chronologically
    • Generate trading signals based on strategy logic
    • Convert signals to position targets
  4. Portfolio-Level Processing

    • Aggregate positions across strategies
    • Apply risk management constraints
    • Apply position optimization if enabled
    • Calculate trade sizes based on current vs. target positions
  5. Order Execution Simulation

    • Apply slippage models to execution prices
    • Calculate transaction costs
    • Generate execution reports
    • Update positions based on fills
  6. Performance Tracking

    • Update equity curve
    • Calculate drawdowns
    • Track risk metrics over time
    • Record trade statistics
  7. Results Analysis

    • Calculate performance metrics (Sharpe, Sortino, etc.)
    • Analyze transaction costs
    • Generate visualizations and reports
    • Save results to database
sequenceDiagram
    participant User as User
    participant BE as BacktestEngine
    participant DB as Database
    participant PM as PortfolioManager
    participant SI as Strategy
    participant RM as RiskManager
    participant DO as DynamicOptimizer
    participant TCA as TCA

    User->>BE: run_portfolio()
    BE->>DB: load_market_data()
    DB-->>BE: historical market data
    
    loop For each timestamp
        BE->>PM: process_market_data(bars)
        PM->>SI: on_data(bars)
        SI-->>PM: target_positions
        
        opt If risk management enabled
            PM->>RM: process_positions(positions)
            RM-->>PM: risk_result
        end
        
        opt If optimization enabled
            PM->>DO: optimize_single_period(positions)
            DO-->>PM: optimized_positions
        end
        
        PM-->>BE: updated positions & executions
        
        BE->>BE: apply_slippage(executions)
        BE->>BE: calculate_transaction_costs(executions)
        BE->>BE: update_equity_curve()
    end
    
    BE->>BE: calculate_metrics()
    BE->>TCA: analyze_trade_sequence()
    TCA-->>BE: transaction_cost_metrics
    
    BE-->>User: backtest_results
Loading

Live Trading Workflow

  1. Initialization

    • Load configuration from files
    • Initialize broker connections
    • Create strategy instances
    • Initialize portfolio manager
    • Configure risk management and optimization components
  2. Market Data Subscription

    • Subscribe to real-time market data feeds
    • Process incoming ticks/bars
    • Update internal market data state
  3. Strategy Processing

    • Feed real-time data to strategies
    • Generate trading signals based on strategy logic
    • Convert signals to position targets
  4. Portfolio-Level Processing

    • Aggregate positions across strategies
    • Apply risk management constraints
    • Apply position optimization if enabled
    • Calculate trade sizes based on current vs. target positions
  5. Order Execution

    • Submit orders to execution engine
    • Select appropriate execution algorithm
    • Route orders to broker/exchange
    • Monitor order status and fills
  6. Position Management

    • Track current positions and exposures
    • Calculate realized and unrealized P&L
    • Enforce risk limits in real-time
  7. Monitoring and Reporting

    • Track system health and component states
    • Generate performance reports
    • Log diagnostics and metrics

πŸ› οΈ Setup, Installation & Building Instructions

Prerequisites

  • C++17 compatible compiler (GCC 8+, Clang 7+, MSVC 2019+)
  • CMake 3.17 or higher
  • Required libraries:
    • nlohmann_json (for configuration handling)
    • Arrow C++ (for data processing)
    • libpqxx (for PostgreSQL connectivity)
    • GoogleTest (for testing)

Clone the Repository

git clone https://github.com/your-organization/trade_ngin.git
cd trade_ngin

Setup Database

  1. Create a PostgreSQL database for market data and strategy results
  2. Create the necessary schemas and tables
  3. Configure database credentials:
    cp config_template.json config.json
    # Edit config.json with your database credentials

Building with CMake

# Create build directory
mkdir build && cd build

# Configure CMake
cmake ..

# Build the library and applications
cmake --build . --config Release

# Run tests
ctest -C Release

Building with Visual Studio

  1. Open the project folder in Visual Studio
  2. Select "Open CMake Project"
  3. Choose the desired configuration (Debug/Release)
  4. Build the solution

Building with CLion

  1. Open the project folder in CLion
  2. CLion should automatically detect the CMake configuration
  3. Choose the desired build configuration
  4. Click "Build" to compile the project

πŸš€ Running the System

Running Backtests

# From the build directory
./bin/Release/bt_trend

Configuration Parameters

All components in trade-ngin are configurable through JSON configuration files:

Backtest Configuration

{
  "strategy_config": {
    "symbols": ["ES", "NQ", "CL", "GC"],
    "asset_class": 0,
    "data_freq": 0,
    "data_type": "ohlcv",
    "start_date": "1609459200",
    "end_date": "1640995200",
    "initial_capital": 1000000.0,
    "commission_rate": 0.0005,
    "slippage_model": 1.0,
    "store_trade_details": true
  },
  "portfolio_config": {
    "initial_capital": 1000000.0,
    "use_risk_management": true,
    "use_optimization": true,
    "risk_config": {
      "var_limit": 0.15,
      "jump_risk_limit": 0.10,
      "max_correlation": 0.7,
      "max_gross_leverage": 4.0,
      "max_net_leverage": 2.0,
      "confidence_level": 0.99,
      "lookback_period": 252,
      "capital": 1000000.0
    },
    "opt_config": {
      "tau": 1.0,
      "capital": 1000000.0,
      "asymmetric_risk_buffer": 0.1,
      "cost_penalty_scalar": 10,
      "max_iterations": 1000,
      "convergence_threshold": 1e-6
    }
  },
  "results_db_schema": "backtest_results"
}

Strategy Configuration

{
  "capital_allocation": 1000000.0,
  "max_leverage": 3.0,
  "max_drawdown": 0.3,
  "var_limit": 0.1,
  "correlation_limit": 0.7,
  "trading_params": {
    "ES": 50.0,
    "NQ": 20.0,
    "CL": 1000.0,
    "GC": 100.0
  },
  "position_limits": {
    "ES": 100,
    "NQ": 100,
    "CL": 50,
    "GC": 50
  },
  "save_executions": true,
  "save_signals": true,
  "save_positions": true
}

πŸ” Extending & Contributing to the System

Adding New Strategies

To create a new strategy, follow these steps:

  1. Create a new header file in include/trade_ngin/strategy/
  2. Create a new implementation file in src/strategy/
  3. Inherit from BaseStrategy or implement StrategyInterface directly
  4. Implement the required methods for your strategy logic
  5. Register your strategy with the portfolio manager

Example of a minimally viable strategy:

class MyStrategy : public BaseStrategy {
public:
    MyStrategy(std::string id, StrategyConfig config, std::shared_ptr<DatabaseInterface> db)
        : BaseStrategy(std::move(id), std::move(config), std::move(db)) {
        // Initialize strategy-specific parameters
    }

    Result<void> on_data(const std::vector<Bar>& data) override {
        // Call base class implementation first
        auto base_result = BaseStrategy::on_data(data);
        if (base_result.is_error()) return base_result;

        // Implement your strategy logic here
        // Generate signals and update positions

        return Result<void>();
    }

    Result<void> initialize() override {
        // Custom initialization logic
        auto base_result = BaseStrategy::initialize();
        if (base_result.is_error()) return base_result;

        // Additional initialization steps

        return Result<void>();
    }
};

Adding New Data Sources

To integrate a new data source:

  1. Implement a new class derived from DatabaseInterface
  2. Override all abstract methods to interact with your data source
  3. Implement conversion from your data source's format to trade-ngin's internal types

Adding New Execution Algorithms

To add a new execution algorithm:

  1. Update the ExecutionAlgo enum in execution_engine.hpp
  2. Implement a new method in ExecutionEngine for your algorithm
  3. Update the submit_execution method to handle your new algorithm

Contribution Guidelines

  1. Code Style

    • Follow the existing coding style and naming conventions
    • Use snake_case for member variables and method names
    • Use PascalCase for class names
    • Use snake_case for file names
  2. Error Handling

    • Use the Result<T> pattern for functions that can fail
    • Provide detailed error messages with component context
  3. Testing

    • Write tests for all new functionality
    • Ensure all tests pass before submitting a pull request
  4. Documentation

    • Document all public interfaces with clear descriptions
    • Update relevant README sections for significant changes

πŸ›‘οΈ Error Handling & Troubleshooting

Common Error Codes

  • ErrorCode::INVALID_ARGUMENT - Invalid parameter provided
  • ErrorCode::NOT_INITIALIZED - Component used before initialization
  • ErrorCode::DATABASE_ERROR - Database connection or query error
  • ErrorCode::DATA_NOT_FOUND - Requested data not found
  • ErrorCode::INVALID_DATA - Data validation failed
  • ErrorCode::CONVERSION_ERROR - Type conversion error
  • ErrorCode::ORDER_REJECTED - Order rejected by the system
  • ErrorCode::INSUFFICIENT_FUNDS - Insufficient capital for order
  • ErrorCode::POSITION_LIMIT_EXCEEDED - Position limit exceeded
  • ErrorCode::INVALID_ORDER - Invalid order parameters
  • ErrorCode::STRATEGY_ERROR - Error in strategy logic
  • ErrorCode::RISK_LIMIT_EXCEEDED - Risk limit exceeded
classDiagram
    class Result~T~ {
        -value_ T
        -error_ unique_ptr~TradeError~
        +Result(value T)
        +Result(error unique_ptr~TradeError~)
        +is_ok() bool
        +is_error() bool
        +value() T
        +error() TradeError*
    }
    
    class TradeError {
        -code_ ErrorCode
        -component_ string
        +TradeError(code, message, component)
        +code() ErrorCode
        +component() string
        +to_string() string
    }
    
    class ErrorCode {
        <<enumeration>>
        NONE
        UNKNOWN_ERROR
        INVALID_ARGUMENT
        NOT_INITIALIZED
        DATABASE_ERROR
        DATA_NOT_FOUND
        INVALID_DATA
        CONVERSION_ERROR
        ORDER_REJECTED
        INSUFFICIENT_FUNDS
        POSITION_LIMIT_EXCEEDED
        INVALID_ORDER
        STRATEGY_ERROR
        RISK_LIMIT_EXCEEDED
    }
    
    Result~T~ o-- TradeError
    TradeError o-- ErrorCode
    
    note for Result~T~ "Result<T>: Pattern for error propagation"
    note for TradeError "TradeError: Extends std::runtime_error and provides error context"
Loading

Troubleshooting Techniques

Database Connection Issues

If you encounter database connection issues:

  1. Verify your credentials in config.json
  2. Ensure the PostgreSQL server is running
  3. Check network connectivity and firewall settings
  4. Examine the error message from PostgresDatabase::connect()

Example of handling database errors:

auto db = std::make_shared<PostgresDatabase>(connection_string);
auto connect_result = db->connect();
if (connect_result.is_error()) {
    // Handle error case
    std::cerr << "Database connection error: " << connect_result.error()->what() << std::endl;
    std::cerr << "Error code: " << static_cast<int>(connect_result.error()->code()) << std::endl;
    return 1;
}

Strategy Initialization Failures

If a strategy fails to initialize:

  1. Check that the database connection is valid
  2. Verify that the strategy configuration is complete
  3. Look for specific error messages in the initialization chain
  4. Examine the strategy's initialize() method

Backtesting Performance Issues

If backtests are running slowly:

  1. Reduce the number of symbols or date range
  2. Check for inefficient loops or calculations in strategies
  3. Optimize database queries to fetch data more efficiently
  4. Consider using release builds instead of debug builds

Memory Management Issues

If you encounter memory issues:

  1. Look for resource leaks in components with manual memory management
  2. Ensure that destructors properly clean up allocated resources
  3. Check for memory-intensive operations in tight loops
  4. Consider using memory profiling tools like Valgrind

πŸ“Š Performance Considerations & Optimizations

Data Processing Optimization

trade-ngin uses Apache Arrow for efficient in-memory data representation:

  • Zero-copy data sharing between components
  • Columnar memory layout for efficient processing
  • Vectorized operations for performance
  • Minimal memory allocations during data processing

Concurrency Model

  • Components use thread-safe designs with mutex protection
  • The market data bus implements a publish-subscribe pattern for efficient event distribution
  • Strategy processing can be parallelized for multiple instruments

Memory Management

  • RAII pattern throughout the codebase
  • Smart pointers for automatic resource management
  • Preallocated buffers for high-performance operations
  • Limited heap allocations in performance-critical paths

Performance Profiling

To profile trade-ngin performance:

  1. Build with profiling flags enabled

    cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_PROFILING=ON ..
  2. Run with profiling tools

    # Linux
    valgrind --tool=callgrind ./bin/bt_trend
    
    # Windows
    Visual Studio Profiler

πŸ“Œ Best Practices & Coding Standards

Naming Conventions

  • Classes: PascalCase (e.g., OrderManager)
  • Methods: snake_case (e.g., add_strategy)
  • Variables: snake_case (e.g., update_allocations)
  • Constants: UPPER_CASE (e.g., MAX_ORDERS)
  • Files: snake_case (e.g., order_manager.cpp)

Error Handling

  • Use Result<T> for functions that can fail
  • Avoid throwing exceptions across component boundaries
  • Provide detailed error messages with context
  • Check all return values for errors

Example of proper error handling:

Result<void> MyComponent::doSomething() {
    auto result = dependentComponent_->operation();
    if (result.is_error()) {
        return make_error<void>(
            result.error()->code(),
            "Failed during operation: " + std::string(result.error()->what()),
            "MyComponent"
        );
    }
    
    // Continue with operation
    return Result<void>();
}

Memory Management

  • Use smart pointers (std::shared_ptr, std::unique_ptr)
  • Follow RAII principles
  • Avoid raw new/delete operations
  • Be mindful of ownership semantics

Documentation

  • Document all public interfaces
  • Include parameter descriptions
  • Document preconditions and postconditions
  • Document error conditions and handling

πŸ“– License & Usage Terms

trade-ngin is licensed under the GPL v3 License. See LICENSE file for details.

Third-party dependencies:

  • nlohmann_json: MIT License
  • Apache Arrow: Apache License 2.0
  • libpqxx: BSD License
  • GoogleTest: BSD 3-Clause License

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 8

Languages