algotradelib 0.0.0.9000
C++ header-only library for algorithmic trading
Loading...
Searching...
No Matches
live_program.hpp File Reference

The production wiring of a live run, with no broker named: the part of example-live-program a consumer keeps. More...

#include <algotradelib/live>
#include <algotradelib/runner>
#include <chrono>
#include <cstddef>
#include <ostream>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
Include dependency graph for live_program.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  live_program::Settings
 What a run is told, gathered so main states it once and a test can state it differently. More...

Enumerations

enum class  live_program::Exit : int {
  CLEAN = 0 , CLOSING_INCOMPLETE = 1 , JOURNAL_REFUSED = 2 , RECOVERY_HALTED = 3 ,
  REFERENCE_UNREADABLE = 4 , LOOP_ABANDONED = 5 , LOCAL_FAILURE = 6 , ACCOUNT_UNRESOLVED = 7 ,
  OWED_ORDER = 8
}
 What the program exits with, so a supervisor can tell its endings apart. More...

Functions

template<typename Session, typename Runner>
bool live_program::load_reference_data (Session &session, Runner &bound, const Settings &settings, std::ostream &out)
 Reads each instrument's reference data (lot size, price grid) onto the runner, once; the loop does not poll it, and no order can be built without it.
void live_program::print_recovery (const runner::RecoveryReport &recovery, std::ostream &out)
 Prints what recovery found, in the words an operator acts on.
void live_program::print_how_to_stop (const Settings &settings, std::ostream &out)
 Prints how to stop the run, before it starts, so nobody reaches for kill -9.
void live_program::print_loop (const runner::LoopReport &report, std::ostream &out)
 Prints the loop's own figures and notes, which read the same in both modes.
void live_program::print_report (const runner::LoopReport &report, std::ostream &out)
 Prints the loop report and what closing_complete() does and does not mean.
bool live_program::stop_closes (const runner::LoopReport &report) noexcept
 Tests whether a run ended with a stop that sends closing instructions.
template<typename Loop>
void live_program::configure (Loop &loop, const Settings &settings)
 Configures the loop the same way for both modes: every age stated, the control file installed.
template<typename Strategy, typename Session, typename MarketData, typename Clock = runner::SteadyClock>
Exit live_program::trade (Session &session, MarketData &market_data, Strategy strategy_instance, const Settings &settings, runner::StopSource &stop, std::ostream &out, Clock clock={})
 Trades a strategy through a session, reading market data and reference data from another.
template<typename Strategy, typename Session, typename Clock = runner::SteadyClock>
Exit live_program::trade (Session &session, Strategy strategy_instance, const Settings &settings, runner::StopSource &stop, std::ostream &out, Clock clock={})
 Trades a strategy through a session: journal, recover, loop, report.
template<typename Strategy, typename Session, typename MarketData, typename Clock = runner::SteadyClock>
Exit live_program::observe (Session &session, MarketData &market_data, Strategy strategy_instance, const Settings &settings, runner::StopSource &stop, std::ostream &out, Clock clock={})
 Runs a strategy against a session's account and another's market data, with nothing to send through.
template<typename Strategy, typename Session, typename Clock = runner::SteadyClock>
Exit live_program::observe (Session &session, Strategy strategy_instance, const Settings &settings, runner::StopSource &stop, std::ostream &out, Clock clock={})
 Observes a strategy against a session's real data, reading market data from it too.

Detailed Description

The production wiring of a live run, with no broker named: the part of example-live-program a consumer keeps.

example-live-program.cpp chooses a broker and calls live_program::trade or live_program::observe. Everything that makes a run safe to restart is here, in the order it has to happen, and the test suite drives it against an in-memory session – which a main could not be.

