37inline std::optional<Plan>
plan(
double signed_position,
Reduce request)
noexcept {
38 if (!
finite(signed_position) || !
finite(request.units) || request.units < 0.0)
40 const double exposure = std::abs(signed_position);
41 const double close = std::min(request.units, exposure);
42 const double signed_close = signed_position > 0.0 ? -close
43 : signed_position < 0.0 ? close : 0.0;
47 const double after = signed_position + signed_close;
50 if (request.units > 0.0 && signed_position != 0.0 &&
after == signed_position)
52 return Plan(signed_position,
after, close, 0.0);
55inline std::optional<Plan>
plan(
double signed_position,
Transact request)
noexcept {
56 if (!
finite(signed_position) || !
finite(request.signed_units))
61 const double after = signed_position + request.signed_units;
63 if (request.signed_units != 0.0 &&
after == signed_position)
67 double open = request.signed_units;
68 if (signed_position != 0.0 && request.signed_units != 0.0
69 && ((signed_position > 0.0) != (request.signed_units > 0.0))) {
70 close = std::min(std::abs(signed_position), std::abs(request.signed_units));
71 const double remainder = std::abs(request.signed_units) - close;
72 open = request.signed_units > 0.0 ? remainder : -remainder;
74 if (!
finite(close) || close < 0.0 || !
finite(open))
return std::nullopt;
75 return Plan(signed_position,
after, close, open);