All reference chapters

13. Appendix

This appendix collects the reference tables that the preceding chapters rely on: the numeric values of every enumeration exported by tse_enums.h, tse_duration.h and tse_log.h; the complete name map from every user-facing action to its C, C++ and Python spelling; the status and last-error contract shared by all three surfaces; the labels, identifiers, boundary conventions and fixed buffer capacities of the C ABI; the schema of the SQLite table into which the blotter journals executed trades; and the defaults that the two wrappers apply on top of a default-free C surface. Sections A through D and F are taken from the current headers of ABI generation 6; section E has no header behind it and is taken from the engine's own blotter SQL, which is internal to the library.

A. Enumerations

Enumeration values are identical across all three surfaces; only the spelling differs. The C constants live in the named headers; the C++ wrapper mirrors each as an enum class in namespace tse with the same lower-snake enumerator names (exceptions are noted per table); the Python wrapper mirrors each as an IntEnum class in module tse with PascalCase member names. For string forms the library exports tse_instrument_to_string, tse_underlying_to_string, tse_venue_to_string, tse_side_to_string, tse_cmp_to_string, tse_price_type_to_string, tse_quantity_mode_to_string, tse_tif_to_string, tse_txn_type_to_string and tse_priority_to_string in tse_enums.h, plus tse_duration_to_string in tse_duration.h. In the tables below the C prefix named in each lead is stripped from the constant column.

TseInstrument (tse_enums.h, prefix tse_instrument_) — C++ tse::Instrument, Python tse.Instrument.

ConstantValueConstantValue
undefined0equity1
option2future4
debt8currency16
index32

TseUnderlying (tse_enums.h, prefix tse_underlying_) — C++ tse::Underlying, Python tse.Underlying.

ConstantValueConstantValue
undefined0equity1
debt2currency4
commodity8crypto16
etf32index64

TseVenue (tse_enums.h, prefix tse_venue_) — C++ tse::Venue, Python tse.Venue; the enumerator names are identical on all three surfaces.

ConstantValueConstantValueConstantValue
undefined0NYSE1NASDAQ2
CBOE3CME4ICE5
TSX6B37BMV8
BCS9BVC10BVL11
BYMA12LSE13EUREX14
EURONEXT15MOEX16XETRA17
SIX18BME19BIT20
OMX21OSLO22WSE23
BIST24TSE25HKEX26
ASX27SSE28SZSE29
NSE30BSE31KRX32
SGX33TWSE34IDX35
SET36MYX37BINANCE38
COINBASE39KRAKEN40BITSTAMP41
OKX42BYBIT43BITFINEX44
KUCOIN45GEMINI46HTX47
user_defined_148user_defined_249user_defined_350
user_defined_451user_defined_552user_defined_653
user_defined_754user_defined_855user_defined_956
user_defined_1057US58EU59
UK60

TseSide (tse_enums.h, prefix tse_side_) — the full mirror of the engine's side/quotation enumeration; the numeric values are the engine codes, and long carries the aliases bid/buy while short carries ask/sell. C++ tse::Side spells the keyword collisions long_ and short_; Python tse.Side uses Long and Short.

ConstantValueConstantValue
undefined0neutral1
long2short4
mid8trade16
quote32general64

TseCmp (tse_enums.h, prefix tse_cmp_) — C++ tse::Cmp, Python tse.Cmp. Directions: ge >=, lt <, gt >, le <=, eq =, ne !=.

ConstantValueConstantValue
ge0lt1
gt2le3
eq4ne5

TsePriceType (tse_enums.h, prefix tse_price_) — C++ tse::PriceType; the Python class is named tse.Price.

ConstantValueConstantValue
undefined0market1
limit2general3

TseTxnType (tse_enums.h, prefix tse_txn_) — the transaction kind of a multileg leg, engine codes. C++ tse::TxnType, Python tse.TxnType (Enter, Exit, StopLoss, StopLossTrailing, TakeProfit, Chaining, Forced, TakeProfitTrailing).

ConstantValueConstantValue
undefined0enter1
exit2stoploss4
stoploss_trailing8takeprofit16
chaining32forced64
takeprofit_trailing128

TsePriority (tse_enums.h, prefix tse_priority_) — the order priority of a multileg leg, engine codes. C++ tse::Priority, Python tse.Priority (NonReplaceable for the third value).

