![]() |
algotradelib 0.0.0.9000
C++ header-only library for algorithmic trading
|
What a strategy sees and emits: events, intents, the portfolio, reconciliation and risk limits. More...
Namespaces | |
| namespace | dispatch |
| Calls a strategy's handlers, skipping the ones it does not declare. | |
| namespace | vanilla |
| The strategies this library ships (buy and hold, crossovers, mean reversion, sizing, liquidation). | |
Classes | |
| struct | AllCaps |
| A capability set in which the broker implements everything optional. More... | |
| struct | BarEvent |
| One bar, delivered to on_bar. More... | |
| struct | BarSlice |
| Every instrument's bar of one interval for one period end, delivered to on_bars. More... | |
| struct | CancelIntent |
| A request to cancel one working order. More... | |
| struct | Fill |
| One execution of an order the strategy placed, delivered to on_fill. More... | |
| struct | GuardDecision |
| What RiskGuard::evaluate concluded about one order. More... | |
| struct | GuardInputs |
| What RiskGuard::check needs besides the order and the portfolio. More... | |
| struct | GuardRejection |
| One order a guard refused, with the limit and the value that exceeded it. More... | |
| struct | InstrumentBasis |
| An instrument's currency and the price to value it at, for the exposure ceiling. More... | |
| struct | NoCaps |
| A capability set in which the broker implements nothing optional. More... | |
| class | OrderIntent |
| One order a strategy asks the runner to place. More... | |
| struct | Plan |
| What to send: first every cancellation, then every placement. More... | |
| struct | PlannedOrder |
| One order the runner is to place. More... | |
| struct | Portfolio |
| What the account holds and which orders are still working, as a strategy sees it. More... | |
| class | Price |
| A price known to be on its instrument's tick grid. More... | |
| struct | ProbeBroker |
| The broker tag of a probe context; nothing it issues reaches a market. More... | |
| class | ProbeContextT |
| A context for testing a strategy without a runner: it records what the strategy asks for. More... | |
| struct | QuoteEvent |
| A quote the runner has just read, delivered to on_quote. More... | |
| struct | ReconcileInputs |
| What reconciliation needs besides the intent and the portfolio; the runner fills it in. More... | |
| struct | Rejection |
| One instruction that was not placed, and why. More... | |
| class | RiskGuard |
| Checks planned orders against RiskLimits, holds trading stopped, and counts orders sent. More... | |
| struct | RiskLimits |
| The limits the operator sets for RiskGuard. More... | |
| class | SellableConventionProbe |
| Infers a broker's SellableConvention from successive portfolios. More... | |
| struct | SellableEvidence |
| How many observations supported each answer. More... | |
| struct | SessionWindow |
| The intraday session of a market, as the operator states it. More... | |
| class | SizeSpec |
| How much an OrderIntent trades: a quantity, a notional amount, or a target weight. More... | |
| struct | StrategyConformance |
| The checks behind ATL_ASSERT_STRATEGY; instantiating it reports what is wrong with S. More... | |
| struct | TargetPosition |
| The position a strategy wants to hold in one instrument. More... | |
| struct | TradeTolerance |
| How small a difference from a target is not worth an order. More... | |
| struct | WeightTarget |
| The result of weight_target: a target position or a refusal, exactly one of them. More... | |
Typedefs | |
| using | MinimalContext = ProbeContextT<NoCaps> |
| A probe context whose broker implements nothing optional. | |
| using | FullContext = ProbeContextT<AllCaps> |
| A probe context whose broker implements everything optional. | |
Functions | |
| constexpr std::string_view | market_phase_name (MarketPhase phase) noexcept |
| Returns a lowercase name for a phase, such as "pre_open", for logs and display. | |
| constexpr bool | market_phase_session_ended (MarketPhase phase) noexcept |
| Tests whether a phase means the day's session is over (or never opened), so a day order no longer works. | |
| std::chrono::system_clock::time_point | bar_period_end (const Bar &bar, BarInterval interval, BarStamp stamp) |
| Computes the instant a bar's period ended. | |
| BarEvent | make_bar_event (InstrumentId instrument, BarInterval interval, BarStamp stamp, Bar bar) |
| Makes a bar event, computing its period_end_ with bar_period_end. | |
| 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. | |
| bool | order_is_open (OrderStatus status) |
| Tests whether an order in a given status may still trade. | |
| constexpr std::string_view | reject_reason_name (RejectReason reason) noexcept |
| Returns a lowercase name for a reason, such as "no_reference_data", for logs. | |
| bool | is_stop_order (const OrderSnapshot &order) |
| Tests whether a working order is a stop order: a trigger-price type, or one carrying a trigger price. | |
| template<typename Broker> | |
| Plan< Broker > | reconcile (const TargetPosition &target, const Portfolio< Broker > &portfolio, const ReconcileInputs &inputs) |
| Plans the cancellations and the order that move a holding to a target position. | |
| template<typename Broker> | |
| Plan< Broker > | reconcile (const OrderIntent &intent, const Portfolio< Broker > &portfolio, const ReconcileInputs &inputs) |
| Plans the order for one intent, without comparing against the portfolio. | |
| WeightTarget | weight_target (const OrderIntent &intent, const ReconcileInputs &inputs) |
| Converts a weight-sized intent into the target position it states. | |
| constexpr bool | halt_blocks (HaltReason reason, InstructionClass klass) noexcept |
| Tests whether a hold stops an instruction of a given class. | |
| constexpr std::string_view | halt_reason_name (HaltReason reason) noexcept |
| Returns a lowercase name for a hold, such as "portfolio_stale", for logs. | |
| constexpr std::string_view | guard_reason_name (GuardReason reason) noexcept |
| Returns a lowercase name for a refusal reason, such as "order_rate_exceeded", for logs. | |
| template<typename Broker> | |
| std::optional< Decimal64 > | projected_gross_exposure (const Portfolio< Broker > &portfolio, const std::vector< InstrumentBasis > &basis, const Currency ¤cy, const PlannedOrder *candidate, const std::optional< Decimal64 > &candidate_price, CandidateContribution contribution) |
| Computes the gross exposure in one currency if every outstanding order (and a candidate) filled. | |
| template<typename Broker> | |
| std::optional< bool > | closes_toward_flat (const Portfolio< Broker > &portfolio, const PlannedOrder &order) |
| Tests whether an order only reduces a held position toward flat, without passing through it. | |
| constexpr std::string_view | sellable_convention_name (SellableConvention convention) noexcept |
| Returns a lowercase name for a convention, such as "net_of_resting", for logs. | |
Variables | |
| constexpr std::array< MarketPhase, 5 > | all_market_phases |
| Every MarketPhase, in declaration order. | |
| constexpr std::array< HaltReason, 8 > | all_halt_reasons |
| Every HaltReason, in declaration order. | |
| constexpr std::size_t | halt_reason_count = all_halt_reasons.size() |
| The number of HaltReason values. | |
What a strategy sees and emits: events, intents, the portfolio, reconciliation and risk limits.
A probe context whose broker implements everything optional.
Definition at line 654 of file concept.hpp.
A probe context whose broker implements nothing optional.
Definition at line 651 of file concept.hpp.
|
strong |
What a candidate order adds to projected_gross_exposure.
Compare QUANTITY_AND_PRICE with PRICE_ONLY to see what the order's quantity alone adds; both value instruments at the same prices.
| Enumerator | |
|---|---|
| QUANTITY_AND_PRICE | The candidate's quantity and price: the exposure if the order is sent. |
| PRICE_ONLY | The candidate's price only: the exposure without the order, valued at the same prices. |
|
strong |
Which check refused an order.
| Enumerator | |
|---|---|
| TRADING_HALTED | A hold is in force; GuardRejection::halt_reason_ names it. |
| INSTRUMENT_NOT_PERMITTED | The instrument is not in RiskLimits::permitted_universe_. |
| PHASE_NOT_PERMITTED | The market phase is not in RiskLimits::permitted_phases_. |
| ORDER_NOTIONAL_TOO_LARGE | The order's value exceeds RiskLimits::max_order_notional_. |
| POSITION_LIMIT_EXCEEDED | The position could exceed RiskLimits::max_position_quantity_. |
| GROSS_EXPOSURE_EXCEEDED | The gross exposure could exceed RiskLimits::max_gross_exposure_. |
| ORDER_RATE_EXCEEDED | RiskLimits::max_orders_per_window_ orders were already sent in the window. |
| VALUE_NOT_KNOWN | A limit needed a value that is not known. No price to value the order, no currency for a per-currency limit, or a GuardInputs::exposure_basis_ that does not cover every instrument held or working. |
| QUANTITY_NOT_SELLABLE | The sell exceeds the broker's sellable quantity, or the broker gave none. |
| SELLABLE_BASIS_UNESTABLISHED | A sellable quantity is present, but what it covers is not established. Unlike QUANTITY_NOT_SELLABLE, the fix is to declare a SellableBasis for the figure, not to resize. A SellableBasis::Coverage::PARTIAL basis reports here too. |
| INSUFFICIENT_BUYING_POWER | The buy costs more than the broker's buying power, or the broker gave none. |
|
strong |
Who or what is holding trading stopped.
Several holds can be in force at once; trading resumes only when every one is released. The enumerators are ordered most fundamental first, and RiskGuard::blocking_reason reports the first one held. Whether a hold also stops cancellations is halt_blocks.
| Enumerator | |
|---|---|
| OPERATOR | A person stopped trading with RiskGuard::halt(); only RiskGuard::resume() clears it. |
| LOCAL_FAILURE | Local machinery failed, such as the order journal not being writable; nothing is sent. Sticky; release it with runner::Runner::resume_after_local_failure, which also acknowledges the journal failures (RiskGuard::resume(LOCAL_FAILURE) lifts the hold without that). The detail names the failure. |
| STOPPING | A stop was requested and the run is shutting down. |
| ORDER_LIST_UNREAD | The broker's order list has not been read since this process started. Until it is, the runner cannot know whether a previous process left orders working, so it places nothing. |
| PORTFOLIO_ABSENT | No holdings snapshot has been read yet, so what the account holds is unknown. An empty portfolio would pass every check as if the account were flat, so placements wait. |
| PORTFOLIO_STALE | The holdings snapshot is older than the configured maximum age. Sizing against old holdings can double a position or miss one acquired since. |
| BUYING_POWER_UNREAD | A buying-power limit is enforced, but there is no current reading to check it against. The reading was never polled, has not returned yet, or has aged out. |
| POLL_FAILING | A poll kept failing and the loop gave up, as opposed to STOPPING on request. |
|
strong |
What an instruction can do to a position, which decides which holds stop it.
A replacement is sent as a withdrawal plus a placement, and the placement is OPENING.
| Enumerator | |
|---|---|
| OPENING | A placement, which can open or enlarge a position. Every hold stops it. |
| WITHDRAWAL | A cancellation of an order the caller named. Not a cancellation the runner derived from the portfolio; runner::Runner holds those to the same holds as a placement. |
|
strong |
Where the clock stands relative to the trading session.
Whether a date trades comes from the broker's calendar; the intraday open and close come from the configured SessionWindow.
|
strong |
Why an instruction was not placed.
Most reasons mean reconciliation could not build a valid instruction. BROKER_REFUSED and BINDING_REFUSED mean it was built and then refused.
| Enumerator | |
|---|---|
| NO_REFERENCE_DATA | No reference data for the instrument, so neither the tick grid nor the lot is known. |
| UNKNOWN_PRICE_GRID | The instrument's tick grid is unknown, so a limit price cannot be made valid. |
| NO_PRICE_AVAILABLE | A price was needed to size the order and none was available. |
| NO_PORTFOLIO_VALUE | A weight needed the portfolio's value, and none (or a non-positive one, or one in another currency) was supplied. |
| QUANTITY_ROUNDS_TO_ZERO | The quantity rounded down to zero on the lot. |
| NOT_REPRESENTABLE | The decimal arithmetic did not fit, or the portfolio's rows did not add up. |
| NO_PERMITTED_PRICE | Rounding the limit onto the grid, in the cautious direction, would move it out of the day's band: no tick lies between the band's bound and the limit (clamped into the band). It takes a band with no tick on that side of the limit; on KRX, for example, only a band narrower than one tick, at a price of a few won. A limit the strategy itself set beyond the band (a buy below the lower bound, a sell above the upper) is left alone, as without a band. |
| BROKER_REFUSED | The broker refused the instruction (a request was sent). |
| BINDING_REFUSED | The binding refused to send the instruction, so no request was made. For example, an idempotency key at a broker that accepts none, or a cancellation of an order the broker has no reference for. |
| TRIGGER_OFF_GRID | A stop-limit order's trigger price is not on the instrument's tick grid. Unlike a limit price, a trigger is never rounded, since rounding would change when the order is released. |
| STOP_ORDER_RESTING | A target needs a trade while a stop order rests on the instrument; the stop is cancelled first and nothing is placed this pass. runner::Runner keeps the target and settles it again once no stop is listed on the instrument (see Runner::deferred_targets); a newer instruction for the instrument replaces it. A target the holding already meets is not refused, and the stop stays. |
| UNSUPPORTED_WEIGHT | A weight-sized intent with something a holding cannot express: a sell, a negative weight, a trigger, a validity other than DAY, or an idempotency key. |
| NEGATIVE_SIZE | An intent's size is negative: a quantity or a notional amount below zero. An intent carries its direction in its side, so a negative size is a sign error, and an order of -5 shares is not a sell of 5. With the inputs it needs available, a zero quantity or notional is QUANTITY_ROUNDS_TO_ZERO; a negative weight is UNSUPPORTED_WEIGHT. |
Definition at line 34 of file reconcile.hpp.
|
strong |
Whether a broker's sellable quantity already excludes sell orders resting at the broker.
No broker documents this. RiskGuard assumes it does not (it subtracts resting sells itself); SellableConventionProbe infers the answer from ordinary polling.
Definition at line 21 of file sellable_convention.hpp.
|
strong |
How an order's size is expressed.
Definition at line 106 of file intent.hpp.
|
inline |
Computes the instant a bar's period ended.
| bar | The bar. |
| interval | The period length the bar covers. |
| stamp | Whether bar.timestamp_ marks the period's open or close. |
Definition at line 232 of file event.hpp.
Referenced by bar_period_end(), and make_bar_event().
| std::optional< bool > algotradelib::strategy::closes_toward_flat | ( | const Portfolio< Broker > & | portfolio, |
| const PlannedOrder & | order ) |
Tests whether an order only reduces a held position toward flat, without passing through it.
With held the net quantity over every position row, the closing side SELL for a long and BUY for a short, and resting the remaining quantity of open orders on the closing side:
RiskGuard uses this to let a closing order through RiskLimits::permitted_phases_.
| Broker | The portfolio's broker tag. |
| portfolio | The positions and working orders. |
| order | The planned order. |
Definition at line 619 of file risk.hpp.
Referenced by closes_toward_flat(), and algotradelib::strategy::RiskGuard::evaluate().
|
inlineconstexprnoexcept |
Returns a lowercase name for a refusal reason, such as "order_rate_exceeded", for logs.
| reason | The reason. |
Definition at line 216 of file risk.hpp.
Referenced by guard_reason_name().
|
inlineconstexprnoexcept |
Tests whether a hold stops an instruction of a given class.
Every hold stops a placement. A named cancellation is stopped only by holds that mean someone stopped the runner (OPERATOR, LOCAL_FAILURE, STOPPING), not by holds that mean data is missing or stale, so a resting order can still be withdrawn when polling fails.
| reason | The hold. |
| klass | The instruction class. |
Definition at line 114 of file risk.hpp.
Referenced by algotradelib::strategy::RiskGuard::blocking_reason_for(), and halt_blocks().
|
inlineconstexprnoexcept |
Returns a lowercase name for a hold, such as "portfolio_stale", for logs.
| reason | The hold. |
Definition at line 144 of file risk.hpp.
Referenced by halt_reason_name(), and live_program::print_loop().
|
inline |
Tests whether a working order is a stop order: a trigger-price type, or one carrying a trigger price.
| order | The order. |
Definition at line 457 of file reconcile.hpp.
Referenced by is_stop_order(), and reconcile().
|
inline |
Makes a bar event, computing its period_end_ with bar_period_end.
| instrument | The instrument the bar is for. |
| interval | The period length the bar covers. |
| stamp | Whether the bar's timestamp marks the period's open or close. |
| bar | The bar. |
Definition at line 273 of file event.hpp.
Referenced by make_bar_event().
|
inlineconstexprnoexcept |
Returns a lowercase name for a phase, such as "pre_open", for logs and display.
| phase | The phase. |
Definition at line 57 of file event.hpp.
Referenced by market_phase_name(), and live_program::print_loop().
|
inlineconstexprnoexcept |
Tests whether a phase means the day's session is over (or never opened), so a day order no longer works.
| phase | The phase. |
Definition at line 79 of file event.hpp.
Referenced by algotradelib::runner::Runner< Strategy, CapsType, Tag, Executor >::feed(), and market_phase_session_ended().
|
inline |
Tests whether an order in a given status may still trade.
| status | The order status. |
Definition at line 20 of file portfolio.hpp.
Referenced by closes_toward_flat(), algotradelib::runner::Runner< Strategy, CapsType, Tag, Executor >::confirm_from_history(), order_is_open(), projected_gross_exposure(), reconcile(), and algotradelib::strategy::Portfolio< Broker >::working_quantity().
| std::optional< Decimal64 > algotradelib::strategy::projected_gross_exposure | ( | const Portfolio< Broker > & | portfolio, |
| const std::vector< InstrumentBasis > & | basis, | ||
| const Currency & | currency, | ||
| const PlannedOrder * | candidate, | ||
| const std::optional< Decimal64 > & | candidate_price, | ||
| CandidateContribution | contribution ) |
Computes the gross exposure in one currency if every outstanding order (and a candidate) filled.
Per instrument, the exposure is max(|held + working buys|, |held - working sells|) times a price, summed over instruments in currency. Opposite-side orders do not offset each other. The price is the highest that could apply: the basis mark and the limit price of every open order on the instrument, the candidate's included. The candidate joins its own instrument on its own side, so a sell that exits a long up to flat (counting sells already working) does not raise the figure, though it does not lower it either until it fills. A sell larger than the long reaches a short and can raise it.
| Broker | The portfolio's broker tag. |
| portfolio | The positions (summed over every row) and working orders. |
| basis | The currency and mark of every instrument held, working or ordered. |
| currency | The currency to total; instruments in other currencies contribute nothing. |
| candidate | The order being checked, or nullptr. |
| candidate_price | The price to value the candidate at if it has no limit (a market order). |
| contribution | Whether the candidate's quantity counts, or only its price. |
Definition at line 432 of file risk.hpp.
Referenced by algotradelib::strategy::RiskGuard::evaluate(), and projected_gross_exposure().
| Plan< Broker > algotradelib::strategy::reconcile | ( | const OrderIntent & | intent, |
| const Portfolio< Broker > & | portfolio, | ||
| const ReconcileInputs & | inputs ) |
Plans the order for one intent, without comparing against the portfolio.
An intent says "trade this much", so the portfolio is not consulted. A notional size is divided by the limit price (or the reference price); the quantity is rounded down onto the lot; a limit more aggressive than the band is clamped to it, and rounded onto the grid; a trigger must already be on the grid.
| Broker | The broker tag. |
| intent | The order intent. |
| portfolio | Not used. |
| inputs | Reference data, prices and band. |
Definition at line 710 of file reconcile.hpp.
| Plan< Broker > algotradelib::strategy::reconcile | ( | const TargetPosition & | target, |
| const Portfolio< Broker > & | portfolio, | ||
| const ReconcileInputs & | inputs ) |
Plans the cancellations and the order that move a holding to a target position.
When a stop order rests on the instrument, the steps above do not apply:
A drift below ReconcileInputs::tolerance_ yields an empty plan, but only when nothing has to be cancelled; an order working against the target is still cancelled.
| Broker | The broker tag. |
| target | The target position. |
| portfolio | The positions and working orders. |
| inputs | Reference data, prices, band and tolerance. |
Definition at line 489 of file reconcile.hpp.
Referenced by reconcile(), and reconcile().
|
inlineconstexprnoexcept |
Returns a lowercase name for a reason, such as "no_reference_data", for logs.
| reason | The reason. |
Definition at line 101 of file reconcile.hpp.
Referenced by live_program::print_loop(), and reject_reason_name().
|
inlineconstexprnoexcept |
Returns a lowercase name for a convention, such as "net_of_resting", for logs.
| convention | The convention. |
Definition at line 37 of file sellable_convention.hpp.
Referenced by sellable_convention_name().
|
inlineconstexprnoexcept |
Tests whether a size states a holding to reach (a target), rather than an amount to trade.
| kind | The kind. |
Definition at line 120 of file intent.hpp.
Referenced by algotradelib::runner::Runner< Strategy, CapsType, Tag, Executor >::retry_retained_targets(), and size_kind_is_target().
|
inline |
Converts a weight-sized intent into the target position it states.
The target is weight * portfolio value / price shares, rounded down onto the lot, where the price is the intent's limit if it has one and the reference price otherwise. The target keeps the intent's limit and tag. Reconciled as a target, its limit applies to whatever trade the difference needs, so above the weight a buy limit becomes the limit of a sell.
| intent | A weight-sized intent (SizeKind::TARGET_WEIGHT). |
| inputs | Reference data, reference price, and portfolio value. |
| std::logic_error | if intent is not weight-sized. |
Definition at line 862 of file reconcile.hpp.
Referenced by weight_target().
|
inlineconstexpr |
Every HaltReason, in declaration order.
|
inlineconstexpr |
Every MarketPhase, in declaration order.
|
inlineconstexpr |
The number of HaltReason values.
Definition at line 84 of file risk.hpp.
Referenced by algotradelib::strategy::RiskGuard::blocking_reason_for(), and algotradelib::strategy::RiskGuard::holds().