tradesimr is an R-native trading execution and
simulation engine with a C++ execution core. It turns strategy
intentions and explicit orders into simulated trades, positions, cash,
P&L, risk, and performance outputs under configurable execution,
margin, funding, and cost assumptions.
The package is designed to sit between strategy packages and market-data adapters:
strategyr, produce signals,
target exposures, or order intents.tradesimr executes those intentions under simulated
exchange/accounting semantics.okxr or other local packages,
provide historical or live market data.The package’s supported CRAN-facing boundary, durable-schema policy,
execution semantics, and 0.18.x compatibility freeze are
documented in inst/CRAN-CORE.md. Local
dashboards, services, and orchestration remain optional tooling rather
than mandatory runtime components.
From the local repository:
install.packages("devtools")
devtools::install("/Users/oliver/Documents/2025/_2025-07-21_tradesimr/tradesimr")Or from GitHub:
devtools::install_github("OliverLDS/tradesimr")library(tradesimr)
bars <- data.frame(
timestamp = as.POSIXct("2026-01-01", tz = "UTC") + 0:4 * 60,
open = c(100, 101, 102, 101, 103),
high = c(101, 102, 103, 102, 104),
low = c(99, 100, 101, 100, 102),
close = c(101, 102, 101, 103, 104),
tgt_pos = c(0, 1, 1, 0, -1)
)
sim <- sim_backtest(bars, init_cash = 10000, lev = 10, fee_rt = 0.0005)
sim_metrics(sim)
sim_orders(sim)
sim_account(sim)Target positions and target weights are first translated into contract actions at their decision boundary. An opening or increasing target action fills only on its next eligible bar. At that fill price, tradesimr clips the requested quantity to the largest contract-step quantity that satisfies:
equity - transaction_fee >= initial_margin
For example, a +1 target with lev = 1 and a
nonzero fee opens a near-100%-notional long position after reserving the
fee, rather than failing because the original target consumed exactly
all cash. Explicit contract orders are not resized and still fail if
their requested quantity violates margin.
library(tradesimr)
exchange <- sim_exchange_new(list(
cash = 10000,
ctr_step = 1,
lev = 10,
mmr = 0.02,
portfolio_margin = TRUE
))
sim_asset_add(exchange, "BTC-USDT-SWAP", asset_id = 1L)
bar <- data.frame(
timestamp = as.POSIXct("2026-01-01 00:00:00", tz = "UTC"),
symbol = "BTC-USDT-SWAP",
asset_id = 1L,
open = 100,
high = 102,
low = 99,
close = 101
)
sim_exchange_add_bars(exchange, bar)
sim_submit_order(
exchange,
agent_id = "agent-a",
symbol = "BTC-USDT-SWAP",
asset_id = 1L,
side = "buy",
qty = 1,
process = TRUE
)
sim_exchange_step(exchange, bar)
sim_exchange_account(exchange)
sim_exchange_orders(exchange)The package includes separate static dashboards:
inst/dashboard/replay/: read-only backtest/replay
dashboard.inst/dashboard/live_state/: state-admin live market
dashboard.inst/dashboard/live_agent/: agent-facing trading
dashboard.Local entrypoints live under:
scripts/: project-level local orchestration.inst/scripts/: installed package examples and shell
entrypoints.Example:
zsh scripts/run_live_state_dashboard.zsh
zsh scripts/open_live_agent_dashboard.zshSimulation and exchange state can be exported as durable files:
sim_export(sim, "sim-out")
loaded <- sim_import("sim-out")Live exchange sessions can also be saved and loaded:
sim_exchange_save(exchange, "exchange-out")
exchange2 <- sim_exchange_load("exchange-out")tradesimr is under active development. The current
design favors stable event schemas, replayability, and explicit
exchange/accounting boundaries before expanding production-grade live
service features.
Bulk portfolio replay exposes phase timings through
sim_portfolio_target_replay(..., profile = TRUE). The
installed Vox-style fixture can be run locally without affecting the
normal test suite:
source(system.file("examples", "vox_arena_replay_benchmark.R", package = "tradesimr"))
run_vox_arena_replay_benchmark(n_days = 252, use_bulk = TRUE, profile = TRUE)$timingsUse fixture = "vox" for the Arena-shaped workload: eight
assets, 64 single-asset deterministic accounts, and two multi-asset
accounts. Profiling artifacts are deliberately local rather than package
fixtures:
run_vox_arena_replay_benchmark(
n_days = 252, fixture = "vox", profile = TRUE,
memory_profile = TRUE, artifact_path = "local-benchmark/vox"
)$metricsThe artifact directory receives scalar phase timings, per-boundary
latency, peak memory, sampled garbage collections, and, when enabled,
Rprof and large-allocation Rprofmem
traces.
The test suite always verifies the timing contract on a small
fixture. To run the full 252-boundary performance workload, set
TRADESIMR_RUN_PERF_TESTS=true. Set
TRADESIMR_MAX_BULK_REPLAY_SECONDS only when enforcing a
budget on a controlled machine; no hardware-dependent wall-time limit is
imposed by default.