ConstantValueConstantValue
undefined0replaceable1
non_replaceable2

TseQuantityMode (tse_enums.h, prefix tse_quantity_) — C++ tse::QuantityMode; the Python class is named tse.Quantity, with FromSignal for the last value.

ConstantValueConstantValue
undefined0all1
fixed2from_signal3

TseTif (tse_enums.h, prefix tse_tif_) — C++ tse::Tif, Python tse.Tif.

ConstantValueConstantValue
undefined0day1
gtd2gtc3
gts4atc5
opg6fok7
ioc8aon9

TseMode (tse_enums.h, prefix tse_mode_) — the account licensing mode set by tse_account_set_mode. C++ tse::Mode, Python tse.Mode.

ConstantValueConstantValue
backtest0live1

TseDuration (tse_duration.h, prefix tse_duration_) — C++ tse::Duration with identical spellings; Python tse.Duration in PascalCase (Duration.FiveSeconds, Duration.ThirtyMinutes, ...).

ConstantValueConstantValueConstantValue
nanoseconds0microseconds1milliseconds2
seconds3five_seconds4ten_seconds5
thirty_seconds6minutes7two_minutes8
three_minutes9five_minutes10ten_minutes11
fifteen_minutes12thirty_minutes13hours14
two_hours15three_hours16six_hours17
eight_hours18twelve_hours19days20
two_days21three_days22weeks23
months24quarters25years26

TseLogLevel (tse_log.h, prefix tse_log_) — C++ tse::LogLevel ends in none; the Python member for value 6 is spelled LogLevel.Off.

ConstantValueConstantValue
trace0debug1
info2warning3
error4critical5
none6

The remaining exported enumerations are declared next to the surface they belong to. TseStatus (tse_types.h) is tabulated in the next section of this appendix; the others are tabulated in their own chapters: TseStorageRegime and TseCurrency in tse_types.h; TseMdType in tse_marketdata.h; TseRuleType in tse_rule.h; TseRiskPolicyType in tse_risk.h; TseOhlcvField and TseBidAskField in tse_execution.h; TseBookLevelKind, TseBookMessageKind and TseBookMissingLevel in tse_book.h.

B. Name map

The map below covers every user-facing action of the export layer. In the C++ column an unqualified name is a method of tse::Account; in the Python column an unqualified name is a method of tse.Account; a Market., Execution., Book., ExPost. or Storage. prefix marks the holder object, and a tse:: or tse. prefix marks a free function of the namespace or module. Where a family of C functions differs only in a type or kind suffix, the row writes the varying part as <t> or <kind> and lists the admissible values.

Library, versions and diagnostics.

ActionCC++Python
set initial params (folders, log level)tse_set_initial_paramstse::setInitialParamstse.set_initial_params
initialization error texttse_last_init_errortse::lastInitErrortse.last_init_error
set log leveltse_set_log_leveltse::setLogLevelAccount.set_log_level
ABI versiontse_abi_versiontse::abiVersiontse.abi_version / Account.abi_version
supported durationstse_supported_durationstse::supportedDurationstse.supported_durations
supported market-data typestse_supported_mdtypestse::supportedMdTypestse.supported_md_types
fix-point scale / encode / decodetse_finvalue_scale, tse_finvalue_from_double, tse_finvalue_to_doubletse::finValueScale, finValueFromDouble, finValueToDoubletse.fin_value_scale, fin_value_from_double, fin_value_to_double
last engine errortse_last_errorthrown as tse::Errorraised as tse.TseError

Account and contracts.

ActionCC++Python
create account (regime, currency required)tse_account_createtse::Account constructortse.Account constructor
destroy accounttse_account_destroyAccount destructorclose
set licensing modetse_account_set_modesetModeset_mode
set equity baseline and risk-free ratetse_set_account_equitysetAccountEquityset_account_equity
declare contracttse_add_contract / tse_add_contract_idaddContractadd_contract
look up contract idtse_get_contract_idgetContractIdget_contract_id

Market data.

