43 std::string
str()
const {
90 if (code ==
"KOSPI") {
91 segment.
known_ = MarketSegment::Known::KOSPI;
92 }
else if (code ==
"KOSDAQ") {
93 segment.
known_ = MarketSegment::Known::KOSDAQ;
94 }
else if (code ==
"NYSE") {
95 segment.
known_ = MarketSegment::Known::NYSE;
96 }
else if (code ==
"NASDAQ") {
97 segment.
known_ = MarketSegment::Known::NASDAQ;
98 }
else if (code ==
"AMEX") {
99 segment.
known_ = MarketSegment::Known::AMEX;
101 segment.
other_ = *preserved;
193 std::optional<Decimal64> tick;
194 for (
const auto& band :
bands_) {
214 const auto tick =
tick_at(price);
218 const auto rest = remainder(price, *tick);
222 return rest->coefficient() == 0;
241 const auto tick =
tick_at(price);
245 const auto rest = remainder(price, *tick);
249 if (rest->coefficient() == 0) {
256 if (side == OrderSide::BUY) {
269 rule.
source_ =
"KRX cash equity tick table, 2023-01 revision (library-maintained)";
289 rule.
source_ =
"no exchange price grid";
301 rule.
source_ = std::move(reason);
307 static std::optional<Decimal64> remainder(
const Decimal64& price,
const Decimal64& tick) {
308 std::int64_t left = 0;
309 std::int64_t right = 0;
310 std::uint8_t scale = 0;
311 if (!decimal_detail::align(price, tick, left, right, scale) || right == 0) {
314 auto rest = left % right;
316 rest += right < 0 ? -right : right;
340 if (country != Country::KR) {
345 case SecurityType::STOCK:
346 case SecurityType::FOREIGN_STOCK:
347 case SecurityType::DEPOSITARY_RECEIPT:
348 case SecurityType::INFRASTRUCTURE_FUND:
349 case SecurityType::REIT:
351 case SecurityType::ETF:
352 case SecurityType::FOREIGN_ETF:
353 case SecurityType::ETN:
355 "KRX prices funds and notes on a ladder this library does not carry"
357 case SecurityType::STOCK_WARRANT:
358 case SecurityType::UNKNOWN:
430 throw std::logic_error(
"StatedDate::date() read a date that was not stated");
442 return lhs.state_ == rhs.state_ && (lhs.state_ !=
State::STATED || lhs.date_ == rhs.date_);
532 static constexpr bool leaves_exclusion_unknown(
StatedDate::State state)
noexcept {
A short uppercase code (letters, digits, _), stored inline without allocation.
bool empty() const noexcept
Tests whether the code is empty.
static std::optional< Code > try_make(std::string_view text)
Makes a code without throwing.
std::string str() const
Returns the code as a string.
A three-letter currency code, such as KRW or USD (ISO 4217 style).
An exact signed decimal: an int64 coefficient times 10^-scale.
Decimal64()=default
Constructs zero.
static Decimal64 parse(std::string_view input)
Parses a decimal string exactly (no binary floating point).
A date a broker stated, did not state, or stated in a form that could not be read.
State
What the broker's field said.
@ STATED
A date that was read.
@ UNREADABLE
Something that is not a readable calendar date.
@ NOT_STATED
No date: absent, null, or the broker's empty spelling.
friend bool operator==(const StatedDate &lhs, const StatedDate &rhs)
Compares two values: the same state, and the same date when stated.
const Date & date() const
Returns the date.
State state() const noexcept
Returns what the broker's field said.
friend bool operator!=(const StatedDate &lhs, const StatedDate &rhs)
Compares two values for inequality.
StatedDate()=default
Constructs a date the broker did not state.
static StatedDate unreadable()
Makes an unreadable date.
static StatedDate stated(Date date)
Makes a stated date.
The library: broker-neutral types (core), and the modules below.
PriceRule price_rule_for(Country country, SecurityType type)
Returns the library's price grid for a kind of security in a country.
MarketSegment market_segment(std::string_view code)
Maps a broker's segment code to a MarketSegment.
SecurityType
What kind of security an instrument is.
std::optional< Decimal64 > decimal_add(const Decimal64 &lhs, const Decimal64 &rhs)
Adds two decimals exactly.
InstrumentStatus
Whether an instrument is listed, awaiting listing, or delisted.
DateExclusion
What an instrument's listing and delisting dates say about one day.
@ EXCLUDED
A readable date rules the day out: listed after it, or delisted on or before it.
@ UNREADABLE
No readable date rules it out, but an unreadable date might.
@ NOT_EXCLUDED
No date rules it out and neither is unreadable. This does not mean "listed".
Country
A country (market) the library supports.
Decimal64 decimal_normalized(const Decimal64 &value)
Removes trailing fractional zeros, so equal numbers compare equal with ==.
std::optional< Decimal64 > decimal_subtract(const Decimal64 &lhs, const Decimal64 &rhs)
Subtracts two decimals exactly.
bool decimal_less(const Decimal64 &lhs, const Decimal64 &rhs)
Compares two decimals numerically, whatever their scales.
OrderSide
The side of an order: its economic direction, buy or sell.
A calendar date with no time of day or time zone.
Identifies an instrument: its country, venue and symbol.
Reference data for one instrument.
std::optional< Decimal64 > shares_outstanding_
Shares outstanding, if published; KIS's blank or zero is empty, never zero shares.
InstrumentStatus status_
Listed, awaiting listing, or delisted.
Currency currency_
The currency it trades in.
InstrumentId id_
The instrument.
std::string isin_
The ISIN, or empty.
StatedDate delisted_on_
The delisting date; always NOT_STATED from Kiwoom, which publishes none.
DateExclusion dates_exclude(Date day) const
Tests whether the listing and delisting dates rule a day out.
StatedDate listed_on_
The listing date.
bool common_share_
Whether this is the common share, not a preferred or derived line.
PriceRule price_rule_
The price grid; kind UNKNOWN where the library has no table.
MarketSegment segment_
The market segment.
std::optional< Decimal64 > lot_size_
The order quantity increment, if the broker publishes one.
std::string english_name_
The English name, or empty.
SecurityType type_
The kind of security, which selects the price grid.
std::string name_
The local-language name, as the broker spells it.
The market segment an instrument is listed on, such as KOSPI or NASDAQ.
Code< 12 > other_
The broker's code, when known_ is UNKNOWN and the code fits Code<12>.
friend bool operator!=(const MarketSegment &lhs, const MarketSegment &rhs)
Compares two segments for inequality.
Known known_
The segment, or UNKNOWN if the broker's code was not recognized.
Known
The segments the library recognizes.
std::string str() const
Returns the segment's name for display.
friend bool operator==(const MarketSegment &lhs, const MarketSegment &rhs)
Compares the normalized segment and the preserved code.
The price grid (tick sizes) an instrument's order prices must sit on.
std::optional< Decimal64 > tick_at(const Decimal64 &price) const
Returns the tick size at a price.
std::string source_
Where the table came from and its revision, or why there is none.
static PriceRule unconstrained()
Returns a rule with no grid, for a market quoted in free decimals.
std::optional< bool > on_tick(const Decimal64 &price) const
Tests whether a price is on the grid.
std::optional< Decimal64 > round_to_tick(const Decimal64 &price, OrderSide side) const
Rounds a price to its band's tick in the order's favour: a buy rounds down, a sell up.
std::vector< TickBand > bands_
The bands, ascending by from_; empty unless kind_ is STATED.
static PriceRule krx_equity()
Returns the KRX cash-equity tick table (January 2023 revision).
Kind
Whether the rule states a grid, imposes none, or does not know it.
@ STATED
bands_ describe the market's grid.
@ UNCONSTRAINED
The market imposes no grid (free decimals).
@ UNKNOWN
The library has no grid for this instrument (for example a KRX ETF or ETN) and will not guess one.
constexpr bool grid_known() const noexcept
Tests whether the rule says anything about the grid: a stated one, or none at all.
static PriceRule unknown(std::string reason)
Returns a rule that knows no grid and refuses to round.
Kind kind_
The kind of rule; UNKNOWN by default, so an unset rule refuses to round.
One band of a price grid: the tick size from a price upward, until the next band.
Decimal64 from_
The price the band starts at, inclusive.
Decimal64 tick_
The tick size within the band.