Trading & Scoring Engine¶
The trading core lives in engine/simulator.py and powers every scenario shown in the Dash UI. It emulates a single-position futures account with leverage, configurable take-profit/stop-loss brackets, and persistent performance tracking.
Trade Lifecycle¶
-
Entry
- Triggered via the LONG or SHORT buttons once the initial 50-candle history is displayed.
enter_trade()records the side, sets the entry price, and converts user-specified TP/SL points into absolute price levels. For example, entering long at 4,000 with a 15-point target produces a 4,015 TP and 3,985 SL.
-
Reveal Loop
- The UI advances one candle per timer tick (100 ms by default). Each new candle flows through
check_exit(). - Exit order of operations favors risk management: stop-loss detection runs before take-profit to mirror worst-case execution within a volatile candle.
- The UI advances one candle per timer tick (100 ms by default). Each new candle flows through
-
Exit Conditions
- TP Hit: Candle reaches or crosses the TP level.
- SL Hit: Candle reaches or crosses the SL level (evaluated first).
- Manual Exit: User presses EXIT, closing at the most recent close.
- Timeout: Scenario reaches the final candle without other triggers.
-
PnL Calculation
close_trade()computes raw percent return(exit - entry) / entry, scales it by account balance and leverage, and updates the running balance.- Each trade appends a record to
scenario_history, including side, realized PnL, percent return, and close reason.
-
Reset for Next Scenario
- Clicking SKIP (or switching data source/ticker) calls
sim.reset()and loads a fresh dataframe—either synthetic (GBM) or real (asset cache).
- Clicking SKIP (or switching data source/ticker) calls
Real-Time Stats & Scoreboard¶
engine/analytics.calculate_metrics() consumes scenario_history to produce the metrics displayed on the right panel:
- Win Rate: Percent of trades with PnL > 0.
- Profit Factor: Gross profits divided by gross losses (falls back to gross profits when no losses exist).
- Total PnL: Sum of realized PnL across the session.
- Trade Count: Number of completed trades.
During an active trade, the UI also computes unrealized PnL via get_unrealized_pnl() so traders can monitor floating gains relative to leverage and entry price.
Risk & Configuration¶
- Leverage: Default is 10x and can be changed by instantiating
FuturesSimulator(leverage=...). - TP/SL Units: The input fields in the right panel accept point distances (not percentages), ensuring consistency across tickers.
- Balance Persistence: Balance and performance history persist across scenarios until the app is restarted, encouraging longer practice sessions.
Extending the Engine¶
- Add support for partial exits or multiple contracts by extending the simulator with position sizing fields.
- Plug in alternative scoring metrics (Sharpe, expectancy, drawdown) by expanding
calculate_metrics()and the scoreboard component. - Introduce new exit logic (trail stops, time-based exits) by updating
check_exit()or adding auxiliary state in the simulator.