ActionCC++Python
create adaptertse_market_createcreateMarketcreate_market
push tick, <t> in ohlcv, bidask, tradetse_market_push_<t>_by_name / _by_idMarket.pushOhlcv / pushBidAsk / pushTrade (symbol and id overloads)Market.push_<t>_by_name / _by_id
push executed tradetse_market_push_executed_by_name / _by_idMarket.pushExecutedMarket.push_executed_by_name / _by_id
push book messagetse_market_push_book_by_name / _by_idMarket.pushBookMarket.push_book_by_name / _by_id

Execution.

ActionCC++Python
create Simulator executiontse_exec_create_simulatorcreateSimulatorcreate_simulator
create custom executiontse_exec_create_customcreateCustomcreate_custom
report a filltse_exec_apply_fillExecution.applyFillExecution.apply_fill
fully-executed order counttse_exec_get_countExecution.getCountExecution.get_count
running flagtse_exec_is_runningExecution.isRunningExecution.is_running

Inputs and patterns.

ActionCC++Python
typed input, <t> in ohlcv, bidask, trade, executed, booktse_add_input_<t>addInputOhlcv / addInputBidAsk / addInputTrade / addInputExecuted / addInputBookadd_input_<t>
built-in book-imbalance inputtse_add_input_book_imbalanceaddInputBookImbalanceadd_input_book_imbalance
record a value from a processortse_storage_pushStorage.pushStorage.push
stored value counttse_storage_sizeStorage.sizeStorage.size
pattern, <kind> in comparison, crossover, threshold, peak, timestamp, formulatse_add_pattern_<kind>addPatternComparison / addPatternCrossover / addPatternThreshold / addPatternPeak / addPatternTimestamp / addPatternFormulaadd_pattern_<kind>

Rules.

ActionCC++Python
market rule (entry / exit / rebalance)tse_add_rule_marketaddRuleMarketadd_rule_market
risk rule (stop-loss / take-profit families)tse_add_rule_riskaddRuleRiskadd_rule_risk
multileg ruletse_add_rule_multilegaddRuleMultilegadd_rule_multileg
bracket ruletse_add_rule_bracketaddRuleBracketadd_rule_bracket
OCO ruletse_add_rule_ocoaddRuleOcoadd_rule_oco
amend rule, <kind> in cancel, replace, modifytse_add_rule_<kind>addRuleCancel / addRuleReplace / addRuleModifyadd_rule_<kind>

Robot lifecycle and bulk actions.

ActionCC++Python
add robottse_add_robotaddRobotadd_robot
start / stop / halttse_start / tse_stop / tse_haltstart / stop / haltstart / stop / halt
cancel all resting orderstse_cancel_allcancelAllcancel_all
close the whole positiontse_sale_allsaleAllsale_all
halt, then cancel alltse_halt_and_cancel_allhaltAndCancelAllhalt_and_cancel_all
halt, then close positiontse_halt_and_sale_allhaltAndSaleAllhalt_and_sale_all
halt, cancel and closetse_halt_and_cancel_sale_allhaltAndCancelSaleAllhalt_and_cancel_sale_all

Results and external-trade booking.

ActionCC++Python
account summarytse_get_summarygetSummaryget_summary
per-robot summarytse_get_robot_summarygetRobotSummaryget_robot_summary
all summariestse_get_summariesgetSummariesget_summaries
retained tradestse_get_tradesgetTradesget_trades
book external trade (moves the portfolio)tse_book_tradebookTradebook_trade without snapshots
book against supplied exposure (pure P&L)tse_book_trade_with_exposurebookTradeWithExposurebook_trade with both snapshots

Portfolio, reset and risk policies.

ActionCC++Python
portfolio aggregate statetse_get_portfolio_stategetPortfolioStateget_portfolio_state
single position statetse_get_position_stategetPositionStateget_position_state
subscribe / unsubscribe markingtse_portfolio_subscribe / tse_portfolio_unsubscribeportfolioSubscribe / portfolioUnsubscribeportfolio_subscribe / portfolio_unsubscribe
register a position without an adaptertse_portfolio_add_contractportfolioAddContractportfolio_add_contract
reset whole portfoliotse_reset_portfolioresetPortfolioreset_portfolio
reset one positiontse_reset_positionresetPositionreset_position
threshold risk policytse_add_risk_policyaddRiskPolicyadd_risk_policy
trading-window risk policytse_add_risk_policy_time_periodaddRiskPolicyTimePeriodadd_risk_policy_time_period
remove risk policytse_remove_risk_policyremoveRiskPolicyremove_risk_policy

