What is the purpose of the Trading System API product?
To provide programmers with a first class trading system development experience in native C++.
What was the basic design philosophy for the Trading System API library?
The Trading System API product is the result of a long running incremental process of product improvement and enhancement. Throughout the development the foremost goal was to minimize any restrictions placed on the developer in terms of the complexity of trading ideas that can be modelled. Furthermore, a strong emphasis was placed on product stability and accuracy, both of which are safeguarded by a large body of automated unit tests. Raw performance was also a major concern as with the ubiquitous availability of cheap and fast computing power we expect computational trading system development methods to continue to grow in importance.
Is the source code available?
Yes! The full API source code is available. Source code is only available for the API product itself, not the related desktop apps and other utilities.
What is the purpose of the server?
The server transmits data from the data feeds to the trading systems as well as relays orders from the trading systems to the broker/exchange. It also stores data in various timeframes for the data ‘backfill’ that trading system require at launch. The server also performs profit / loss accounting and position monitoring on a per trading system basis.
When will the server be released?
Probably by the end of 2017. If you are interested in Beta testing, please get in touch.
Are multi-leg trades supported?
Yes, the library makes a distinction between transactions and trades.
A trade may be composed of any number of transactions, but must have at least two, one to open the position and another to close it. A trade may be composes of any number of additional transactions representing position ‘add-ons’ and ‘partial exits’. The trading position must go flat or reverse for a trade to be considered closed.
Are portfolio simulations supported?
Yes, a prototype portfolio simulator exists! It facilitates the parallel simulation of any number of trading systems all using a common capital allocator. This system allows the simulation of trading systems on large and changing baskets of stocks where capital is allocated based on the overall portfolio position as well as the number of new signals generated on the latest time interval (bar). This portfolio simulator is currently ‘experimental’. A simpler way of aggregating strategy results into portfolio metrics is also available. This simply involves ‘merging’ strategy results from strategies that have already been simulated. There is no limitation on which strategy results can be merged or whether the results being merged already represent merged results. This later method is very convenient and powerful in its own right but does not allow for a common portfolio capital allocator or common money management.
How does the library account for transaction costs in simulations?
Transaction costs are comprised of slippage and commission. Commission can be accounted for either on a per-transaction basis or on a per-unit basis. User defined slippage is added for all market and stop-orders on a per-unit basis, but not for limit-orders.
Can a strategy simulation run out of memory?
The library uses advanced memory management algorithms and only loads data on demand. A strategy can thus iterate over decades of tick-by-tick data without running out of memory. At the start of a simulation, series objects grow in size until they meet the data requirement of the various indicators (e.g. moving averages) used by the strategy. After that, series objects maintain a constant memory footprint by continuously recycling address space. This architecture is also beneficial in situations where a strategy accesses data for many instruments simultaneously or during portfolio simulations when many strategies are evaluated in parallel.
How fast is strategy simulation?
A barebone trading system simulation over 10 years of daily bars takes around 4 milliseconds in ‘release’ mode on a modern desktop computer. This means that a single barebone interval/bar takes between 1 and 2 microseconds to process. Any additional indicator, user logic, or complex multi-leg position keeping will slow the simulation proportionally.
How does the library support ‘null’ / ‘undefined’ values
It is possible to check if a value coming from a database or data stream was ‘defined’ (or not ‘null’). This is helpful when working with company fundamental information which is often riddled with gaps. In traditional database systems such missing values are represented as ‘null’, which this library interprets as ‘undefined’.
Why do trading systems run as separate executables? Isn’t that unusual!
This approach has various advantages for the developer. It makes debugging straight forward. There is no need to worry about any DLL’s, or how to load them. You can step through the code using off-the-shelve debugger’s/IDE’s like MS Visual Studio. To launch a trading system, simply launch your executable passing arguments as command line arguments or via .INI files like you would for any other application. Trading systems simulations produces logs that are meant to be opened by our desktop app for rendering reports and charts.
How are limit orders handled in simulations?
The library has a conservative approach to limit order fills. In simulation, limit orders are only considered filled if the traded prices break through the limit price. A simple price touch would not trigger a fill. An optional setting called limit-order-provis determines by how much transaction prices have to penetrate the limit price before the limit order is considered filled. This improves accuracy when simulating larger transaction size.
Can SQL databases be used as data source for trading system simulation?
An experimental adaptors is available for PostgreSQL that allows users to run trading systems from data stored in a PostgreSQL database. Other databases may be added in future.
Can the library be connected to custom data sources and targets?
There is no restriction on where data can flow to or from but this will required writing specialized adaptors. Please get in touch if you have special requirements.
Can the library be used for non-financial applications?
Working with time-synchronized data streams is useful in many domains, notably machine learning involving neural networks as well as the study of cycles in many domains as well as digital signal processing. It is thus likely that the library will find uses outside of finance. Please get in touch if you have a special requirement.
Does the library run on Linux and Mac OS?
We are not there yet (June 2017). But our goal is to make both the API and the desktop Reporting App run on all three major platforms – Linux, Mac OS/X, and Windows. Theoretically the core API should compile and run on all ‘unix’ like systems without much change, subject to unit testing. Ports to new platforms can be arranged via our Professional Services.
Is the library multi-currency capable?
A single trading system can send orders to multiple exchanges regardless of the currency the instrument is priced in. For strategy simulations however, it is necessary that all price data be priced in the same currency, else aggregated performance metrics would be misleading. No implicit currency conversion functionality is built into the library. At the moment, the only way to correctly combine instruments priced in different currencies in a single trading strategy would be to convert the corresponding price series to a common currency before strategy simulation.
What is a ‘series’?
Class ‘series’ is the fundamental container class of the Trading System API library. It represents a sequence of data values that are usually time synchronized to all other data series managed by the trading system. Class series is similar to class std::vector<> of the Standard C++ Library. The primary difference between the two is that adding new data items to a series pushes the new value onto the front of the series rather than the back. This means that the latest, most current, value in a series is always to be found at position 0. Furthermore, series memory is guaranteed to be contiguous. Users may thus access the raw series data pointer for fast iteration with pointer arithmetic. Another difference between class series and class std::vector is that objects of type series do not grow indefinitely. Once a series reaches capacity, older data items are simply dropped and the address space is automatically reused by new values.
Please send any further questions to: support@TradingSystemAPI.com