PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
exit_lifecycle.cpp
Go to the documentation of this file.
2
3#include "../../engine_internal.hpp"
6
7#include <cmath>
8
10
11std::optional<exit_legs::Operation> select_exit_suspension(
12 const exit_legs::Lifecycle& lifecycle, const ExitSuspensionContext& context) {
13 if (context.open_slice_this_bar || !context.standing) return std::nullopt;
14 const auto& prices = lifecycle.prices();
15 const bool has_trail = !std::isnan(prices.trail_points) || !std::isnan(prices.trail_price);
16 if (std::isnan(prices.stop_price) && std::isnan(prices.limit_price) && !has_trail)
17 return std::nullopt;
19 std::vector<exit_legs::Leg> retire;
20 if (has_trail) {
21 window.best = window.prefix = context.prior_best;
22 double activation = prices.trail_price;
23 if (!std::isnan(prices.trail_points)) {
24 const double ticks =
27 ? trail_points_to_ticks(prices.trail_points, context.tick)
28 : trail_points_to_ticks(prices.trail_points);
30 context.direction > 0
31 ? context.position_entry_price + ticks * context.tick
32 : context.position_entry_price - ticks * context.tick,
33 context.tick);
34 }
35 if (std::isfinite(activation) && std::isfinite(context.open)
36 && (context.direction > 0 ? context.open >= activation : context.open <= activation)) {
37 retire.push_back(exit_legs::Leg::Trail);
38 }
39 }
40 return exit_legs::Suspend{{exit_legs::Leg::Stop, exit_legs::Leg::Limit}, {}, window,
41 retire};
42}
43
45 exit_legs::Frame cause) {
46 if (lifecycle.dormant()) return exit_legs::CancelDeferredActivation{};
47 return exit_legs::Suspend{{exit_legs::Leg::Stop, exit_legs::Leg::Limit},
48 exit_legs::Barrier{cause}, {}, {}};
49}
50
52 const exit_legs::Lifecycle& lifecycle) {
53 if (lifecycle.pending_replacement())
54 return lifecycle.suspension()->replacement->revival_definition;
55 return lifecycle.definition(lifecycle.target().incarnation);
56}
57
59 const double original = lifecycle.original_stop();
60 return std::isfinite(original) ? original : lifecycle.prices().stop_price;
61}
62
63std::optional<exit_legs::Operation> select_exit_completion(
64 const exit_legs::Lifecycle& lifecycle, exit_legs::Frame completed) {
65 if (completed.domain == exit_legs::Domain::RawTicks
66 || completed.phase != exit_legs::Phase::AfterMargin) {
67 return std::nullopt;
68 }
69 const auto target = lifecycle.release_barrier();
70 if (!target) return std::nullopt;
71 return exit_legs::CompleteBarrier{completed, target};
72}
73
74} // namespace pineforge::compat::pine
std::optional< Barrier > release_barrier() const
Definition definition(uint64_t incarnation) const
const std::optional< Suspension > & suspension() const
exit_legs::Operation select_pair_hold(const exit_legs::Lifecycle &, exit_legs::Frame)
double trail_points_to_ticks(double trail_points)
double snap_trail_level_to_tick_grid(double price, double mintick)
double select_margin_revival_stop(const exit_legs::Lifecycle &)
std::optional< exit_legs::Operation > select_exit_completion(const exit_legs::Lifecycle &, exit_legs::Frame completed)
exit_legs::Definition select_replacement_revival_definition(const exit_legs::Lifecycle &)
std::optional< exit_legs::Operation > select_exit_suspension(const exit_legs::Lifecycle &, const ExitSuspensionContext &)
std::variant< BindOwner, Suspend, StageReplacement, CancelDeferredActivation, Restore, CompleteBarrier, Observe, Cancel > Operation
bool pine_callback_lifecycle_rule(PineCallbackLifecycleRule rule) noexcept