Order books.

ActionCC++Python
create a booktse_book_createcreateBookcreate_book
destroy a book earlytse_book_destroyaccount-owned, no callaccount-owned, no call
apply a messagetse_book_applyBook.applyBook.apply
whole-book imbalancetse_book_imbalanceBook.imbalanceBook.imbalance
imbalance to price boundstse_book_imbalance_to_boundBook.imbalanceToBoundBook.imbalance_to_bound
imbalance to depthtse_book_imbalance_to_depthBook.imbalanceToDepthBook.imbalance_to_depth
one side's aggregatestse_book_side_statsBook.sideStatsBook.side_stats
aggregates to a boundtse_book_side_stats_to_boundBook.sideStatsToBoundBook.side_stats_to_bound
top level rowstse_book_levels_topBook.levelsTopBook.levels_top
book error texttse_book_last_errorthrown as tse::Errorraised as tse.TseError

ex_post statistics and features.

ActionCC++Python
write the scores databasetse_ex_post_saveexPostSaveex_post_save
validate an existing databasetse_ex_post_loadexPostLoadex_post_load
create a live scoring objecttse_ex_post_createcreateExPostcreate_ex_post
destroy ittse_ex_post_destroyExPost destructorExPost.close
robot count / label / bucket counttse_ex_post_robot_count / _robot_label / _bucket_countExPost.robotCount / robotLabel / bucketCountExPost.robot_count / robot_label / bucket_count
parameter axistse_ex_post_param_count / tse_ex_post_param_nameExPost::paramCount / paramNameExPost.param_count / param_name
momentum featuretse_ex_post_feature_momentumExPost.featureMomentumExPost.feature_momentum
EWMA featuretse_ex_post_feature_ewmaExPost.featureEwmaExPost.feature_ewma
level-crossings featuretse_ex_post_feature_level_crossingsExPost.featureLevelCrossingsExPost.feature_level_crossings

Persistence.

ActionCC++Python
register input processor, <t> in ohlcv, bidask, trade, executedtse_register_input_processor_<t>registerInputProcessor / registerInputProcessorBidAsk / registerInputProcessorTrade / registerInputProcessorExecutedregister_input_processor / _bidask / _trade / _executed
register formula processortse_register_formula_processorregisterFormulaProcessorregister_formula_processor
savable input, <t> in ohlcv, bidask, trade, executedtse_add_input_<t>_by_keyaddInputOhlcvByKey / addInputBidAskByKey / addInputTradeByKey / addInputExecutedByKeyadd_input_<t>_by_key
savable formula patterntse_add_pattern_formula_by_keyaddPatternFormulaByKeyadd_pattern_formula_by_key
save / load a robot recipetse_save / tse_loadsave / loadsave / load
bind a loaded inputtse_bind_inputbindInputbind_input

Data loading, timeserie toolbox and grid search.

ActionCC++Python
load OHLCV CSVtse_load_ohlcv_csv / tse_load_ohlcv_csv_exAccount::loadOhlcvCsvload_ohlcv_csv
load bid/ask CSVtse_load_bidask_csvAccount::loadBidAskCsvload_bidask_csv
load trade CSVtse_load_trade_csvAccount::loadTradeCsvload_trade_csv
free loaded tickstse_free_ticks / tse_free_bidask_ticks / tse_free_trade_tickshandled by std::vectorhandled by lists
CSV-loader error texttse_last_csv_errorthrown as tse::Errortse.last_csv_error
columnar CSV readertse_csv_reader_*tse::CsvReadertse.CsvReader
CSV writertse_csv_writer_*tse::CsvWritertse.CsvWriter
head / tail subrangetse_timeserie_head_<t> / tse_timeserie_tail_<t>tse::head / tse::tail (overloads for every serie kind)tse.head / tse.tail (scalar series only)
split by durationtse_timeserie_split_by_duration_<t>tse::splitByDurationtse.split_by_duration (scalar series only)
diff / lag / log transformtse_timeserie_diff_scalar / _lag_scalar / _log_scalartse::diff / tse::lag / tse::logtse.diff / tse.lag / tse.log
grid searchtse_run_gridtse::runGridtse.run_grid

C. Statuses and errors

