18#include <algotradelib/analytics>
19#include <algotradelib/core>
45using analytics::Scalar;
46using analytics::observed;
49std::string cell(Scalar value) {
53 std::ostringstream text;
54 text << std::fixed << std::setprecision(2) << std::setw(7) << value;
68 static constexpr const char* closes[] = {
69 "70000",
"70800",
"70200",
"71500",
"72300",
"71900",
"73100",
"74000",
"73400",
70 "72600",
"71800",
"72500",
"73900",
"75200",
"74800",
"76100",
"77000",
"76200",
73 static constexpr const char* highs[] = {
74 "70500",
"71300",
"70700",
"72000",
"72800",
"72400",
"73600",
"74500",
"73900",
75 "73100",
"72300",
"73000",
"74400",
"75700",
"75300",
"76600",
"77500",
"76700",
78 static constexpr const char* lows[] = {
79 "69400",
"70200",
"69600",
"70900",
"71700",
"71300",
"72500",
"73400",
"72800",
80 "72000",
"71200",
"71900",
"73300",
"74600",
"74200",
"75500",
"76400",
"75600",
85 series.instrument_ = InstrumentId{Country::KR, Venue::COMBINED,
"005930"};
86 series.interval_ = BarInterval::ONE_DAY;
87 series.currency_ = Currency{
"KRW"};
88 series.received_at_ = std::chrono::system_clock::now();
90 const auto start = std::chrono::system_clock::time_point{} + std::chrono::hours(24 * 20000);
91 for (std::size_t day = 0; day < std::size(closes); ++day) {
93 bar.timestamp_ =
start + std::chrono::hours(24 *
static_cast<int>(day));
97 bar.open_ = Decimal64::parse(closes[day]);
99 bar.high_ = Decimal64::parse(highs[day]);
100 bar.low_ = Decimal64::parse(lows[day]);
101 bar.close_ = Decimal64::parse(closes[day]);
102 bar.volume_ = Decimal64::parse(
"1200000");
103 series.bars_.push_back(bar);
111 const BarSeries
bars = fixture();
115 const analytics::SeriesFrame frame = analytics::from_bars(bars);
119 const math::SeriesView close = frame.close();
120 const math::SeriesView open = frame.open();
121 const math::Vector average = analytics::sma(close, 5);
122 const math::Vector smoothed = analytics::ema(close, analytics::alpha_from_span(5));
123 const math::Vector strength = analytics::rsi(close, 5);
124 const math::Vector score = analytics::zscore(close, 5);
125 const auto bands = analytics::bollinger(close, 5, 2.0);
126 const math::Vector range = analytics::atr(frame.high(), frame.low(), close, 5);
127 const math::Vector period_returns = analytics::returns(close);
128 const math::Vector growth = analytics::cumulative_returns(period_returns);
130 std::cout <<
bars.instrument_.symbol_ <<
", " <<
bars.bars_.size()
131 <<
" daily bars, no network\n\n";
132 std::cout <<
"row close open sma5 ema5 rsi5 zscore"
133 <<
" upper lower atr5 cumret\n";
134 for (math::Index row = 0; row < close.size(); ++row) {
135 std::cout << std::setw(3) << row <<
" " << cell(close[row]) <<
" "
136 << cell(open[row]) <<
" " << cell(average[row]) <<
" "
137 << cell(smoothed[row]) <<
" " << cell(strength[row]) <<
" "
138 << cell(score[row]) <<
" " << cell(bands.upper_[row]) <<
" "
139 << cell(bands.lower_[row]) <<
" " << cell(range[row]) <<
" "
140 << cell(growth[row] * 100.0) <<
"\n";
145 std::cout <<
"\nThe dashes are the point. A window reports nothing until it holds "
146 <<
"enough\nobservations, and row 3 has no open at all.\n";
150 const auto rows =
static_cast<std::size_t
>(close.size());
151 const auto last = close.size() - 1;
152 std::cout <<
"\nOver the whole series:\n"
153 <<
" mean daily return " << std::fixed << std::setprecision(4)
154 << analytics::rolling_mean(period_returns, rows, rows - 1)[last] * 100.0 <<
" %\n"
155 <<
" daily volatility "
156 << analytics::rolling_stdev(period_returns, rows, rows - 1)[last] * 100.0 <<
" %\n"
157 <<
" per-period Sharpe " << analytics::sharpe(period_returns) <<
"\n"
158 <<
" annualized Sharpe "
159 << analytics::annualize_ratio(analytics::sharpe(period_returns), 245.0) <<
"\n"
160 <<
" worst drawdown "
161 << analytics::max_drawdown(close).magnitude_ * 100.0 <<
" %\n";
166 const math::Scalar alpha = analytics::alpha_from_span(5);
167 math::Scalar level = math::missing();
168 for (math::Index row = 0; row < close.size(); ++row) {
169 level = analytics::ema_step(level, close[row], alpha);
171 std::cout <<
" ema_step == ema " << (level == smoothed[last] ?
"yes" :
"no") <<
"\n";
177 const auto limit = analytics::round_scalar_to_tick(
178 bands.upper_[last], rule, OrderSide::SELL
180 std::cout <<
"\nA sell limit at the upper band, rounded onto the KRX tick grid: "
181 << (limit ? limit->str() : std::string(
"refused")) <<
"\n";
A three-letter currency code, such as KRW or USD (ISO 4217 style).
An exact signed decimal: an int64 coefficient times 10^-scale.
Returns, rolling statistics, indicators and performance metrics over numeric series.
The numeric vocabulary: Scalar, missing(), and the matrix and vector types.
bool observed(Scalar value)
Tests whether a value is an observation.
void start(S &strategy, Ctx &context)
Calls strategy.on_start(context) if the strategy declares on_start; otherwise does nothing.
void bar(S &strategy, Ctx &context, const BarEvent &event)
Calls strategy.on_bar(context, event) if the strategy declares on_bar; otherwise does nothing.
void bars(S &strategy, Ctx &context, const BarSlice &slice)
Calls strategy.on_bars(context, slice) if the strategy declares on_bars; otherwise does nothing.
PriceRule price_rule_for(Country country, SecurityType type)
Returns the library's price grid for a kind of security in a country.
SecurityType
What kind of security an instrument is.
Country
A country (market) the library supports.
Venue
A trading venue: an exchange, or the combined view across exchanges.
BarInterval
The period one bar covers.
OrderSide
The side of an order: its economic direction, buy or sell.
The bars of one instrument and interval, oldest first.
One bar: the prices and volume of one period, as exact decimals.
Identifies an instrument: its country, venue and symbol.