๐Ÿงฉ DLL Plugin Architecture
Every algorithm compiles into an independent shared library (.dll / .so). Entry points: createPlugin(), destroyPlugin(), getPluginConstInfo(). Your strategy derives from algoFramework_c and overrides only the callbacks you need. The core engine handles exchange connectivity, market data normalization, and order routing โ€” your code stays clean, isolated, and focused on strategy logic.

Event Callbacks

Override any of these virtual methods in your derived class. The framework dispatches events from a lock-free pipeline โ€” your callbacks receive pointers directly into the circular buffers. No copying, no allocation in the hot path.

Lifecycle

๐Ÿš€

onInitAlgo()

Called once when the algo is loaded. Register positions, start timers, initialize state. Return from this and the algo goes live.

๐Ÿ›‘

onExitAlgo()

Graceful shutdown. Kill timers, cancel open orders (if fCancelOpenOrdersOnExit is set), clean up resources.

โš™๏ธ

onSetParams()

Receives algo-specific JSON parameters from the config file. Parse with Boost.JSON. Hot-reloadable โ€” called whenever params change.

Market Data

๐Ÿ”„

onMarketdataTick()

Every trade. Receives instrumentInfo_s* and singleTradeInfo_s*. Fields: decPrice, decSize, decSizeCvd (cumulative volume delta), fTakerIsSell (aggressor direction), dtTimestamp.

๐Ÿ“–

onMarketdataBbo()

Best bid/offer update. Access via instrumentPtr->marketdataInfo.bbo.back(). Fields: bid.decPrice, bid.decSize, ask.decPrice, ask.decSize, getMid(), integrated spread tracking.

๐Ÿ“š

onMarketdataBook()

Order book snapshot. Up to MARKET_DATA_BOOK_SIZE (20) levels per side. bid[0..19] and ask[0..19] with singlePriceSize_s (price + aggregated size).

๐Ÿ“Š

onMarketdataOhlcClose()

Fires when an OHLC bar completes. Receives ohlcInfo_s*. Configurable timeframes per instrument via the config file. Bars carry price, volume, CVD, trade count, and Heikin-Ashi.

๐Ÿ†•

onInstrumentNew()

A new instrument was registered for this algo. Inspect runtimeInfo for symbol, base/quote currency, instrument type (future, perpetual, spot, option), min/max size, leverage limits, fees.

๐Ÿ“œ

onInstrumentHistoricalOk()

Historical OHLC data has been loaded and is ready. Start indicator calculations or run initial analysis before trading begins.

Orders

๐Ÿ“

onOrderCreated()

Order has been accepted by the system and is being routed to the exchange. The orderInfo_s is now live.

โœ…

onOrderFill()

Execution! Receives executionInfo_s* with decPrice, decSize, decFee, strFeeCur, and a link back to the originating order and position.

๐Ÿ”„

onOrderUpdate()

Order state changed: partial fill, modification confirmed, stop triggered. Inspect infoState.eState and eProcessingState.

โŒ

onOrderCanceled()

Order was successfully cancelled. Clean up any tracking state.

โš ๏ธ

onOrderFailed()

Order was rejected or failed. Check infoState.eErrorState and strInfo for the reason.

Positions & Assets

๐Ÿ“ˆ

onPositionRegister()

A new position was registered for your algo. Track it via the position manager.

๐Ÿ’ฐ

onAssetUpdate()

Account balance or asset value changed. Monitor equity, available margin, and P&L in real-time.

Order Management

The algoOrderManager_c (accessible as m_orderManager) handles the full order lifecycle. No raw exchange API calls โ€” use the manager and it routes correctly whether you're live, simulating, or replaying.

๐Ÿ“‹

Order Types

Enum Type Description
EOIT_MARKET Market Execute immediately at best available price
EOIT_LIMIT Limit Resting order at a specified price level
EOIT_STOP_MARKET Stop-Market Price trigger โ†’ market execution
EOIT_STOP_LIMIT Stop-Limit Price trigger โ†’ limit order placement
๐ŸŽฏ

Order Directions

Enum Meaning
EOID_BUY_OPEN_LONG Buy to open a long position
EOID_SELL_CLOSE_LONG Sell to close a long position
EOID_SELL_OPEN_SHORT Sell to open a short position
EOID_BUY_CLOSE_SHORT Buy to close a short position
EOID_BUY / EOID_SELL Generic buy/sell (direction only)
โฑ๏ธ