Every C entry point that can fail returns TseStatus; handle-creating functions (tse_account_create, tse_market_create, tse_exec_create_simulator, tse_exec_create_custom, tse_book_create, tse_ex_post_create) return the handle directly, or NULL on error. Every C entry point is wrapped in a noexcept try/catch inside the library: no exception ever crosses the C boundary. A failure comes back as tse_error or a NULL handle, and the reason is a human-readable text waiting in the last-error channel that owns the failed call.

TseStatus (tse_types.h) — the two constants of the status type.

ConstantValue
tse_ok0
tse_error1

Each area of the library has exactly one last-error channel, scoped to match the lifetime of what it reports on.

ChannelDeclared inScope
tse_last_error(account)tse_error.hPer account: any failed call belonging to that account or its child handles.
tse_last_init_error()tse_params.hProcess-wide: tse_set_initial_params, which runs before any account exists.
tse_last_csv_error()tse_dataplane.hThread-local: the CSV loaders tse_load_*_csv; empty when the last load on this thread succeeded.
tse_book_last_error(book)tse_book.hPer book handle; a failed tse_book_create itself reports through tse_last_error(account).
tse_csv_reader_error(reader)tse_timeserie.hPer CSV-reader handle.
tse_csv_writer_error(writer)tse_timeserie.hPer CSV-writer handle.
tse_connection_last_error(client)tse_connection/tse_connection_client.hPer connection client, in the separate connection library.

The C++ wrapper turns every failed status into an exception. It throws exactly one type, tse::Error, whose message carries the last-error text of the channel the failed call belongs to; the pre-account entry points stay exception-free (tse::setInitialParams is noexcept and returns bool, with the detail in tse::lastInitError()).

The Python wrapper raises tse.TseError under the same contract, and mirrors the pre-account channels as module-level functions tse.last_init_error(lib) and tse.last_csv_error().

struct Error final : std::runtime_error {
	using std::runtime_error::runtime_error;
};
try:
    account = tse.Account("research", tse.StorageRegime.Mem)
    account.start("robot")
except tse.TseError as error:
    print(error)

D. Labels, identifiers and capacities

Labels and identifiers. Entities are addressed by string labels: the account, the market adapters, the execution, the Inputs, the Patterns, the Rules and the Robots are all created under a label and referenced by it everywhere else — a Pattern names the Inputs it observes, a Rule names its Pattern, a Robot names its Rules. Contracts are the exception: they are addressed by symbol, or by the numeric uint64_t contract id returned by tse_add_contract_id / tse_get_contract_id. In a record that carries both, such as TseRetained, a contractId of zero means addressing by symbol.

Fixed string capacities. At the C boundary these strings live in fixed-size fields: labels occupy 64 bytes (63 useful characters); symbols and order identifiers occupy 32 bytes (31 useful characters). The useful length is one less than the capacity because of the NUL terminator. Oversized values fail loud: the call is rejected on input and the owning last-error channel carries the diagnostic — "the value exceeds the boundary capacity (63 characters for labels, 31 for symbols and identifiers)". Nothing is silently truncated.

FieldC fieldCapacityUseful lengthCarried by
contract symbolsymbolchar[32]31TseTrade, TseRetained, TseOrder, TseLegDescriptor.contractSymbol
client order idclientOrderIdchar[32]31TseTrade, TseRetained, TseOrder
broker order idbrokerOrderIdchar[32]31TseTrade, TseRetained
rule labelruleLabelchar[64]63TseTrade, TseRetained, TseOrder
robot labelrobotLabelchar[64]63TseTrade, TseRetained, TseOrder

The two order identifiers. An order carries two identifiers with distinct birthplaces. The client order id is minted on the client side when the order is created; the engine's intended-trade record carries it, the fill callback of a custom execution receives it in TseOrder, and tse_exec_apply_fill addresses fills by it. The broker order id is minted at the execution point — by the Simulator, or by the venue behind a custom execution — when the order is accepted or filled; the engine's executed-trade record carries it. The retained trade, journaled by the blotter, carries both, which is exactly the identifier block that recurs across TseTrade and TseRetained.

Capacity-in / count-out. tse_get_trades, tse_get_summaries and tse_book_levels_top share one protocol: pass the capacity of the output array in *inoutCount; on return it holds the number actually written; pass a null output pointer to query the required count without writing. When the capacity is smaller than the number of available elements the surplus is silently not written — query the count first. The wrappers hide the round trip entirely.

