algotradelib 0.0.0.9000
C++ header-only library for algorithmic trading
Loading...
Searching...
No Matches
market_data.hpp
1#pragma once
2
3#include "./types.hpp"
4
5#include <algorithm>
6#include <array>
7#include <chrono>
8#include <optional>
9#include <string>
10#include <vector>
11
12namespace algotradelib {
13
20enum class BarInterval {
21 ONE_MINUTE,
22 ONE_DAY,
23 ONE_WEEK,
24 ONE_MONTH,
25 ONE_YEAR,
34};
35
37inline constexpr std::array<BarInterval, 9> all_bar_intervals{
38 BarInterval::ONE_MINUTE,
39 BarInterval::ONE_DAY,
40 BarInterval::ONE_WEEK,
41 BarInterval::ONE_MONTH,
42 BarInterval::ONE_YEAR,
47};
48
54inline constexpr std::string_view bar_interval_name(BarInterval interval) noexcept {
55 switch (interval) {
56 case BarInterval::ONE_MINUTE:
57 return "1m";
58 case BarInterval::ONE_DAY:
59 return "1d";
60 case BarInterval::ONE_WEEK:
61 return "1w";
62 case BarInterval::ONE_MONTH:
63 return "1mo";
64 case BarInterval::ONE_YEAR:
65 return "1y";
67 return "5m";
69 return "15m";
71 return "30m";
73 return "1h";
74 }
75 return "";
76}
77
84inline constexpr std::optional<std::chrono::seconds> bar_interval_length(BarInterval interval) noexcept {
85 switch (interval) {
86 case BarInterval::ONE_MINUTE:
87 return std::chrono::seconds(60);
89 return std::chrono::seconds(300);
91 return std::chrono::seconds(900);
93 return std::chrono::seconds(1800);
95 return std::chrono::seconds(3600);
96 case BarInterval::ONE_DAY:
97 case BarInterval::ONE_WEEK:
98 case BarInterval::ONE_MONTH:
99 case BarInterval::ONE_YEAR:
100 return std::nullopt;
101 }
102 return std::nullopt;
103}
104
105static_assert(
106 lists_every_value(all_bar_intervals, [](BarInterval interval) { return !bar_interval_name(interval).empty(); }),
107 "all_bar_intervals must list every BarInterval"
108);
109
117enum class BarStamp {
119 OPEN,
121 CLOSE,
122};
123
129struct Bar {
131 std::chrono::system_clock::time_point timestamp_;
133 std::optional<Decimal64> open_;
143 std::optional<Decimal64> traded_value_;
144};
145
151struct BarSeries {
155 BarInterval interval_{BarInterval::ONE_DAY};
161 bool adjusted_{true};
168 std::vector<Bar> bars_;
174 std::optional<std::string> next_cursor_;
176 std::chrono::system_clock::time_point received_at_;
177
182 bool ascending() const {
183 for (std::size_t index = 1; index < bars_.size(); ++index) {
184 if (!(bars_[index - 1].timestamp_ < bars_[index].timestamp_)) {
185 return false;
186 }
187 }
188 return true;
189 }
190};
191
199
210 std::vector<DepthLevel> bids_;
212 std::vector<DepthLevel> asks_;
216 std::optional<std::chrono::system_clock::time_point> exchange_time_;
218 std::chrono::system_clock::time_point received_at_;
219
224 std::optional<DepthLevel> best_bid() const {
225 return bids_.empty() ? std::nullopt : std::optional<DepthLevel>(bids_.front());
226 }
227
232 std::optional<DepthLevel> best_ask() const {
233 return asks_.empty() ? std::nullopt : std::optional<DepthLevel>(asks_.front());
234 }
235
240 std::optional<Decimal64> spread() const {
241 const auto bid = best_bid();
242 const auto ask = best_ask();
243 if (!bid || !ask) {
244 return std::nullopt;
245 }
246 return decimal_subtract(ask->price_, bid->price_);
247 }
248
256 std::optional<Decimal64> mid() const {
257 const auto bid = best_bid();
258 const auto ask = best_ask();
259 if (!bid || !ask) {
260 return std::nullopt;
261 }
262 const auto sum = decimal_add(bid->price_, ask->price_);
263 if (!sum) {
264 return std::nullopt;
265 }
266 return decimal_halve(*sum);
267 }
268};
269
274inline void order_depth(DepthSnapshot& book) {
275 const auto by_price = [](const DepthLevel& lhs, const DepthLevel& rhs) {
276 return decimal_less(lhs.price_, rhs.price_);
277 };
278 std::sort(book.asks_.begin(), book.asks_.end(), by_price);
279 std::sort(book.bids_.begin(), book.bids_.end(), [&by_price](const auto& l, const auto& r) {
280 return by_price(r, l);
281 });
282}
283
297 std::optional<std::chrono::system_clock::time_point> exchange_time_;
298};
299
309 std::optional<Decimal64> upper_;
311 std::optional<Decimal64> lower_;
315 std::optional<std::chrono::system_clock::time_point> exchange_time_;
316};
317
324struct BarQuery {
328 BarInterval interval_{BarInterval::ONE_DAY};
330 int count_{100};
332 std::optional<std::chrono::system_clock::time_point> before_;
334 bool adjusted_{true};
335};
336
337} // namespace algotradelib
A three-letter currency code, such as KRW or USD (ISO 4217 style).
Definition types.hpp:234
An exact signed decimal: an int64 coefficient times 10^-scale.
Definition types.hpp:297
The library: broker-neutral types (core), and the modules below.
BarStamp
Which edge of its period a bar's timestamp marks.
@ CLOSE
The timestamp is the instant the period ended.
constexpr std::optional< std::chrono::seconds > bar_interval_length(BarInterval interval) noexcept
Returns an interval's fixed length, for an intraday interval.
constexpr bool lists_every_value(const std::array< Enum, N > &values, IsEnumerator is_enumerator) noexcept
Tests whether a list holds every value of an enum exactly once, in any order.
std::optional< Decimal64 > decimal_add(const Decimal64 &lhs, const Decimal64 &rhs)
Adds two decimals exactly.
Definition types.hpp:509
std::optional< Decimal64 > decimal_halve(const Decimal64 &value)
Halves a decimal exactly, adding a decimal place when needed.
Definition types.hpp:549
constexpr std::string_view bar_interval_name(BarInterval interval) noexcept
Returns a short name for an interval, such as "1m", "5m", "1h" or "1d".
constexpr std::array< BarInterval, 9 > all_bar_intervals
Every BarInterval, in declaration order.
std::optional< Decimal64 > decimal_subtract(const Decimal64 &lhs, const Decimal64 &rhs)
Subtracts two decimals exactly.
Definition types.hpp:530
bool decimal_less(const Decimal64 &lhs, const Decimal64 &rhs)
Compares two decimals numerically, whatever their scales.
Definition types.hpp:665
BarInterval
The period one bar covers.
@ FIVE_MINUTES
Five minutes.
@ THIRTY_MINUTES
Thirty minutes.
@ FIFTEEN_MINUTES
Fifteen minutes.
void order_depth(DepthSnapshot &book)
Sorts a book's levels best first: bids descending, asks ascending.
What bars to fetch.
InstrumentId instrument_
The instrument.
BarInterval interval_
The period of each bar; an interval the broker does not publish is refused.
int count_
How many bars to return in total, across pages.
std::optional< std::chrono::system_clock::time_point > before_
The newest bar time to return, inclusive; pass the oldest timestamp seen to page backwards.
bool adjusted_
Whether to ask for prices adjusted for corporate actions.
The bars of one instrument and interval, oldest first.
bool ascending() const
Tests whether the bars are strictly ascending in time.
std::optional< std::string > next_cursor_
A cursor to continue from, if the broker has more.
std::chrono::system_clock::time_point received_at_
When the series was received, on this machine's clock.
BarInterval interval_
The period each bar covers.
Currency currency_
The currency of the prices.
bool adjusted_
Whether the prices are adjusted for corporate actions.
BarStamp stamp_
Which edge of its period each bar's timestamp marks.
InstrumentId instrument_
The instrument.
std::vector< Bar > bars_
The bars, oldest first.
One bar: the prices and volume of one period, as exact decimals.
Decimal64 volume_
The shares traded.
Decimal64 high_
The highest trade price.
Decimal64 close_
The last trade price.
std::chrono::system_clock::time_point timestamp_
The instant marking the period; BarSeries::stamp_ says which edge.
std::optional< Decimal64 > open_
The first trade's price; empty if nothing traded in the period (never zero or the previous close).
std::optional< Decimal64 > traded_value_
The value traded, if the broker publishes it.
Decimal64 low_
The lowest trade price.
One price level of an order book.
Decimal64 quantity_
The quantity resting at it.
Decimal64 price_
The price.
An instrument's order book: resting bids and offers.
std::optional< DepthLevel > best_ask() const
Returns the best offer.
Currency currency_
The currency of the prices.
std::optional< Decimal64 > spread() const
Returns the spread, best offer minus best bid, exactly.
std::chrono::system_clock::time_point received_at_
When the book was received, on this machine's clock.
InstrumentId instrument_
The instrument.
std::vector< DepthLevel > bids_
The bids, descending by price.
std::vector< DepthLevel > asks_
The offers, ascending by price.
std::optional< Decimal64 > mid() const
Returns the midpoint of the best bid and offer, exactly (one more decimal place if needed).
std::optional< std::chrono::system_clock::time_point > exchange_time_
When the exchange says the book was true, if the broker gave a time.
std::optional< DepthLevel > best_bid() const
Returns the best bid.
Identifies an instrument: its country, venue and symbol.
Definition types.hpp:78
The highest and lowest price an instrument may trade at today.
std::optional< Decimal64 > lower_
The lowest price allowed today; empty means the same as for upper_.
std::optional< std::chrono::system_clock::time_point > exchange_time_
When the exchange set the bounds, if the broker gave a time.
std::optional< Decimal64 > upper_
The highest price allowed today.
Currency currency_
The currency of the bounds.
One executed trade, as the broker reported it.
Currency currency_
The currency of price_.
Decimal64 price_
The trade price.
Decimal64 quantity_
The quantity traded.
std::optional< std::chrono::system_clock::time_point > exchange_time_
When the exchange says it executed, if the broker gave a time.