Time in Force

TIF Behavior
ETIF_GTC Good-Till-Cancelled โ€” rests until filled or cancelled
ETIF_FOK Fill-Or-Kill โ€” all or nothing, immediately
ETIF_IOC Immediate-Or-Cancel โ€” fill what you can, cancel the rest
ETIF_GTD Good-Till-Date โ€” active until dtGTD timestamp
๐Ÿ”€

Order Synchronization

Orders can be linked via orderInfo_s::sync() with sync types like EOST_CANCEL (cancel the other when this fills) or EOST_REDUCE (reduce the other's size). This enables OCO (One-Cancels-Other) pairs and bracket orders.

Additional flags: fPostOnly (maker-only orders), fEnableExtTradingHours, i32Leverage (set leverage per order).

๐Ÿ”‘ Order Lifecycle State Machine
Every order tracks its state: EOS_IDLE โ†’ EOS_ACTIVE โ†’ EOS_COMPLETED (or EOS_FAILED / EOS_CANCELED). The processing state (EOPS_ALGO_CREATE โ†’ EOPS_MANAGER_CREATE โ†’ EOPS_EXCHG_CREATE) lets you trace exactly where in the pipeline your order is. Location tracking (EOL_LOCAL / EOL_BROKER / EOL_EXCHANGE) confirms whether the exchange has acknowledged it.

Position Management

The algoPositionManager_c (m_positionManager) tracks every position. Positions are instrument-specific and direction-aware (long/short tracked independently).

๐Ÿ“Š

Position Structure

Each positionInfo_s contains two independent value trackers: pvLong and pvShort. Each tracks:

Field Description
decSize Total position size
decValue Total notional value
decAvgPrice Volume-weighted average entry price
decFee Total fees paid
stExecutionCount Number of fills
๐Ÿ—๏ธ

Pyramiding

The framework fully supports pyramiding โ€” multiple concurrent positions on the same instrument. Each position has a unique ui64User identifier. The position manager's findPosition() method lets you query by instrument, user value, or direction.

Use the algoClosePositionManager_c (m_closePositionManager) to close positions with market orders, limit orders, or stop-market triggers โ€” each with independent user values for tracking.

Timer System

The algoTimerManager_c (m_timerManager) provides three timer types for scheduling recurring logic, one-shot actions, and time-based alerts.

โฒ๏ธ

timerStart()

Recurring timer. timerStart(intervalMs, timerId, userPtr). Fires onTimer(timerId, userPtr) every intervalMs milliseconds. Use for periodic health checks, polling, or scheduled rebalancing.

๐Ÿ”ซ

timerFireOnce()

One-shot timer. Fires exactly once after the specified delay. Callback: onTimerFireOnce(timerId, userPtr). Use for delayed actions like order timeout handling.

๐Ÿ””

timerAlert()

Alert timer. Fires at a specific wall-clock time. Callback: onTimerAlert(timerId, userPtr). Use for session-open/close actions or scheduled events.

๐Ÿ’ก Timer Best Practices
Pass your instrumentInfo_s* as the user pointer to get context in the callback. Kill all timers in onExitAlgo() with m_timerManager.timerKillAll(). Timer IDs are arbitrary int32_t values โ€” use an enum to keep them organized.

Risk & Money Management

๐Ÿ›ก๏ธ

Risk Calculator

algoRiskCalculator_c (m_riskCalculator) โ€” configured via JSON:

Risk Type JSON Key Calculation
Fixed "FIXED" Absolute USD value per trade
Percent "PERCENT" % of account equity
Basis Points "BPS" BPS of account รท 100
Min Size ร— Factor "MIN" Min market size ร— multiplier

Methods: getRiskFixedSize(), getRiskPercent(), getRiskMinSize(). Each takes an instrumentInfo_s* for instrument-specific calculations.

๐Ÿ›‘

Stop-Loss Engine

algoStopLossCalculator_c (m_stopLossCalculator):

Method Configuration
OHLC-based Stop at a specific OHLC bar's high/low
Indicator-based Stop at an indicator value (e.g., ATR ร— N)
Multiplier setStopLossMultiplier() โ€” scale the stop distance
Max BPS Cap setMaxStopLossBPS() โ€” hard limit in basis points

Order types for stops: EOTSL_MARKET (trigger โ†’ market) or EOTSL_BBO (trigger โ†’ limit at current BBO). Use setStopLossOrderType() to choose.

๐Ÿ“

Position Sizing

Every instrument exposes runtimeInfo.mmsSize (min/max/step) and runtimeInfo.mmsLeverage (min/max/step for derivatives). Use getMinOrderSize(), getMaxOrderSize(), and makeSize() to ensure your order sizes are exchange-valid.

๐Ÿ’ต

Fee Awareness

Each instrument carries runtimeInfo.decFeeMaker and decFeeTaker. These are exchange-specific and automatically applied to fills. Your strategy can query them to decide whether to use limit orders (maker) or market orders (taker). Bitfinex and Poloniex report competitive fees.

NN & Machine Learning

ttTrader integrates with Eigen (header-only C++ linear algebra library) for on-line machine learning directly in your strategy code. No Python bridge, no external services.

๐Ÿงฎ

Linear Algebra (Eigen)

Use Eigen matrices and vectors for: linear regression (trend detection, support/resistance), PCA (dimensionality reduction on multi-timeframe indicators), Kalman filters (mid-price estimation, regime detection), OLS / Ridge regression (alpha signal construction).

๐Ÿ”„

Online Learning

Implement online gradient descent or recursive least squares to adapt strategy parameters in real-time. On every trade fill, compute the P&L feedback signal and nudge your model weights. No offline training needed โ€” the model co-evolves with the market.

๐Ÿง 

Neural Networks

Build simple feed-forward NNs using Eigen matrix operations. A 3-layer network (input โ†’ hidden โ†’ output) can be expressed in a few lines of Eigen code. Use ReLU/tanh activations, softmax for classification, MSE for regression. Train with backprop using Eigen's auto-differentiation or manual gradients.

๐Ÿง  Local LLM Integration
Connect to a local LLM inference engine (e.g., llama.cpp) via a simple IPC pipe or HTTP socket from your C++ strategy. Every N minutes, send a JSON snapshot of recent OHLCV, indicator values, and book pressure. The LLM classifies the current regime (trending / ranging / choppy) and your strategy delegates to the appropriate sub-logic. No cloud dependency. No data leaves your machine.

Example: Online Regression with Eigen

Every 100 trades, fit a linear regression of price vs. CVD slope. If Rยฒ drops below threshold, the signal is weakening โ€” exit the position.

โ†’
Auto-adaptive
Parameters evolve with market conditions, no manual tuning
โ†’
Low overhead
Eigen is header-only, SIMD-optimized, zero runtime cost until called
โ†’
Deterministic
Same input โ†’ same output. Critical for backtesting reproducibility.
// Online least-squares regression with Eigen #include <Eigen/Dense> Eigen::MatrixXd X(n, 2); // CVD slope, time Eigen::VectorXd y(n); // price // On each new data point: Eigen::VectorXd theta = (X.transpose() * X) .ldlt() .solve(X.transpose() * y); double rSquared = /* compute Rยฒ */; if (rSquared < threshold) exitPosition(); // Signal decayed

Configuration-Driven Architecture

No hardcoded instruments. No hardcoded parameters. Everything is controlled by a single JSON configuration file passed via the command line.

๐Ÿ“„

Single Config File

Launch with: ttTrader.exe config.json. The config defines:

  • System: execution mode (production / simulation / playback), exit behavior
  • Exchanges: which exchanges to connect, API credentials (stored separately)
  • Instruments: which instruments each algo subscribes to โ€” fully dynamic
  • Algos: algo DLL path, algo-specific JSON parameters
  • OHLC: timeframes per instrument for bar generation
  • Indicators: which indicators to compute on which OHLC series
๐Ÿ”

Protected API Keys

Exchange API keys are never stored in the main config. They reside in a separate, protected credentials store managed by the exchange subsystem. The config only references which exchange profile to use โ€” the keys themselves are loaded securely at runtime.

Each exchange connection supports independent API credentials, rate limit tracking, and automatic reconnection with configurable backoff.

โšก Dynamic Instrument Management
Instruments are not compiled in. The storeInstrument_c singleton holds all instruments from all configured exchanges. Your algo receives them via onInstrumentNew(). You can filter by instrument type (perpetual, future, spot, option), base/quote currency, or any runtime property. Add a new instrument to the config, restart โ€” no recompilation needed.