Count-then-buffer. The timeserie toolbox (tse_timeserie.h) and the ex_post feature readers (tse_ex_post.h) use the sibling convention: a NULL output buffer makes the call store the required element count (for features, the row count into *inoutRowCount) and touch nothing else.

Zero time bounds. In tse_get_trades, and fixed as part of the ABI: a zero fromNanoseconds means the 1970 epoch and a zero toNanoseconds means the 2100 epoch, so zero bounds mean "no bound" and 0, 0 selects everything.

Whole-row truncation of matrix extraction. tse_csv_reader_read_matrix_by_name / _by_index return a row-major flat buffer whose capacity and written count are in double elements; on a short buffer truncation drops whole rows only, so the written count always stays a multiple of the column count.

structSize stamping. TseBookMessage, TseCsvOptions and TseCsvWriterOptions carry a leading structSize field that the caller must set to sizeof of the struct; the C++ and Python wrappers fill it automatically.

Borrowed strings. A char const* returned by a CSV reader or writer handle stays valid until the next read on the same handle or its destruction. tse_last_csv_error is thread-local and stays valid until the next load on the same thread. tse_ex_post_robot_label copies into a caller buffer, NUL-terminated and truncated to the given capacity; tse_csv_reader_cell_* writes up to capacity-1 bytes plus a NUL, and with a NULL output stores the cell length instead.

Absent-value markers. TSE_ABSENT_HIGH_PRICE ((double)INT64_MIN) and TSE_ABSENT_LOW_PRICE ((double)INT64_MAX) mark a position with no observed extreme yet, with the matching timestamps written as zero (tse_trades.h); C++ mirrors them as tse::absentHighPrice / tse::absentLowPrice. TSE_ABSENT_MULTIPLE (zero) marks a placeholder exposure node in TsePositionState.multiple (tse_portfolio.h).

Versions. tse_abi_version() returns 6; the robot recipe written by tse_save uses persistence schema version 3, and a mismatched schema is rejected on load with a diagnostic.

Reading the two identifiers off a retained trade:

std::vector<tse::Trade> const trades {account.getTrades()};
std::string const
	client {trades.front().clientOrderId},
	broker {trades.front().brokerOrderId};
for trade in account.get_trades():
    print(trade.clientOrderId.decode(), trade.brokerOrderId.decode())

The C capacity-in / count-out round trip, and what the wrappers do in its place:

size_t count = 0;
tse_get_trades(account, 0, 0, NULL, NULL, &count);

TseTrade* trades = calloc(count, sizeof(TseTrade));
tse_get_trades(account, 0, 0, NULL, trades, &count);

free(trades);
std::vector<tse::Trade> const trades {account.getTrades()};
trades = account.get_trades()

E. The retained trades table

An account created under a storage regime that includes the database — tse_storage_regime_db, C++ tse::StorageRegime::db, Python tse.StorageRegime.Db — journals every executed trade into a SQLite file. The file lives in the data folder passed as TseInitialParams.dataFolderPath to tse_set_initial_params; when no data folder has been configured the engine places it next to the running executable. Its name is the account label followed by _Blotter_retained_trades.sqlite3.db. The trades themselves occupy one table, retained_trades, and this section is its schema, so that a client can open the file and query it with plain SQL instead of going through the API.

The columns fall into six groups. The order identifiers are client_order_id and broker_order_id, the pair described above under labels and identifiers. The labels are rule_label, which is stored inline, robot_id, which is a foreign key into the strategies table whose label column holds the robot label, and contract_id, which is the numeric contract id rendered as decimal text and is a foreign key into the contracts table whose name column holds the symbol. The timestamps are ts_mkt_event and ts_execution, both nanoseconds since the 1970 epoch. The price and quantity block is price, quantity, fee and booked_pl together with the codes that classify the trade and the order behind it. The contract-exposure snapshot taken at the moment of the trade is the prev_contract_exposure_* family plus the four position-extreme columns. The portfolio-exposure snapshot is the prev_portfolio_exposure_* family.

