Strategy Interval Loop
The first tutorial demonstrates the most basic of all strategies. It prints a greeting and then keeps printing the timestamp of the current bar ('interval'). Lets have a look at the strategy code.
Tutorial 101:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9) (10)
(11)
|
#include "tsa.h"
class my_strategy : public tsa::strategy { void on_start(void) override { std::cout << "Strategy starts!" << std::endl; }
void on_bar_close(void) override // same as 'on_bar_close()' { if (first()) { std::cout << "hello trader!" << std::endl; }
std::cout << "Bar: " << bar_count() << "\t " << "Timestamp: " << timestamp() << std::endl; }
void on_end(void) override { std::cout << "Strategy ends!" << std::endl; }
};
try { my_strategy s; s.run("2012-01-01", "2012-01-15"); } catch (std::exception& x) { std::cerr << x.what() << std::endl; } |
Program Output |
Strategy starts! hello trader! Bar: 1 Timestamp: 2012-01-01T00:00:00.0 Bar: 2 Timestamp: 2012-01-02T00:00:00.0 Bar: 3 Timestamp: 2012-01-03T00:00:00.0 Bar: 4 Timestamp: 2012-01-04T00:00:00.0 Bar: 5 Timestamp: 2012-01-05T00:00:00.0 Bar: 6 Timestamp: 2012-01-06T00:00:00.0 (... lines skipped here ...) Strategy ends! press any key to exit... |
(1) |
#include "tsa.h"
Includes the main library header 'tsa.h' which in turn includes all other relevant headers. Please do not include headers individually as header names will change in future versions. |
(2) |
class my_strategy : public tsa::strategy {
Derives a custom strategy class from class tsa::strategy from which all new strategy classes must inherit. |
(3) |
void on_start(void) override {
Defines an override of the virtual strategy::on_start() member. The on_start() member can be used for various initializations such as connecting stream and instrument objects to data sources. In this short tutorial on_start() prints a short message. |
(4) |
void on_bar_close(void) override {
Defines an override of the virtual strategy::on_bar_close() member ( on_next() is defined as a synonym of on_bar_close(); use whichever you prefer).
The on_bar_close() member is called just after the close of each bar. Normally this is where you would put the code that creates and manages orders. |
(5) |
if (first()) { std::cout << "hello trader!" << std::endl; }
Calls he strategy::first() member which returns 'true' when on_bar_close() is invoked for the first time. This allows for certain initializations to be performed - in this case it prints a simple "hello trader" message. In general, it is preferable to use the strategy's on_start() member to perform all required initializations. |
(6) |
std::cout << "Bar: " << bar_count() << "\t " << "Timestamp: " << timestamp() << std::endl;
Prints the bar's timestamp and bar number. The strategy::bar_count() member returns the ordinal number of the current bar starting at 1. The strategy::timestamp() member returns the timestamp of the current bar (the bar that just closed). Normally the sequence of timestamps used by the strategy to iterate over bars comes from a stream object, itself connected to some data-source like a database table or a live-feed. In this simple example there is no data source and the strategy simply auto-generates daily intervals.
The process of feeding the strategy a timestamp sequence is referred to as scheduling. We'll take a closer look at this in the next tutorial. |
(7) |
void on_end(void) override { std::cout << "Strategy ends!" << std::endl; }
The on_end() member is called when the strategy simulations reaches its end. |
(9)(10) |
try { my_strategy s; s.run("2012-01-01", "2012-01-15"); } catch (std::exception& x) {
Defining a new strategy class is of course not sufficient. We also need to instantiate a new strategy object and make it do some work. We do this by invoking its strategy::run() member which has various signatures. In the example above we simply pass it two date arguments, one as the start date of the simulations range, and one as the end. |
|
|