algotradelib 0.0.0.9000
C++ header-only library for algorithmic trading
Loading...
Searching...
No Matches
intent.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algotradelib/core>
4
5#include <optional>
6#include <stdexcept>
7#include <string>
8#include <utility>
9
10namespace algotradelib {
11namespace strategy {
12
22
29class Price {
30public:
39 static std::optional<Price> checked(Decimal64 value, const PriceRule& rule) {
40 const auto aligned = rule.on_tick(value);
41 if (!aligned || !*aligned) {
42 return std::nullopt;
43 }
44 return Price(std::move(value));
45 }
46
57 static std::optional<Price> rounded(
58 const Decimal64& value,
59 const PriceRule& rule,
60 OrderSide side
61 ) {
62 auto moved = rule.round_to_tick(value, side);
63 if (!moved) {
64 return std::nullopt;
65 }
66 return Price(std::move(*moved));
67 }
68
73 const Decimal64& value() const noexcept { return value_; }
74
79 std::string str() const { return value_.str(); }
80
87 friend bool operator==(const Price& lhs, const Price& rhs) {
88 return lhs.value_ == rhs.value_;
89 }
90
97 friend bool operator!=(const Price& lhs, const Price& rhs) { return !(lhs == rhs); }
98
99private:
100 explicit Price(Decimal64 value) : value_(std::move(value)) {}
101
102 Decimal64 value_;
103};
104
114
120inline constexpr bool size_kind_is_target(SizeKind kind) noexcept {
121 switch (kind) {
123 return true;
126 return false;
127 }
128 return false;
129}
130
137class SizeSpec {
138public:
140 SizeSpec() = default;
141
147 static SizeSpec quantity(Decimal64 amount) {
148 SizeSpec size;
149 size.kind_ = SizeKind::QUANTITY;
150 size.quantity_ = std::move(amount);
151 return size;
152 }
153
159 static SizeSpec notional(Money amount) {
160 SizeSpec size;
161 size.kind_ = SizeKind::NOTIONAL;
162 size.notional_ = std::move(amount);
163 return size;
164 }
165
188 SizeSpec size;
189 size.kind_ = SizeKind::TARGET_WEIGHT;
190 size.weight_ = std::move(fraction);
191 return size;
192 }
193
198 SizeKind kind() const noexcept { return kind_; }
199
205 const Decimal64& as_quantity() const {
206 require(SizeKind::QUANTITY, "quantity");
207 return quantity_;
208 }
209
215 const Money& as_notional() const {
216 require(SizeKind::NOTIONAL, "notional");
217 return notional_;
218 }
219
226 require(SizeKind::TARGET_WEIGHT, "target weight");
227 return weight_;
228 }
229
230private:
231 void require(SizeKind wanted, const char* name) const {
232 if (kind_ != wanted) {
233 throw std::logic_error(std::string("order size is not a ") + name);
234 }
235 }
236
238 Decimal64 quantity_;
239 Money notional_;
240 Decimal64 weight_;
241};
242
249class OrderIntent {
250public:
261 static OrderIntent limit(
265 Price limit,
267 ) {
268 OrderIntent intent;
269 intent.instrument_ = std::move(instrument);
270 intent.side_ = side;
271 intent.type_ = OrderType::LIMIT;
272 intent.time_in_force_ = time_in_force;
273 intent.size_ = std::move(size);
274 intent.limit_ = std::move(limit);
275 return intent;
276 }
277
294 static OrderIntent stop_limit(
299 Price limit,
301 ) {
302 OrderIntent intent;
303 intent.instrument_ = std::move(instrument);
304 intent.side_ = side;
305 intent.type_ = OrderType::STOP_LIMIT;
306 intent.time_in_force_ = time_in_force;
307 intent.size_ = std::move(size);
308 intent.limit_ = std::move(limit);
309 intent.trigger_ = std::move(trigger);
310 return intent;
311 }
312
322 static OrderIntent market(
327 ) {
328 OrderIntent intent;
329 intent.instrument_ = std::move(instrument);
330 intent.side_ = side;
331 intent.type_ = OrderType::MARKET;
332 intent.time_in_force_ = time_in_force;
333 intent.size_ = std::move(size);
334 return intent;
335 }
336
343 OrderIntent with_tag(std::string tag) const {
344 OrderIntent copy = *this;
345 copy.tag_ = std::move(tag);
346 return copy;
347 }
348
358 OrderIntent with_client_order_id(std::string key) const {
359 OrderIntent copy = *this;
360 copy.client_order_id_ = std::move(key);
361 return copy;
362 }
363
368 const InstrumentId& instrument() const noexcept { return instrument_; }
369
374 OrderSide side() const noexcept { return side_; }
375
380 OrderType type() const noexcept { return type_; }
381
386 TimeInForce time_in_force() const noexcept { return time_in_force_; }
387
392 const SizeSpec& size() const noexcept { return size_; }
393
398 const std::optional<Price>& limit() const noexcept { return limit_; }
399
404 const std::optional<Price>& trigger() const noexcept { return trigger_; }
405
410 const std::string& tag() const noexcept { return tag_; }
411
416 const std::optional<std::string>& client_order_id() const noexcept {
417 return client_order_id_;
418 }
419
420private:
421 OrderIntent() = default;
422
423 InstrumentId instrument_;
424 OrderSide side_{OrderSide::BUY};
426 TimeInForce time_in_force_{TimeInForce::DAY};
427 SizeSpec size_;
428 std::optional<Price> limit_;
429 std::optional<Price> trigger_;
430 std::string tag_;
431 std::optional<std::string> client_order_id_;
432};
433
452
470template <typename Broker>
475 std::string tag_;
476};
477
478} // namespace strategy
479} // namespace algotradelib
An exact signed decimal: an int64 coefficient times 10^-scale.
Definition types.hpp:297
One order a strategy asks the runner to place.
Definition intent.hpp:249
OrderType type() const noexcept
Returns the order type.
Definition intent.hpp:380
OrderIntent with_tag(std::string tag) const
Returns a copy with a tag.
Definition intent.hpp:343
TimeInForce time_in_force() const noexcept
Returns how long the order stays valid.
Definition intent.hpp:386
const std::string & tag() const noexcept
Returns the tag.
Definition intent.hpp:410
const std::optional< std::string > & client_order_id() const noexcept
Returns the idempotency key.
Definition intent.hpp:416
const SizeSpec & size() const noexcept
Returns how much to trade.
Definition intent.hpp:392
const InstrumentId & instrument() const noexcept
Returns the instrument to trade.
Definition intent.hpp:368
OrderSide side() const noexcept
Returns the side.
Definition intent.hpp:374
OrderIntent with_client_order_id(std::string key) const
Returns a copy with a broker idempotency key.
Definition intent.hpp:358
const std::optional< Price > & limit() const noexcept
Returns the limit price.
Definition intent.hpp:398
static OrderIntent stop_limit(InstrumentId instrument, OrderSide side, SizeSpec size, Price trigger, Price limit, TimeInForce time_in_force=TimeInForce::DAY)
Makes a stop-limit order: a limit order the broker releases when the trigger price is reached.
Definition intent.hpp:294
const std::optional< Price > & trigger() const noexcept
Returns the trigger price.
Definition intent.hpp:404
static OrderIntent market(InstrumentId instrument, OrderSide side, SizeSpec size, TimeInForce time_in_force=TimeInForce::DAY)
Makes a market order, which carries no price.
Definition intent.hpp:322
static OrderIntent limit(InstrumentId instrument, OrderSide side, SizeSpec size, Price limit, TimeInForce time_in_force=TimeInForce::DAY)
Makes a limit order.
Definition intent.hpp:261
A price known to be on its instrument's tick grid.
Definition intent.hpp:29
friend bool operator!=(const Price &lhs, const Price &rhs)
Compares two prices for inequality.
Definition intent.hpp:97
const Decimal64 & value() const noexcept
Returns the price as a decimal.
Definition intent.hpp:73
friend bool operator==(const Price &lhs, const Price &rhs)
Compares two prices by exact value (scale included; see Decimal64).
Definition intent.hpp:87
static std::optional< Price > checked(Decimal64 value, const PriceRule &rule)
Makes a price from a value that is already on the grid.
Definition intent.hpp:39
std::string str() const
Returns the price as text, for logs.
Definition intent.hpp:79
static std::optional< Price > rounded(const Decimal64 &value, const PriceRule &rule, OrderSide side)
Makes a price by rounding a value onto the grid, in the order's favour.
Definition intent.hpp:57
How much an OrderIntent trades: a quantity, a notional amount, or a target weight.
Definition intent.hpp:137
static SizeSpec notional(Money amount)
Makes a size as an amount of money.
Definition intent.hpp:159
const Decimal64 & as_target_weight() const
Returns the target weight.
Definition intent.hpp:225
static SizeSpec quantity(Decimal64 amount)
Makes a size in shares or contracts.
Definition intent.hpp:147
const Decimal64 & as_quantity() const
Returns the quantity.
Definition intent.hpp:205
SizeKind kind() const noexcept
Returns how the size is expressed.
Definition intent.hpp:198
const Money & as_notional() const
Returns the notional amount.
Definition intent.hpp:215
static SizeSpec target_weight(Decimal64 fraction)
Makes a size as a fraction of portfolio value to hold.
Definition intent.hpp:187
SizeSpec()=default
Constructs a quantity of zero (reconciling it reports QUANTITY_ROUNDS_TO_ZERO).
What a strategy sees and emits: events, intents, the portfolio, reconciliation and risk limits.
Definition concept.hpp:16
constexpr bool size_kind_is_target(SizeKind kind) noexcept
Tests whether a size states a holding to reach (a target), rather than an amount to trade.
Definition intent.hpp:120
SizeKind
How an order's size is expressed.
Definition intent.hpp:106
@ NOTIONAL
An amount of money; the runner divides it by a price.
Definition intent.hpp:110
@ QUANTITY
A number of shares or contracts.
Definition intent.hpp:108
@ TARGET_WEIGHT
A fraction of portfolio value to hold; the runner trades the difference.
Definition intent.hpp:112
The library: broker-neutral types (core), and the modules below.
OrderType
How an order's price is decided (its price basis).
Definition types.hpp:1707
@ LIMIT
지정가: fills at the stated price or better.
Definition types.hpp:1710
@ STOP_LIMIT
스톱지정가: a limit released when a trigger price is reached.
Definition types.hpp:1722
@ MARKET
시장가: fills at whatever the book offers.
Definition types.hpp:1712
TimeInForce
How long an order stays valid and what happens to an unfilled remainder.
Definition types.hpp:1797
@ DAY
Rests until the session ends; an unfilled remainder is cancelled then.
Definition types.hpp:1800
OrderSide
The side of an order: its economic direction, buy or sell.
Definition types.hpp:1683
Identifies an instrument: its country, venue and symbol.
Definition types.hpp:78
An exact amount of money in one currency.
Definition types.hpp:895
A broker's reference to one order, used to amend or cancel it.
Definition types.hpp:2111
The price grid (tick sizes) an instrument's order prices must sit on.
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.
A request to cancel one working order.
Definition intent.hpp:471
OrderRef< Broker > ref_
The order to cancel.
Definition intent.hpp:473
std::string tag_
A label for attribution.
Definition intent.hpp:475
The position a strategy wants to hold in one instrument.
Definition intent.hpp:442
InstrumentId instrument_
The instrument.
Definition intent.hpp:444
std::string tag_
A label carried to the orders and their fills.
Definition intent.hpp:450
Decimal64 target_quantity_
The position to hold, signed: negative is short, and zero means flat.
Definition intent.hpp:446
std::optional< Price > limit_
The limit price for the orders the runner places; without one they are market orders.
Definition intent.hpp:448