Every *_code column is declared as a foreign key into a small seeded lookup table that names its values, and the numbers are the same engine codes tabulated in the enumerations section. Three of those tables are seeded short of the enumeration they name, which matters the moment a query joins on them. side_types, referenced by all five side columns, holds exactly three rows — 1 neutral, 2 long_, 4 short_, the two directional names carrying the trailing underscore of the C++ keyword workaround — and has no row for the undefined side, code 0. price_types holds 0 undefined, 1 market and 2 limit, and has no row for general, code 3. quantity_types holds 0 undefined, 1 all and 2 fixed, and has no row for from_signal, code 3. The remaining tables cover their enumerations in full: book_mode_types (0 undefined, 1 main, 2 split), execution_types (0 undefined, 1 ongoing, 2 completed_full, 4 completed_partial), tif_types matching TseTif and priority_types matching TsePriority. Because the seeding is partial, resolve a code with a LEFT JOIN: an inner join on side_types, price_types or quantity_types silently drops every row whose code has no lookup row.

ColumnSQL typeMeaning
idINTEGER PRIMARY KEY AUTOINCREMENTRow key; carries no trading meaning.
client_order_idTEXTThe client order id, minted on the client side.
broker_order_idTEXTThe broker order id, minted at the execution point.
contract_idTEXT NOT NULLThe contract id as decimal text; joins contracts(contract_id).
rule_labelTEXT NOT NULLLabel of the rule that produced the order.
robot_idINTEGER NOT NULLJoins strategies(id); the robot label is strategies.label.
ts_mkt_eventINTEGER NOT NULLTimestamp of the market event behind the trade, nanoseconds since the epoch.
ts_executionINTEGER NOT NULLTimestamp of the execution, nanoseconds since the epoch.
priceREAL NOT NULLExecution price of the trade.
quantityREAL NOT NULLExecuted quantity.
feeREAL NOT NULLFee charged on this trade.
booked_plREAL NOT NULLRealized profit and loss booked by this trade.
txn_side_codeINTEGER NOT NULLSide of the transaction; side_types.
pos_side_codeINTEGER NOT NULLSide of the position the trade belongs to; side_types.
book_mode_codeINTEGER NOT NULLBooking mode of the trade; book_mode_types.
execution_codeINTEGER NOT NULLExecution state of the order; execution_types.
price_type_codeINTEGER NOT NULLPrice type of the order; price_types.
prev_contract_exposure_quantityREAL NOT NULLPosition quantity in the contract snapshot.
prev_contract_exposure_unrealized_plREAL NOT NULLUnrealized profit and loss of that position.
prev_contract_exposure_acquisition_price_tsINTEGER NOT NULLTimestamp of the average acquisition price.
prev_contract_exposure_acquisition_priceREAL NOT NULLAverage acquisition price of the position.
pos_high_price_tsINTEGER NOT NULLTimestamp of the highest price observed on the position; zero when none.
pos_high_priceREAL NOT NULLHighest observed price; TSE_ABSENT_HIGH_PRICE when the extremes are not seeded.
pos_low_price_tsINTEGER NOT NULLTimestamp of the lowest price observed on the position; zero when none.
pos_low_priceREAL NOT NULLLowest observed price; TSE_ABSENT_LOW_PRICE when the extremes are not seeded.
prev_contract_exposure_sideINTEGER NOT NULLSide of the position in the snapshot; side_types.
prev_portfolio_exposure_acquisition_valueREAL NOT NULLAcquisition value of the whole portfolio.
prev_portfolio_exposure_sideINTEGER NOT NULLSide of the portfolio; side_types.
prev_portfolio_exposure_market_value_sideINTEGER NOT NULLSide of the portfolio market value; side_types.
exchange_rate_numeratorINTEGER NOT NULLNumerator of the rational exchange rate stored with the trade.
exchange_rate_denominatorINTEGER NOT NULLDenominator of that rate; the monetary columns are stored unconverted. The two rate columns belong to the cross-currency work that is still in the process of shipping; on a single-currency account they carry the unit rate.
tif_type_codeINTEGER NOT NULLTime in force of the order; tif_types.
quantity_type_codeINTEGER NOT NULLQuantity mode of the order; quantity_types.
priority_type_codeINTEGER NOT NULLOrder priority; priority_types.
prev_contract_exposure_market_price_tsINTEGER NOT NULLTimestamp of the marking price of the position.
prev_contract_exposure_market_priceREAL NOT NULLMarking price of the position.
prev_contract_exposure_market_price_seededINTEGER NOT NULLOne when the position has been marked at least once, zero otherwise.
prev_portfolio_exposure_market_valueREAL NOT NULLMarket value of the whole portfolio.
prev_portfolio_exposure_unrealized_plREAL NOT NULLUnrealized profit and loss of the whole portfolio.

