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

What a strategy is, how a runner calls its handlers, and ATL_ASSERT_STRATEGY. More...

#include "./event.hpp"
#include "./intent.hpp"
#include "./portfolio.hpp"
#include <chrono>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
Include dependency graph for concept.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  algotradelib::strategy::NoCaps
 A capability set in which the broker implements nothing optional. More...
struct  algotradelib::strategy::AllCaps
 A capability set in which the broker implements everything optional. More...
struct  algotradelib::strategy::ProbeBroker
 The broker tag of a probe context; nothing it issues reaches a market. More...
class  algotradelib::strategy::ProbeContextT< CapsType >
 A context for testing a strategy without a runner: it records what the strategy asks for. More...
class  algotradelib::strategy::ProbeContextT< CapsType >::Log
 A log that keeps each line in memory for a test to read. More...
struct  algotradelib::strategy::StrategyConformance< S, Ctx >
 The checks behind ATL_ASSERT_STRATEGY; instantiating it reports what is wrong with S. More...

Namespaces

namespace  algotradelib
 The library: broker-neutral types (core), and the modules below.
namespace  algotradelib::strategy
 What a strategy sees and emits: events, intents, the portfolio, reconciliation and risk limits.
namespace  algotradelib::strategy::dispatch
 Calls a strategy's handlers, skipping the ones it does not declare.

Macros

#define ATL_DETECT_DECLARED(NAME)
#define ATL_ASSERT_STRATEGY(S, Ctx)
 Asserts at compile time that S is a strategy a runner with context Ctx can drive.

Typedefs

using algotradelib::strategy::MinimalContext = ProbeContextT<NoCaps>
 A probe context whose broker implements nothing optional.
using algotradelib::strategy::FullContext = ProbeContextT<AllCaps>
 A probe context whose broker implements everything optional.

Functions

template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::start (S &strategy, Ctx &context)
 Calls strategy.on_start(context) if the strategy declares on_start; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::stop (S &strategy, Ctx &context)
 Calls strategy.on_stop(context) if the strategy declares on_stop; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::bar (S &strategy, Ctx &context, const BarEvent &event)
 Calls strategy.on_bar(context, event) if the strategy declares on_bar; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::bars (S &strategy, Ctx &context, const BarSlice &slice)
 Calls strategy.on_bars(context, slice) if the strategy declares on_bars; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::quote (S &strategy, Ctx &context, const QuoteEvent &event)
 Calls strategy.on_quote(context, event) if the strategy declares on_quote; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::fill (S &strategy, Ctx &context, const Fill &event)
 Calls strategy.on_fill(context, event) if the strategy declares on_fill; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::order_update (S &strategy, Ctx &context, const OrderSnapshot &event)
 Calls strategy.on_order_update(context, event) if the strategy declares on_order_update; otherwise does nothing.
template<typename S, typename Ctx>
void algotradelib::strategy::dispatch::phase (S &strategy, Ctx &context, const MarketPhase &event)
 Calls strategy.on_phase(context, event) if the strategy declares on_phase; otherwise does nothing.

Detailed Description

What a strategy is, how a runner calls its handlers, and ATL_ASSERT_STRATEGY.

A strategy is a plain struct whose handlers are member templates on the context type. Every handler is optional; declare only the ones you need:

struct MyStrategy {
struct Params { std::size_t window_{20}; };
Params params_;
template <class Ctx> void on_start(Ctx& ctx);
template <class Ctx> void on_bar(Ctx& ctx, const BarEvent& bar); // or on_bars, not both
template <class Ctx> void on_quote(Ctx& ctx, const QuoteEvent& quote);
template <class Ctx> void on_fill(Ctx& ctx, const Fill& fill);
template <class Ctx> void on_order_update(Ctx& ctx, const OrderSnapshot& order);
template <class Ctx> void on_phase(Ctx& ctx, const MarketPhase& phase);
template <class Ctx> void on_stop(Ctx& ctx);
};

on_bar receives one bar at a time. A strategy that decides on several instruments together (a pair's hedge ratio, a ranking across a universe) declares instead template <class Ctx> void on_bars(Ctx& ctx, const BarSlice& slice);, called once per period end and interval with every instrument's bar for it, after all of them are cached. A strategy declares one of the two; declaring both does not compile, so neither runs in silence beside the other.

Because the handlers are templates, the same strategy runs under every runner: a dry run, a live session with any broker, and a backtest. Take the context by reference; a context cannot be copied, so a handler that takes it by value does not compile.

Warning
on_fill is called in a backtest but never by the shipped live loop; see Fill.

Definition in file concept.hpp.

Macro Definition Documentation

◆ ATL_ASSERT_STRATEGY

#define ATL_ASSERT_STRATEGY ( S,
Ctx )
Value:
static_assert( \
"Strategy does not satisfy the algotradelib strategy surface; see the messages above" \
)
static constexpr bool value
Always true; reading it compiles every handler call the runner makes with Ctx.
Definition concept.hpp:691

Asserts at compile time that S is a strategy a runner with context Ctx can drive.

Checks that:

  • S is a class and not final;
  • Ctx cannot be copied, so a handler taking it by value does not compile;
  • S declares at least one handler, and not both on_bar and on_bars;
  • every handler S declares can be called the way a runner calls it with Ctx. Each handler's body is compiled for Ctx, including handlers for events the program never feeds.

With MinimalContext or FullContext it checks handlers against a probe without series accessors; a strategy that reads bars() is checked by its runner instead. Usable at namespace, class and block scope.

Parameters
SThe strategy type.
CtxThe context type.
Note
Not detected: a handler that takes by value a copyable base class of the context.

Definition at line 712 of file concept.hpp.

◆ ATL_DETECT_DECLARED

#define ATL_DETECT_DECLARED ( NAME)
Value:
struct NAME##_fallback { \
int NAME; \
}; \
template <typename S> \
struct NAME##_probe : S, NAME##_fallback {}; \
template <typename S, typename = void> \
struct NAME##_is_ambiguous : std::true_type {}; \
template <typename S> \
struct NAME##_is_ambiguous<S, std::void_t<decltype(&NAME##_probe<S>::NAME)>> \
: std::false_type {}; \
template <typename S> \
constexpr bool declares_##NAME = std::conjunction_v< \
std::is_class<S>, std::negation<std::is_final<S>>, NAME##_is_ambiguous<S> \
>

Detects that S declares a member named NAME: of any kind, signature or access, inherited included.

Handlers are optional, so something has to decide whether to call one, and this is it: a declared name is called, and a call that does not compile is the compiler's error at the call (see dispatch). The name is what the author wrote; asking instead whether a particular call compiles would read a handler with a wrong parameter as absent and skip it in silence. Looking NAME up in a class that derives from S and from one declaring int NAME is ambiguous exactly when S declares it, which works for a member template, where &S::NAME cannot name one.

A final class cannot be derived from, and a non-class type has no members, so neither can be looked into; dispatch and StrategyConformance refuse both rather than read them as declaring nothing.

Definition at line 68 of file concept.hpp.