The order is the whole point, and each step exists because leaving it out fails silently:

  1. Open the journal before binding. A runner that cannot record what it sends should not send.
  2. Bind through the journal (live::bind_journaled). live::bind has no journal, so an order in flight when the process dies leaves no trace, and the next start may send it again.
  3. Recover before the loop starts (runner::recover_runner), so whatever a previous process left owed is withheld until the broker's own lists resolve it. The runner is serialized (Runner::serialized): it places nothing before recovery, and each order owns its instrument until holdings account for it, across restarts too.
  4. Let the source resolve the journal (SessionSource::set_journal). Without it every recovered instrument stays withheld forever.
  5. State every age the loop asks about. A run that states none holds; a run that says "unbounded" sizes against a portfolio nobody bounded.
  6. Stop by signal or by control file, and read closing_complete() at the end.
  7. Unattended, watch for orders that stay owed. A serialized order keeps its instrument until holdings or its own history account for it, and the indeterminacy ledger need not say so: an order counted as timed out (Runner::orders_unconfirmed_timed_out) marks it only if it was never named, and one whose history reads keep failing is not counted at all. The loop stops placing by itself for two kinds: an order no sweep has named yet (a later sweep may still find it) and one held for an operator, owed longer than Settings::owed_order_limit_ (Exit::OWED_ORDER). An order the broker named is not watched that way: watch how long each has been owed (Runner::obligations, its sent_at_) and a non-empty Runner::ledger. PollingLoop::run reports only when it returns and has no hook inside a run; calling it in short chunks is no substitute, since each call starts its failure budget and poll schedule afresh.

Definition in file live_program.hpp.

Enumeration Type Documentation

◆ Exit

enum class live_program::Exit : int
strong

What the program exits with, so a supervisor can tell its endings apart.

Enumerator
CLEAN 0 

The run ended, and any closing pass it made got every instruction out.

CLOSING_INCOMPLETE 1 

A stop that closes ran and closing_complete() is false: read the broker's order list.

JOURNAL_REFUSED 2 

The journal would not open, so nothing was bound.

RECOVERY_HALTED 3 

Recovery halted the runner; nothing was started.

REFERENCE_UNREADABLE 4 

Reference data could not be read, so no order could be priced; nothing was started.

LOOP_ABANDONED 5 

The loop gave up after repeated poll failures: it was not trading when it returned.

LOCAL_FAILURE 6 

Local machinery failed during the run – usually a journal write – and the runner halted itself. Whatever it was sending when that happened is unknown until the broker's order list is read.

ACCOUNT_UNRESOLVED 7 

The program could not settle which account to trade (used by example-live-program).

OWED_ORDER 8 

The run stopped placing by itself: an order has been owed too long with nobody able to account for it. Starting again stops again; read the broker's lists and release the order first.

Definition at line 105 of file live_program.hpp.

Function Documentation

◆ configure()

template<typename Loop>
void live_program::configure ( Loop & loop,
const Settings & settings )

Configures the loop the same way for both modes: every age stated, the control file installed.

Template Parameters
LoopThe loop type.
Parameters
loopThe loop.
settingsThe settings.

Definition at line 295 of file live_program.hpp.

◆ load_reference_data()

template<typename Session, typename Runner>
bool live_program::load_reference_data ( Session & session,
Runner & bound,
const Settings & settings,
std::ostream & out )

Reads each instrument's reference data (lot size, price grid) onto the runner, once; the loop does not poll it, and no order can be built without it.

Template Parameters
SessionThe session type.
RunnerThe runner type.
Parameters
sessionThe session to read from.
boundThe runner.
settingsThe settings (its universe).
outWhere to print a failure.
Returns
true if every instrument was read; otherwise prints why and returns false.

Definition at line 144 of file live_program.hpp.

◆ observe() [1/2]

template<typename Strategy, typename Session, typename MarketData, typename Clock = runner::SteadyClock>
Exit live_program::observe ( Session & session,
MarketData & market_data,
Strategy strategy_instance,
const Settings & settings,
runner::StopSource & stop,
std::ostream & out,
Clock clock = {} )

Runs a strategy against a session's account and another's market data, with nothing to send through.

live::bind_observer gives the runner the session's real capabilities and no executor that reaches the broker, so the pipeline, the guard and the gates all run, and no order can leave. No journal is opened.

Template Parameters
StrategyThe strategy type.
SessionThe account session type.
MarketDataThe market-data session type.
ClockThe clock type.
Parameters
sessionThe account session.
market_dataThe session market data is read from.
strategy_instanceThe strategy.
settingsThe settings.
stopThe stop source the loop polls.
outWhere the program prints.
clockThe clock.
Returns
CLEAN, REFERENCE_UNREADABLE or LOOP_ABANDONED.

Definition at line 495 of file live_program.hpp.

◆ observe() [2/2]