The table carries one compound uniqueness constraint, written out at the end of this section. The insert is written as ON CONFLICT ... DO NOTHING against exactly this tuple, which makes journaling idempotent: one executed trade cannot be written twice. A fill that reaches the blotter a second time — a replayed message, a reconnect that redelivers the same execution report, a repeated run over the same data into the same file — matches the constraint and is dropped instead of inflating the trade count and double-counting booked_pl. Note what the tuple deliberately omits: the two order identifiers and the price play no part in it, so a duplicate is recognized even when the broker restates an identifier. Indexes cover the two timestamps, the rule label, the contract and the robot, each alone and in the combinations a reporting query normally uses, so time-ranged and per-robot selections stay cheap on a large file.

The same records reach the caller without any SQL through tse_get_trades, which fills an array of TseTrade — C++ getTrades, Python get_trades. TseTrade carries the identifiers, the labels, both timestamps, the price and quantity block and both exposure snapshots, resolving contract_id back into the symbol character field and robot_id back into robotLabel; rule_label, stored inline in the table, is copied straight into ruleLabel with nothing to resolve. Four column families stay in the table only: the exchange-rate pair, the order-detail codes price_type_code, tif_type_code, quantity_type_code and priority_type_code, which are exposed instead through TseRetained, the prev_contract_exposure_market_price_seeded flag, and prev_portfolio_exposure_market_value_side.

The constraint reads:

UNIQUE(contract_id, rule_label, robot_id, ts_mkt_event, ts_execution,
       quantity, book_mode_code, pos_side_code,
       exchange_rate_numerator, exchange_rate_denominator)

F. Wrapper defaults

The C ABI itself carries no defaults: every struct field and every argument is required, and coreId parameters are mandatory (a negative value runs the component without a separate pinned thread). The two wrappers reintroduce the following defaults — everything not listed here remains required on all three surfaces.

ParameterC++ default (tse.hpp)Python default (tse.py)
account currencyCurrency::usdCurrency.Usd
account core idcoreId = -1core_id=-1
library locationlinked at build timelib_path=None: the TSE_EXPORT_LIB environment variable, else the platform library filename
execution requiredDataLength3required_data_length=3
execution core id-1-1
input and pattern core id-1-1
getTrades / get_trades time bounds0, 0 (no bound)0, 0 (no bound)
getTrades / get_trades robot selectorempty string = all robotsrobot_label=None = all robots
threshold risk-policy contractempty string = portfolio-widecontract_symbol=None = portfolio-wide
time-period policy time zoneempty string = engine behaviourtime_zone_name=""
removeRiskPolicy contractseparate overloads with and withoutcontract_symbol=None
book_trade snapshotstwo distinct methodsboth None = portfolio-moving mode; both set = exposure mode
CSV loader options (CsvOptions / make_csv_options)separator ,, hasHeader true, ignoreParseErrors false, bufferSize 0, empty format and column namesseparator=",", has_header=True, empty format and column names
CsvReader constructionCsvOptions {} (so hasHeader true)separator=",", has_header=False, ignore_parse_errors=False, buffer_size=0
CsvWriter constructionseparator ,, formatTimestamps false, empty dateFormatseparator=",", format_timestamps=False, date_format=None
CSV write headers{} = no header rowheaders=None = no header row
head / tail lengthn = 5n=5
diff / lag / logoffset or lag 1, Currency::usd1, Currency.Usd
grid-search currencyCurrency::usdCurrency.Usd
initial paramsnone: InitialParams is a plain aggregate with an explicit applyLogLevel flagdata_folder="", log_folder="" and log_level=None all mean "leave unchanged"

Note the one asymmetry in the CSV readers: the C++ CsvReader default (CsvOptions {}) assumes a header row, while the Python CsvReader default (has_header=False), like the C-level tse_csv_reader_create(NULL), assumes none. The Python tick-loader helper make_csv_options assumes a header row, matching its C++ counterpart.

Version 5.0.0.0