75 "all_stop_intents must list every StopIntent"
168 const int desired =
static_cast<int>(
intent);
169 int current = requested_.load(std::memory_order_relaxed);
172 if (requested_.compare_exchange_weak(
173 current, desired, std::memory_order_release, std::memory_order_relaxed)) {
184 return requested_.load(std::memory_order_acquire) >= 0;
191 std::optional<StopIntent>
intent() const noexcept {
192 const int held = requested_.load(std::memory_order_acquire);
200 void clear() noexcept { requested_.store(-1, std::memory_order_release); }
204 std::atomic<int> requested_{-1};
211 std::atomic<int>::is_always_lock_free,
212 "StopSource requires a lock-free atomic<int> to stay signal-safe");
241 bool enabled() const noexcept {
return !path_.empty(); }
247 const std::string&
path() const noexcept {
return path_; }
254 std::optional<StopIntent>
poll() {
255 unrecognized_.clear();
259 std::FILE* handle = std::fopen(path_.c_str(),
"rb");
260 if (handle ==
nullptr) {
263 char buffer[64] = {};
264 const std::size_t read = std::fread(buffer, 1,
sizeof(buffer) - 1, handle);
267 std::string_view text(buffer, read);
268 const auto begin = text.find_first_not_of(
" \t\r\n");
269 if (begin == std::string_view::npos) {
272 text.remove_prefix(begin);
273 const auto end = text.find_first_of(
" \t\r\n");
274 if (end != std::string_view::npos) {
275 text = text.substr(0, end);
281 unrecognized_.assign(text);
289 const std::string&
unrecognized() const noexcept {
return unrecognized_; }
293 std::string unrecognized_;
FileStopChannel(std::string path={})
Constructs a channel.
bool enabled() const noexcept
Tests whether a path was configured.
const std::string & path() const noexcept
Returns the watched path.
std::optional< StopIntent > poll()
Reads the file's first word.
const std::string & unrecognized() const noexcept
Returns the word the last poll did not recognize.
A stop request the loop polls; safe to set from a signal handler.
std::optional< StopIntent > intent() const noexcept
Returns the requested intent.
bool requested() const noexcept
Tests whether a stop has been requested.
void clear() noexcept
Clears the request (for tests, or a supervisor deliberately resuming); the loop never does.
void request(StopIntent intent) noexcept
Requests a stop, keeping whichever of this and an earlier intent is stronger.
A compile-time check that a list names every value of an enum, and a parser over the list.
Runs a strategy: the runner, the polling loop, the order journal, and stopping.
constexpr bool stop_intent_closes_positions(StopIntent intent) noexcept
Tests whether a stop intent closes positions with market orders, after withdrawing the working orders...
std::optional< StopIntent > stop_intent_from(std::string_view text) noexcept
Parses an intent's name.
constexpr int stop_intent_strength(StopIntent intent) noexcept
Returns an intent's strength: a stronger intent does everything a weaker one does.
constexpr std::array< StopIntent, 3 > all_stop_intents
Every StopIntent, in declaration order.
StopIntent
What an operator asks for when stopping a running loop.
@ FLATTEN
Withdraw, then ask the broker to close the positions with market orders.
@ WITHDRAW
Quiesce, then ask the broker to cancel the working orders.
@ QUIESCE
Stop sending new orders; nothing is cancelled or closed. The default, and what a signal means.
constexpr bool stop_intent_covers(StopIntent held, StopIntent candidate) noexcept
Tests whether one intent does everything another would.
constexpr bool stop_intent_closes(StopIntent intent) noexcept
Tests whether a stop intent asks for a closing pass (cancellations, and for FLATTEN closing orders) a...
constexpr std::string_view stop_intent_name(StopIntent intent) noexcept
Returns a lowercase name for an intent, as written in the control file ("withdraw").
The library: broker-neutral types (core), and the modules below.
constexpr std::optional< Enum > value_named(const std::array< Enum, N > &values, Name name, std::string_view text) noexcept
Returns the value of a list whose name is text, so a parser reads exactly what its writer writes.
constexpr bool lists_every_value(const std::array< Enum, N > &values, IsEnumerator is_enumerator) noexcept
Tests whether a list holds every value of an enum exactly once, in any order.