template<typename Strategy, typename Session, typename Clock = runner::SteadyClock>
Exit live_program::observe ( Session & session,
Strategy strategy_instance,
const Settings & settings,
runner::StopSource & stop,
std::ostream & out,
Clock clock = {} )

Observes a strategy against a session's real data, reading market data from it too.

Template Parameters
StrategyThe strategy type.
SessionThe session type.
ClockThe clock type.
Parameters
sessionThe session.
strategy_instanceThe strategy.
settingsThe settings.
stopThe stop source the loop polls.
outWhere the program prints.
clockThe clock.
Returns
CLEAN, REFERENCE_UNREADABLE or LOOP_ABANDONED.

Definition at line 544 of file live_program.hpp.

◆ print_how_to_stop()

void live_program::print_how_to_stop ( const Settings & settings,
std::ostream & out )
inline

Prints how to stop the run, before it starts, so nobody reaches for kill -9.

Parameters
settingsThe settings (its control file).
outWhere to print.

Definition at line 193 of file live_program.hpp.

◆ print_loop()

void live_program::print_loop ( const runner::LoopReport & report,
std::ostream & out )
inline

Prints the loop's own figures and notes, which read the same in both modes.

Parameters
reportThe loop report.
outWhere to print.

Definition at line 216 of file live_program.hpp.

◆ print_recovery()

void live_program::print_recovery ( const runner::RecoveryReport & recovery,
std::ostream & out )
inline

Prints what recovery found, in the words an operator acts on.

Parameters
recoveryThe recovery report.
outWhere to print.

Definition at line 162 of file live_program.hpp.

◆ print_report()

void live_program::print_report ( const runner::LoopReport & report,
std::ostream & out )
inline

Prints the loop report and what closing_complete() does and does not mean.

Parameters
reportThe loop report.
outWhere to print.

Definition at line 272 of file live_program.hpp.

◆ stop_closes()

bool live_program::stop_closes ( const runner::LoopReport & report)
inlinenoexcept

Tests whether a run ended with a stop that sends closing instructions.

Parameters
reportThe loop report.
Returns
true for a WITHDRAW or FLATTEN stop.

Definition at line 284 of file live_program.hpp.

◆ trade() [1/2]

template<typename Strategy, typename Session, typename MarketData, typename Clock = runner::SteadyClock>
Exit live_program::trade ( Session & session,
MarketData & market_data,
Strategy strategy_instance,
const Settings & settings,
runner::StopSource & stop,
std::ostream & out,
Clock clock = {} )

Trades a strategy through a session, reading market data and reference data from another.

This places orders, through session only; market_data is only read. Use a session that cannot trade for market_data (a KIS session with an empty KisAccount, a Toss session with account sequence 0), so that a swapped pair refuses rather than trades.

Template Parameters
StrategyThe strategy type.
SessionThe trading session type.
MarketDataThe market-data session type.
ClockThe clock type.
Parameters
sessionThe session orders go through.
market_dataThe session market data is read from.
strategy_instanceThe strategy.
settingsThe settings.
stopThe stop source the loop polls.
outWhere the program prints.
clockThe clock.
Returns
CLEAN, CLOSING_INCOMPLETE, JOURNAL_REFUSED, RECOVERY_HALTED, REFERENCE_UNREADABLE, LOOP_ABANDONED, LOCAL_FAILURE or OWED_ORDER.

Definition at line 325 of file live_program.hpp.

◆ trade() [2/2]

template<typename Strategy, typename Session, typename Clock = runner::SteadyClock>
Exit live_program::trade ( Session & session,
Strategy strategy_instance,
const Settings & settings,
runner::StopSource & stop,
std::ostream & out,
Clock clock = {} )

Trades a strategy through a session: journal, recover, loop, report.

This places orders. observe is the same loop with nowhere to send.

Template Parameters
StrategyThe strategy type.
SessionThe session type.
ClockThe clock type.
Parameters
sessionThe session (orders and market data).
strategy_instanceThe strategy.
settingsThe settings.
stopThe stop source the loop polls.
outWhere the program prints.
clockThe clock.
Returns
CLEAN, CLOSING_INCOMPLETE, JOURNAL_REFUSED, RECOVERY_HALTED, REFERENCE_UNREADABLE, LOOP_ABANDONED, LOCAL_FAILURE or OWED_ORDER.

Definition at line 462 of file live_program.hpp.