trade-ngin is a high-performance, modular quantitative trading system built in C++20 designed for professional algorithmic traders and financial institutions. The system supports systematic trading strategies with a focus on futures trading, featuring comprehensive risk management, portfolio optimization, and realistic backtesting capabilities.
| Capability | Description |
|---|---|
| Multi-Strategy Portfolio Management | Dynamic capital allocation across multiple strategies (e.g., TREND_FOLLOWING, TREND_FOLLOWING_FAST) |
| Comprehensive Risk Management | VaR constraints, position limits, leverage controls, correlation monitoring |
| High-Performance Backtesting | Realistic execution simulation with tick-based spread and square-root market impact models |
| Live Trading Support | Full production live trading with position persistence, email reports, and CSV exports |
| Fixed-Point Arithmetic | Custom Decimal class for financial precision (no floating-point errors) |
| PostgreSQL Integration | Apache Arrow for efficient data processing with connection pooling |
| Transaction Cost Modeling | Explicit (commissions) + Implicit (spread, market impact) cost decomposition |
| Statistical Analysis | PCA, stationarity tests (ADF, KPSS), cointegration, GARCH, Kalman Filter, HMM |
This section provides step-by-step instructions to get trade-ngin running from a fresh clone.
git clone https://github.com/AlgoGators/trade-ngin.git
cd trade-nginOption A: Use the automated setup script (Recommended)
# Make script executable
chmod +x scripts/setup-dev-environment.sh
# Run setup (detects OS automatically)
./scripts/setup-dev-environment.shOption B: Manual installation
Ubuntu/Debian
sudo bash requirements/install_ubuntu.sh
# Or manually:
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
clang-format \
cpplint \
libgtest-dev \
nlohmann-json3-dev \
libarrow-dev \
libpqxx-dev \
lcov \
gcovrmacOS (Homebrew)
bash requirements/install_macos.sh
# Or manually:
brew install \
cmake \
clang-format \
nlohmann-json \
apache-arrow \
libpqxx \
lcov \
googletest
pip3 install cpplintConfiguration uses a template + local override setup:
-
Copy the template (templates are committed; real configs are gitignored):
cp -r config_template config
-
Fill in placeholders in
config/:config/defaults.jsonβ database:YOUR_DB_HOST,YOUR_DB_USERNAME,YOUR_DB_PASSWORD,YOUR_DB_NAMEconfig/portfolios/base/email.jsonandconfig/portfolios/conservative/email.jsonβ SMTP credentials and recipients
The config/ directory is gitignored so credentials and local overrides are never committed. See Configuration for details.
# Create build directory
mkdir -p build && cd build
# Configure CMake
cmake ..
# Build (Release mode)
cmake --build . --config Release
# Return to project root
cd ..# Check executables exist
ls -la build/bin/Release/
# Expected outputs:
# bt_portfolio - Main portfolio backtest
# bt_portfolio_conservative - Conservative portfolio backtest
# live_portfolio - Main live trading application
# live_portfolio_conservative - Conservative live trading./build/bin/Release/bt_portfolio| Document | Purpose | Location |
|---|---|---|
| Config Template | Setup config from templates, placeholder list | config_template/ |
| Config Guide | Full configuration walkthrough | docs/ |
| Performance & Upkeep | CI/CD, testing, cron jobs | docs/ |
| Live Pipeline Spec | Live trading pipeline details | docs/ |
| Strategy Creation Tutorial | How to build your own strategy | docs/ |
| Transaction Cost Model | Comprehensive cost model documentation | docs/ |
| Statistics Module | Statistical analysis capabilities | docs/ |
| CI/CD Pipeline | GitHub Actions workflows, linting, coverage | docs/ |
| Docker Guide | Container deployment | docs/ |
Each source module has its own detailed README:
| Module | README | Purpose |
|---|---|---|
| Data | src/data/README.md | PostgreSQL, Arrow, connection pooling |
| Transaction Cost | src/transaction_cost/README.md | Spread/impact models with worked examples |
| Statistics | src/statistics/README.md | All 9 statistical models |
| Optimization | src/optimization/README.md | Dynamic optimizer + RiskManager |
| Live Trading | src/live/README.md | Live coordinator, email, CSV export |
| Backtest | src/backtest/README.md | BacktestCoordinator, metrics |
| Strategy | src/strategy/README.md | Complete strategy development guide |
| Portfolio | src/portfolio/README.md | Multi-strategy coordination |
- β Multi-timeframe trend following strategy with EMA crossovers across 6 timeframes
- β Multi-strategy portfolio support (TREND_FOLLOWING + TREND_FOLLOWING_FAST)
- β 28 futures contracts support (ES, NQ, GC, CL, ZN, etc.)
- β Fixed-point arithmetic with custom Decimal class for financial precision
- β PostgreSQL integration with Apache Arrow and connection pooling
- β Comprehensive risk management with VaR constraints and leverage limits
- β Dynamic portfolio optimization with transaction cost consideration
- β Realistic transaction cost modeling (tick-based spread + square-root impact)
- β Live trading coordinator with position loading and persistence
- β Email reporting system with embedded charts
- β CSV export functionality for positions and trades
- β Non-trading day detection (weekends + holidays)
- β Margin validation for futures instruments
- β Extensive logging and debugging capabilities
Configuration uses a template + local override model:
| Directory | Tracked in Git? | Purpose |
|---|---|---|
config_template/ |
Yes | Template files with placeholders; safe to commit |
config/ |
No (gitignored) | Local config with real credentials; never committed |
Setup flow:
- Copy:
cp -r config_template config - Edit
config/defaults.jsonβ replaceYOUR_DB_HOST,YOUR_DB_USERNAME,YOUR_DB_PASSWORD,YOUR_DB_NAME - Edit
config/portfolios/base/email.jsonandconfig/portfolios/conservative/email.jsonβ replace SMTP credentials and recipient emails
Structure:
config/
βββ defaults.json # Database, execution, optimization (shared)
βββ portfolios/
βββ base/ # BASE_PORTFOLIO β bt_portfolio, live_portfolio
β βββ portfolio.json # Strategies, capital, allocations
β βββ risk.json # Risk limits
β βββ email.json # Email notifications
βββ conservative/ # CONSERVATIVE_PORTFOLIO β bt_portfolio_conservative, live_portfolio_conservative
βββ portfolio.json
βββ risk.json
βββ email.json
Loading: Applications load from config/ via ConfigLoader::load("./config", "base") or ConfigLoader::load("./config", "conservative"). Defaults are merged with portfolio-specific files.
For full placeholder list and examples, see config_template/README.md.
Example config/defaults.json (after replacing placeholders):
{
"database": {
"host": "your-database-host",
"port": "5432",
"username": "your-username",
"password": "your-password",
"name": "your-database-name",
"num_connections": 5
},
"strategy_defaults": {
"max_strategy_allocation": 1.0,
"min_strategy_allocation": 0.1
}
}Example config/portfolios/base/portfolio.json (strategies):
{
"portfolio_id": "BASE_PORTFOLIO",
"initial_capital": 500000.0,
"reserve_capital_pct": 0.10,
"strategies": {
"TREND_FOLLOWING": {
"enabled_backtest": true,
"enabled_live": true,
"default_allocation": 0.7,
"type": "TrendFollowingStrategy",
"config": {
"weight": 0.03,
"risk_target": 0.2,
"idm": 2.5,
"ema_windows": [[2,8], [4,16], [8,32], [16,64], [32,128], [64,256]]
}
},
"TREND_FOLLOWING_FAST": {
"enabled_backtest": true,
"enabled_live": true,
"default_allocation": 0.3,
"type": "TrendFollowingFastStrategy",
"config": { "..." }
}
}
}Note: The system fully supports multiple strategies and portfolios. Each strategy can have different allocations (must sum to 1.0), parameters, and can be independently enabled/disabled for backtest vs. live trading.
The trade-ngin system supports running multiple independent portfolios simultaneously. Each portfolio:
- Has its own unique
portfolio_id - Can contain different strategies with different allocations
- Stores positions and results separately in the database
- Generates separate CSV exports and email reports
Example: Portfolio A (Aggressive)
{
"portfolio_id": "PORTFOLIO_A",
"portfolio": {
"strategies": {
"TREND_FOLLOWING": { "default_allocation": 0.7 },
"MEAN_REVERSION": { "default_allocation": 0.3 }
}
}
}Example: Portfolio B (Conservative)
{
"portfolio_id": "PORTFOLIO_B",
"portfolio": {
"strategies": {
"TREND_FOLLOWING": { "default_allocation": 1.0 }
}
}
}To run different portfolios, use the built-in base and conservative configs under config/portfolios/, or add a new portfolio directory (e.g., config/portfolios/aggressive/) and a corresponding executable. All portfolio data is isolated by portfolio_id in the database.
| Parameter | Value | Description |
|---|---|---|
| Initial Capital | $500,000 | Starting portfolio capital |
| IDM | 2.5 | Instrument Diversification Multiplier |
| Weight per Symbol | 0.03 (3%) | Maximum allocation per instrument |
| Risk Target | 0.20-0.25 | Annualized volatility target |
| Max Gross Leverage | 4.0x | Maximum total exposure |
| Max Net Leverage | 2.0x | Maximum directional exposure |
| VaR Limit | 0.15 (15%) | Maximum 99% daily VaR |
| Reserve Capital | 10% | Capital held in reserve |
trade-ngin/
βββ apps/ # Application executables
β βββ backtest/ # Backtesting applications
β β βββ bt_portfolio.cpp # Main portfolio backtest runner
β β βββ bt_portfolio_conservative.cpp # Conservative variant
β β βββ CMakeLists.txt
β βββ strategies/ # Live trading applications
β β βββ live_portfolio.cpp # Main live trading application
β β βββ live_portfolio_conservative.cpp
β β βββ results/ # Live trading CSV outputs
β β βββ PORTFOLIO_A/ # Portfolio-specific results
β βββ CMakeLists.txt
β
βββ include/trade_ngin/ # Public header files (65 total)
β βββ backtest/ # Backtest components (10 headers)
β β βββ backtest_coordinator.hpp
β β βββ backtest_data_loader.hpp
β β βββ backtest_execution_manager.hpp
β β βββ backtest_metrics_calculator.hpp
β β βββ backtest_pnl_manager.hpp
β β βββ backtest_portfolio_constraints.hpp
β β βββ backtest_price_manager.hpp
β β βββ backtest_types.hpp
β β βββ slippage_models.hpp
β β βββ transaction_cost_analysis.hpp
β βββ core/ # Core system components (14 headers)
β β βββ chart_generator.hpp # Chart generation for emails
β β βββ config_base.hpp
β β βββ config_manager.hpp
β β βββ email_sender.hpp # Email report system
β β βββ error.hpp # Error types and Result<T>
β β βββ holiday_checker.hpp # Holiday detection
β β βββ holidays.json # CME holiday calendar
β β βββ logger.hpp # Logging framework
β β βββ run_id_generator.hpp
β β βββ state_manager.hpp
β β βββ time_utils.hpp
β β βββ types.hpp # Core types (Decimal, Bar, Position, etc.)
β βββ data/ # Data management (6 headers)
β β βββ conversion_utils.hpp # Arrow β domain conversion
β β βββ credential_store.hpp # Secure credential access
β β βββ database_interface.hpp # Abstract database interface
β β βββ database_pooling.hpp # Connection pool
β β βββ market_data_bus.hpp # Pub-sub for market data
β β βββ postgres_database.hpp # PostgreSQL implementation
β βββ execution/ # Order execution
β β βββ execution_engine.hpp
β βββ instruments/ # Financial instruments (5 headers)
β β βββ equity.hpp
β β βββ futures.hpp # Futures with margin requirements
β β βββ instrument.hpp # Base instrument interface
β β βββ instrument_registry.hpp # Singleton registry
β β βββ option.hpp
β βββ live/ # Live trading components (10 headers)
β β βββ csv_exporter.hpp # CSV output generation
β β βββ execution_manager.hpp
β β βββ live_data_loader.hpp
β β βββ live_metrics_calculator.hpp
β β βββ live_pnl_manager.hpp
β β βββ live_price_manager.hpp # T-1/T-2 price tracking
β β βββ live_trading_coordinator.hpp # Main orchestrator
β β βββ margin_manager.hpp # Margin requirement validation
β β βββ pnl_manager_base.hpp
β β βββ price_manager_base.hpp
β βββ optimization/ # Portfolio optimization
β β βββ dynamic_optimizer.hpp # Cost-aware optimization
β βββ order/ # Order management
β β βββ order_manager.hpp
β βββ portfolio/ # Portfolio management
β β βββ portfolio_manager.hpp # Multi-strategy coordination
β βββ risk/ # Risk management
β β βββ risk_manager.hpp # VaR, leverage limits
β βββ statistics/ # Statistical analysis
β β βββ statistics_tools.hpp # PCA, GARCH, Kalman, HMM
β βββ storage/ # Results persistence (3 headers)
β β βββ backtest_results_manager.hpp
β β βββ live_results_manager.hpp
β β βββ results_manager_base.hpp
β βββ strategy/ # Strategy components (7 headers)
β β βββ base_strategy.hpp # Common strategy functionality
β β βββ regime_detector.hpp # Market regime classification
β β βββ strategy_interface.hpp # Abstract interface
β β βββ trend_following.hpp # Main trend strategy
β β βββ trend_following_fast.hpp
β β βββ trend_following_slow.hpp
β β βββ types.hpp # Strategy-specific types
β βββ transaction_cost/ # Transaction cost modeling (4 headers)
β βββ asset_cost_config.hpp # Per-symbol configurations
β βββ impact_model.hpp # Square-root market impact
β βββ spread_model.hpp # Tick-based spread with vol widening
β βββ transaction_cost_manager.hpp # Main orchestrator
β
βββ src/ # Implementation files (61 files)
β βββ backtest/ # Backtest implementations (9 files)
β β βββ backtest_coordinator.cpp # Main orchestrator
β β βββ backtest_data_loader.cpp
β β βββ backtest_execution_manager.cpp
β β βββ backtest_metrics_calculator.cpp
β β βββ backtest_pnl_manager.cpp
β β βββ backtest_portfolio_constraints.cpp
β β βββ backtest_price_manager.cpp
β β βββ slippage_model.cpp
β β βββ transaction_cost_analysis.cpp
β βββ core/ # Core implementations (8 files)
β β βββ chart_generator.cpp # Gnuplot chart generation
β β βββ config_base.cpp
β β βββ config_manager.cpp
β β βββ config_version.cpp
β β βββ email_sender.cpp # SMTP with HTML/charts
β β βββ logger.cpp # File rotation, log levels
β β βββ run_id_generator.cpp
β β βββ state_manager.cpp
β βββ data/ # Data implementations (6 files)
β β βββ conversion_utils.cpp
β β βββ credential_store.cpp
β β βββ database_pooling.cpp # Connection pool with retry
β β βββ market_data_bus.cpp
β β βββ postgres_database.cpp # All data operations
β β βββ postgres_database_extensions.cpp
β βββ execution/
β β βββ execution_engine.cpp
β βββ instruments/ # Instrument implementations (4 files)
β β βββ equity.cpp
β β βββ futures.cpp # Margin, multiplier, expiry
β β βββ instrument_registry.cpp
β β βββ option.cpp
β βββ live/ # Live trading implementations (8 files)
β β βββ csv_exporter.cpp
β β βββ execution_manager.cpp
β β βββ live_data_loader.cpp
β β βββ live_metrics_calculator.cpp
β β βββ live_pnl_manager.cpp
β β βββ live_price_manager.cpp
β β βββ live_trading_coordinator.cpp
β β βββ margin_manager.cpp
β βββ optimization/
β β βββ dynamic_optimizer.cpp # Cost-aware optimization
β βββ order/
β β βββ order_manager.cpp
β βββ portfolio/
β β βββ portfolio_manager.cpp
β βββ risk/
β β βββ risk_manager.cpp # VaR, leverage, correlation
β βββ statistics/
β β βββ statistics_tools.cpp # All statistical models
β βββ storage/ # Results persistence (3 files)
β β βββ backtest_results_manager.cpp
β β βββ live_results_manager.cpp
β β βββ results_manager_base.cpp
β βββ strategy/ # Strategy implementations (5 files)
β β βββ base_strategy.cpp
β β βββ regime_detector.cpp
β β βββ trend_following.cpp # Main trend strategy
β β βββ trend_following_fast.cpp
β β βββ trend_following_slow.cpp
β βββ transaction_cost/ # Transaction cost implementations (4 files)
β βββ asset_cost_config.cpp
β βββ impact_model.cpp
β βββ spread_model.cpp
β βββ transaction_cost_manager.cpp
β
βββ tests/ # Unit and integration tests (27 test files)
β βββ backtesting/ # Backtest engine tests
β βββ core/ # Logger, config tests
β βββ data/ # Database, conversion tests
β βββ execution/ # Execution engine tests
β βββ optimization/ # Optimizer tests
β βββ order/ # Order manager tests
β βββ portfolio/ # Portfolio manager tests
β βββ risk/ # Risk manager tests
β βββ statistics/ # Statistics tools tests
β βββ strategy/ # Strategy tests
β
βββ docs/ # Documentation (27 files)
β βββ CI_CD_README.md # CI/CD pipeline documentation
β βββ CI_CD_IMPLEMENTATION_SUMMARY.md
β βββ LIBRARY_API_ARCHITECTURE.md # API design guide
β βββ README.Docker.md # Docker deployment
β βββ TYPE_CONVERSION_GUIDE.md # Type system guide
β βββ commission_CHANGES.md # Commission model changes
β βββ commission_MIGRATION.md # Migration guide
β βββ config_deliverable.md # Configuration specification
β βββ futures_enhancements_transaction_costs.md
β βββ live_pipeline_spec.md # Live trading specification
β βββ live_portfolio_multi_strategy_migration.md
β βββ live_portfolio_refactoring_analysis.md
β βββ multi_portfolio_email_csv_analysis.md
β βββ non_trading_day_fix.md # Holiday handling
β βββ performance_upkeep.md # Cron jobs, monitoring
β βββ statistics.md # Statistics overview
β βββ statistics_model_improvement.md
β βββ statistics_module_deliverable.md
β βββ strategy_creation_tutorial.md
β βββ strategy_level_metrics.md
β βββ transaction_cost_config_fixes.md
β βββ transaction_cost_migration_guide.md
β βββ transaction_cost_refactor.md
β
βββ scripts/ # Development scripts
β βββ dev_build_run.sh # Quick build and run
β βββ pre-commit-hook.sh # Pre-commit checks
β βββ run_live_trend.sh # Live trading launcher
β βββ setup-dev-environment.sh # Environment setup
β
βββ linting/ # Code quality tools
β βββ lint_runner.sh # Linting runner
β βββ auto_fix_lint.sh # Auto-fix formatting
β
βββ requirements/ # Dependency installation
β βββ README.md # Installation guide
β βββ install_ubuntu.sh # Ubuntu dependencies
β βββ install_macos.sh # macOS dependencies
β
βββ config_template/ # Config templates (committed, no secrets)
β βββ README.md # Setup instructions
β βββ defaults.json # Placeholders: YOUR_DB_HOST, etc.
β βββ portfolios/
β βββ base/ # portfolio.json, risk.json, email.json
β βββ conservative/
βββ config/ # Local config (gitignored; copy from config_template)
β βββ defaults.json # Fill in database credentials
β βββ portfolios/base/, portfolios/conservative/
βββ CMakeLists.txt # Main build configuration
βββ Dockerfile # Docker container definition
βββ build_docker.sh # Docker build script
βββ live_trend.cron # Cron job definition
trade-ngin follows a modular, component-based architecture with well-defined interfaces between system components.
flowchart TB
subgraph External["External Systems"]
DB[(PostgreSQL<br/>Database)]
SMTP[Email Server]
end
subgraph Core["Core Infrastructure"]
Logger[Logger]
Config[ConfigManager]
State[StateManager]
Creds[CredentialStore]
end
subgraph Data["Data Layer"]
PgDB[PostgresDatabase]
Pool[DatabasePool]
MDB[MarketDataBus]
Conv[ConversionUtils]
end
subgraph Instruments["Instrument Layer"]
Registry[InstrumentRegistry]
Futures[FuturesInstrument]
Equity[EquityInstrument]
end
subgraph Strategy["Strategy Layer"]
BaseStrat[BaseStrategy]
TrendFollow[TrendFollowingStrategy]
TrendFast[TrendFollowingFastStrategy]
Regime[RegimeDetector]
end
subgraph Portfolio["Portfolio Layer"]
PM[PortfolioManager]
Opt[DynamicOptimizer]
Risk[RiskManager]
end
subgraph TransactionCost["Transaction Cost"]
TCM[TransactionCostManager]
Spread[SpreadModel]
Impact[ImpactModel]
ACfg[AssetCostConfig]
end
subgraph Backtest["Backtest Engine"]
BTC[BacktestCoordinator]
BTData[BacktestDataLoader]
BTPnL[BacktestPnLManager]
BTMetrics[BacktestMetricsCalculator]
end
subgraph Live["Live Trading"]
LTC[LiveTradingCoordinator]
LData[LiveDataLoader]
LPnL[LivePnLManager]
Email[EmailSender]
CSV[CSVExporter]
Margin[MarginManager]
end
DB --> PgDB
PgDB <--> Pool
Pool --> Data
Config --> Core
Creds --> PgDB
Data --> Instruments
Instruments --> Strategy
Strategy --> Portfolio
TCM --> Spread
TCM --> Impact
ACfg --> TCM
Portfolio --> Backtest
Portfolio --> Live
TCM --> Portfolio
Live --> Email
Live --> CSV
Email --> SMTP
Tip: For detailed component documentation, see the module-specific READMEs listed in Quick Reference.
trade-ngin uses a custom type system for financial precision:
The Decimal class (include/trade_ngin/core/types.hpp) provides fixed-point arithmetic with 8 decimal places:
// 8 decimal places for financial precision
class Decimal {
static constexpr int64_t SCALE = 100000000LL; // 10^8
int64_t value_;
public:
Decimal(double d); // Converts with rounding
explicit operator double() const;
// Arithmetic with overflow checking
Decimal operator+(const Decimal& other) const;
Decimal operator*(const Decimal& other) const;
// ... etc
// Utilities
Decimal abs() const;
bool is_zero() const;
std::string to_string() const;
};using Timestamp = std::chrono::system_clock::time_point;
using Price = Decimal;
using Quantity = Decimal;// Market data bar
struct Bar {
Timestamp timestamp;
Price open, high, low, close;
double volume;
std::string symbol;
};
// Position tracking
struct Position {
std::string symbol;
Quantity quantity;
Price average_price;
Decimal unrealized_pnl;
Decimal realized_pnl;
Timestamp last_update;
};
// Execution report with cost breakdown
struct ExecutionReport {
std::string order_id;
std::string symbol;
Side side;
Quantity filled_quantity;
Price fill_price;
Decimal commissions_fees; // Explicit costs
Decimal implicit_price_impact; // Spread + impact
Decimal slippage_market_impact; // Implicit costs in $
Decimal total_transaction_costs; // Total
};trade-ngin includes a comprehensive, thread-safe logging system for debugging, monitoring, and auditing.
| Level | Macro | Usage |
|---|---|---|
TRACE |
TRACE(msg) |
Detailed debug information (very verbose) |
DEBUG |
DEBUG(msg) |
General debug information |
INFO |
INFO(msg) |
General operational information |
WARNING |
WARN(msg) |
Warnings that don't affect operation |
ERROR |
ERROR(msg) |
Errors that affect operation but don't stop system |
FATAL |
FATAL(msg) |
Critical errors requiring system shutdown |
#include "trade_ngin/core/logger.hpp"
// Initialize once at startup
LoggerConfig config;
config.min_level = LogLevel::INFO;
config.destination = LogDestination::BOTH; // Console + file
config.log_directory = "logs";
config.filename_prefix = "live_trend";
config.max_file_size = 50 * 1024 * 1024; // 50MB
config.max_files = 10;
Logger::instance().initialize(config);
// Log messages
INFO("Portfolio initialized with capital: $" << initial_capital);
DEBUG("Loading positions for date: " << date_str);
WARN("No market data available for: " << symbol);
ERROR("Database connection failed: " << error_msg);[2025-01-15 09:30:45.123] [INFO] Portfolio initialized with capital: $500000
[2025-01-15 09:30:45.456] [DEBUG] Loading 28 instruments from registry
[2025-01-15 09:30:46.789] [INFO] Strategy TREND_FOLLOWING generating signals
Both backtest and live trading log key operations to the database for auditing:
During backtests, the following is recorded:
- Daily equity snapshots stored in
trading.backtest_equity_curve - Trade executions with full cost breakdown
- Metrics calculated at backtest completion
// Logged during backtest
INFO("Processing date: " << date << " | Equity: $" << equity);
DEBUG("Symbol: " << symbol << " | Signal: " << signal << " | Position: " << position);During live runs, extensive logging captures:
// Position loading
INFO("Loading positions for date: " << date << " | Portfolio: " << portfolio_id);
// Strategy signals
INFO("Strategy " << strategy_id << " signal for " << symbol << ": " << signal);
// Position changes
INFO("Position change: " << symbol << " | Old: " << old_qty << " | New: " << new_qty);
// Database operations
DEBUG("Storing position: " << symbol << " | Qty: " << qty << " | Price: " << price);
// Risk validation
INFO("Risk check: Gross=" << gross_lev << " | Net=" << net_lev << " | VaR=" << var);| Mode | Log Location | Filename Pattern |
|---|---|---|
| Backtest | logs/ |
bt_portfolio_YYYYMMDD_HHMMSS.log |
| Live | logs/ |
live_trend_YYYYMMDD.log |
// Change minimum log level
Logger::instance().set_level(LogLevel::DEBUG);
// Get current level
LogLevel current = Logger::instance().get_min_level();trade-ngin implements a comprehensive transaction cost model based on Robert Carver's methodology. See transaction_cost_refactor.md for full specification or src/transaction_cost/README.md for implementation details.
total_transaction_costs = explicit_costs + implicit_costs
explicit_costs = |quantity| Γ $1.75 per contract
implicit_costs = (spread_cost + market_impact) Γ |quantity| Γ point_value
spread_price_impact = 0.5 Γ spread_ticks Γ tick_size Γ volatility_multiplierWhere:
spread_ticks= baseline spread in ticks (per instrument)tick_size= minimum price increment (e.g., 0.25 for ES)volatility_multiplier= 1.0 Β± Ξ» Γ z_Ο (widens in high volatility)
impact_bps = k_bps Γ β(|quantity| / ADV)
market_impact_price_impact = (impact_bps / 10000) Γ reference_priceWhere k_bps is selected based on ADV buckets:
| ADV | k_bps | Category |
|---|---|---|
| > 1,000,000 | 10 | Ultra liquid |
| > 200,000 | 20 | Liquid |
| > 50,000 | 40 | Medium |
| > 20,000 | 60 | Thin |
| β€ 20,000 | 80 | Very thin |
Given:
- Reference Price: $5,000
- Quantity: 10 contracts
- Tick Size: 0.25 points
- Point Value: $50
- ADV: 500,000 contracts
Calculations:
Explicit: 10 Γ $1.75 = $17.50
Spread: 0.5 Γ 1 Γ 0.25 = 0.125 points
Impact: 10 Γ β(10/500000) Γ 5000/10000 = 0.02235 points
Implicit: (0.125 + 0.02235) Γ 10 Γ 50 = $73.68
Total: $17.50 + $73.68 = $91.18
The statistics module provides quantitative analysis capabilities. See src/statistics/README.md for detailed usage.
| Category | Model | Status | Usage |
|---|---|---|---|
| Transformers | Normalizer (Z-Score, Min-Max, Robust) | β Complete | Data preprocessing |
| Transformers | PCA (variance threshold, whitening) | β Complete | Dimensionality reduction |
| Stationarity | ADF Test | β Complete | Unit root testing |
| Stationarity | KPSS Test | β Complete | Stationarity confirmation |
| Cointegration | Johansen Test | β Complete | Multi-series cointegration |
| Cointegration | Engle-Granger Test | β Complete | Pairwise cointegration |
| Volatility | GARCH(1,1) | β Complete | Volatility forecasting |
| State Estimation | Kalman Filter | β Complete | Signal extraction |
| State Estimation | Hidden Markov Model | β Complete | Regime detection |
#include "trade_ngin/statistics/statistics_tools.hpp"
// Test for stationarity
auto result = statistics::adf_test(price_series, 5); // 5 lags
if (result.p_value < 0.05) {
// Series is stationary
}sequenceDiagram
participant User
participant BTC as BacktestCoordinator
participant DB as PostgresDatabase
participant PM as PortfolioManager
participant Strat as Strategies
participant TCM as TransactionCostManager
participant RM as RiskManager
User->>BTC: run_portfolio()
BTC->>DB: load_market_data(symbols, dates)
DB-->>BTC: historical bars
loop For each trading day
BTC->>PM: process_market_data(bars)
PM->>Strat: on_data(bars)
Strat-->>PM: target_positions
PM->>TCM: calculate_trading_costs(symbols)
TCM-->>PM: cost_vector
PM->>RM: process_positions(positions)
RM-->>PM: risk_result (multipliers)
PM-->>BTC: executions, positions
BTC->>BTC: update_equity_curve()
end
BTC->>BTC: calculate_metrics()
BTC->>DB: save_results()
BTC-->>User: BacktestResults
sequenceDiagram
participant Cron as Cron Job
participant LTC as LiveTradingCoordinator
participant DB as PostgresDatabase
participant PM as PortfolioManager
participant Holiday as HolidayChecker
participant Email as EmailSender
participant CSV as CSVExporter
Cron->>LTC: main(date, --send-email)
LTC->>Holiday: is_holiday(yesterday)?
alt Non-trading day
Holiday-->>LTC: true (weekend/holiday)
LTC->>DB: load_previous_positions()
LTC-->>Cron: Positions unchanged
else Trading day
Holiday-->>LTC: false
LTC->>DB: load_positions_by_date(prev_date)
DB-->>LTC: existing_positions
LTC->>DB: load_market_data(today)
DB-->>LTC: today_bars
LTC->>PM: process_market_data(bars)
PM-->>LTC: new_positions, executions
LTC->>DB: store_positions()
LTC->>DB: store_executions()
end
alt --send-email flag
LTC->>Email: prepare_report(positions, metrics)
Email->>Email: generate_charts()
Email-->>LTC: send_email()
end
LTC->>CSV: export_positions()
LTC-->>Cron: Exit(0)
Quick Start: For the fastest setup, follow the Quick Start section.
| Requirement | Version | Purpose |
|---|---|---|
| C++ Compiler | GCC 10+ / Clang 10+ / MSVC 2019+ | C++20 support |
| CMake | 3.17+ | Build configuration |
| PostgreSQL | 12+ | Market data storage |
| nlohmann_json | Latest | JSON configuration |
| Apache Arrow C++ | Latest | Efficient data processing |
| libpqxx | Latest | PostgreSQL C++ client |
| Eigen3 | Latest | Linear algebra for optimization |
| libcurl | Latest | Email functionality |
| GoogleTest | Bundled | Unit testing |
- Memory: 8GB+ RAM for typical backtests
- Storage: SSD recommended for database
- OS: Linux (preferred), macOS, Windows (WSL2)
mkdir -p build && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-g -O0 -fprofile-arcs -ftest-coverage"
cmake --build . -j$(nproc)
cd ..cd build
ctest --output-on-failure --verbose# Run main backtest
./build/bin/Release/bt_portfolio
# Run conservative portfolio backtest
./build/bin/Release/bt_portfolio_conservativeLive trading requires a date argument in YYYY-MM-DD format:
# Run for a specific date (no email)
./build/bin/Release/live_portfolio 2025-01-15
# Run for a specific date WITH email report
./build/bin/Release/live_portfolio 2025-01-15 --send-email
# Conservative portfolio variant
./build/bin/Release/live_portfolio_conservative 2025-01-15 --send-emailNote: The date-less execution mode is deprecated. Always specify the date.
| Output Type | Location | Description |
|---|---|---|
| Logs | logs/live_trend_YYYYMMDD.log |
Daily log files |
| CSV Exports | apps/strategies/results/<portfolio_id>/ |
Position files |
| Database | trading.positions |
Persisted positions |
| Type | Class | Description |
|---|---|---|
TrendFollowingStrategy |
TrendFollowingStrategy |
Standard 6-window trend following |
TrendFollowingFastStrategy |
TrendFollowingFastStrategy |
Faster-reacting (shorter windows) |
TrendFollowingSlowStrategy |
TrendFollowingSlowStrategy |
Slower-reacting (longer windows) |
{
"email": {
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"username": "your-email@gmail.com",
"password": "your-app-password",
"from_email": "your-email@gmail.com",
"to_emails": ["recipient1@example.com", "recipient2@example.com"],
"use_tls": true
}
}Gmail Setup: Use an App Password rather than your account password.
| Schema | Table | Purpose |
|---|---|---|
trading |
positions |
Current and historical positions |
trading |
executions |
Trade execution records |
trading |
live_run_metadata |
Daily run configuration |
trading |
strategy_trading_days_metadata |
Strategy configuration history |
futures_data |
ohlcv_1d |
Daily OHLCV data |
futures_data |
instruments |
Contract specifications |
CREATE TABLE trading.positions (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
portfolio_id VARCHAR(255) NOT NULL,
strategy_id VARCHAR(255) NOT NULL,
symbol VARCHAR(50) NOT NULL,
quantity DECIMAL(18,8),
average_price DECIMAL(18,8),
unrealized_pnl DECIMAL(18,8),
realized_pnl DECIMAL(18,8),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE trading.executions (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
portfolio_id VARCHAR(255) NOT NULL,
strategy_id VARCHAR(255) NOT NULL,
symbol VARCHAR(50) NOT NULL,
side VARCHAR(10),
quantity DECIMAL(18,8),
price DECIMAL(18,8),
commission DECIMAL(18,8),
slippage DECIMAL(18,8),
total_cost DECIMAL(18,8),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);For comprehensive strategy development instructions, see src/strategy/README.md.
- Create header in
include/trade_ngin/strategy/your_strategy.hpp - Implement in
src/strategy/your_strategy.cpp - Inherit from
BaseStrategy - Override required methods:
initialize(),on_data(),validate_config() - Register in
CMakeLists.txt(add toTRADE_NGIN_SOURCES) - Add to factory in
live_portfolio.cppandbt_portfolio.cpp - Configure in
config/portfolios/<name>/portfolio.jsonunderstrategies
// include/trade_ngin/strategy/my_strategy.hpp
#pragma once
#include "trade_ngin/strategy/base_strategy.hpp"
namespace trade_ngin {
struct MyStrategyConfig {
double parameter1 = 0.5;
int lookback_window = 20;
};
class MyStrategy : public BaseStrategy {
public:
MyStrategy(std::string id,
StrategyConfig config,
MyStrategyConfig my_config,
std::shared_ptr<PostgresDatabase> db,
std::shared_ptr<InstrumentRegistry> registry);
Result<void> initialize() override;
Result<void> on_data(const std::vector<Bar>& data) override;
protected:
Result<void> validate_config() const override;
private:
MyStrategyConfig my_config_;
};
} // namespace trade_ngin// src/strategy/my_strategy.cpp
#include "trade_ngin/strategy/my_strategy.hpp"
namespace trade_ngin {
MyStrategy::MyStrategy(std::string id,
StrategyConfig config,
MyStrategyConfig my_config,
std::shared_ptr<PostgresDatabase> db,
std::shared_ptr<InstrumentRegistry> registry)
: BaseStrategy(std::move(id), std::move(config), db, registry),
my_config_(my_config) {}
Result<void> MyStrategy::initialize() {
auto validate_result = validate_config();
if (validate_result.is_error()) {
return validate_result;
}
INFO("MyStrategy initialized with parameter1=" +
std::to_string(my_config_.parameter1));
return Result<void>();
}
Result<void> MyStrategy::on_data(const std::vector<Bar>& data) {
// Your trading logic here
for (const auto& bar : data) {
// Calculate signal
double signal = calculate_signal(bar);
// Size position
double position = signal * get_position_size(bar.symbol);
// Update target
update_target_position(bar.symbol, position);
}
return Result<void>();
}
Result<void> MyStrategy::validate_config() const {
if (my_config_.parameter1 <= 0 || my_config_.parameter1 > 1.0) {
return make_error<void>(ErrorCode::INVALID_ARGUMENT,
"parameter1 must be in (0, 1]",
"MyStrategy");
}
return Result<void>();
}
} // namespace trade_ngintrade-ngin uses the Result<T> pattern for error propagation (see include/trade_ngin/core/error.hpp):
Result<void> MyComponent::operation() {
auto result = other_component->do_something();
if (result.is_error()) {
return make_error<void>(
result.error()->code(),
"Failed during operation: " + std::string(result.error()->what()),
"MyComponent"
);
}
return Result<void>();
}
// Usage
auto result = component.operation();
if (result.is_error()) {
ERROR(result.error()->what());
return 1;
}| Code | Meaning |
|---|---|
INVALID_ARGUMENT |
Invalid parameter provided |
NOT_INITIALIZED |
Component not initialized |
DATABASE_ERROR |
Database operation failed |
DATA_NOT_FOUND |
Requested data not found |
STRATEGY_ERROR |
Strategy logic error |
RISK_LIMIT_EXCEEDED |
Risk constraint violated |
MARGIN_VALIDATION_FAILED |
Margin requirements not met |
- Apache Arrow for zero-copy data sharing
- Columnar memory layout for vectorized operations
- Connection pooling for database efficiency (5 connections by default)
- RAII pattern throughout
- Smart pointers (
std::shared_ptr,std::unique_ptr) for automatic resource management - Preallocated buffers for performance-critical operations
- Thread-safe component designs with mutex protection
- Pub-sub pattern for market data distribution
- Connection pool with thread-safe acquisition
- Use
reserve()on vectors when size is known - Avoid unnecessary copies (use
const&or move semantics) - Profile with
perforvalgrindfor bottlenecks
The system includes Docker support for containerized deployment:
# Build Docker image
./build_docker.sh
# Or manually:
docker build -t trade-ngin -f Dockerfile .
# Run container
docker run -d \
--name trade-ngin \
-v $(pwd)/config:/app/config \
-v $(pwd)/logs:/app/logs \
trade-nginThe container includes:
- All system dependencies
- Cron job for scheduled runs (
live_trend.cron) - Gnuplot for chart generation
- Timezone set to America/New_York
Mount your local config/ directory (created from config_template/) into the container so it has database and email credentials.
The project uses GitHub Actions for continuous integration. See docs/CI_CD_README.md for details.
| Workflow | Trigger | Purpose |
|---|---|---|
ci-cd-pipeline.yml |
Push, PR | Lint, build, test |
code-coverage.yml |
Push, PR | Coverage reports |
# Run before each commit
./scripts/pre-commit-hook.sh
# Run linting
./linting/lint_runner.sh
# Auto-fix formatting
./linting/auto_fix_lint.sh- Minimum Coverage: 75%
- Tools: lcov, gcovr
- Reports: HTML, XML (Cobertura)
cd build
# Run all tests
ctest --output-on-failure
# Run specific test
./tests/test_portfolio_manager
# Run with verbose output
ctest -V
# Run with coverage
cmake .. -DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_FLAGS="-g -O0 -fprofile-arcs -ftest-coverage"
make -j$(nproc)
ctest
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory coverage_htmltests/
βββ backtesting/ # BacktestCoordinator tests
βββ core/ # Logger, config tests
βββ data/ # Database tests
βββ execution/ # Execution engine tests
βββ optimization/ # Optimizer tests
βββ order/ # Order manager tests
βββ portfolio/ # Portfolio manager tests
βββ risk/ # Risk manager tests
βββ statistics/ # Statistics tools tests
βββ strategy/ # Strategy tests
Missing dependencies:
# Ubuntu
sudo apt-get install libarrow-dev nlohmann-json3-dev libpqxx-dev
# macOS
brew install apache-arrow nlohmann-json libpqxxlibpqxx not found:
# Check pkg-config
pkg-config --libs libpqxx
# If missing, add to PKG_CONFIG_PATH
export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH"Connection refused:
- Check database host is accessible
- Verify port 5432 is open
- Confirm credentials in
config/defaults.json(copy fromconfig_template/and fill placeholders)
Missing tables:
- Ensure required schemas exist (
trading,futures_data) - Run database migrations if available
No market data:
- Check if date is a trading day
- Verify data exists in
futures_data.ohlcv_1d - Ensure symbols list is correct
Email not sending:
- Verify SMTP credentials
- Check Gmail App Password (not account password)
- Confirm recipient email addresses
Enable verbose logging:
// In config or at runtime
LoggerConfig config;
config.min_level = LogLevel::DEBUG; // or TRACE for maximum detail- Check the
logs/directory for error details - Review relevant documentation in
docs/ - Create an issue with:
- Error message
- Steps to reproduce
- Configuration (sanitized)
- Log snippets
- Follow Google C++ Style Guide
- Use
clang-formatwith the provided.clang-formatconfiguration - Run linting before committing
| Item | Convention | Example |
|---|---|---|
| Classes | PascalCase | PortfolioManager |
| Functions | snake_case | calculate_position() |
| Variables | snake_case | target_position |
| Constants | UPPER_SNAKE | MAX_LEVERAGE |
| Files | snake_case | portfolio_manager.cpp |
| Headers | snake_case.hpp | portfolio_manager.hpp |
- Create feature branch from
develop - Make changes with meaningful commits
- Run pre-commit checks
- Create PR to
develop - Address code review feedback
- Merge after approval
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
- Robert Carver for systematic trading methodology
- AlgoGators team for contributions
- Open source community for tooling
Last updated: January 2026