19[[nodiscard]]
BetaVelocity ratio_to_beta(
double raw_ratio)
noexcept {
21 const double abs_ratio = std::abs(raw_ratio);
31std::optional<BetaVelocity>
33 double max_velocity)
noexcept {
34 if (!std::isfinite(price_velocity)) {
37 if (max_velocity <= 0.0) {
42 const double raw_beta = std::abs(price_velocity) / max_velocity;
43 return ratio_to_beta(raw_beta);
48std::optional<BetaVelocity>
50 double max_return)
noexcept {
51 if (!std::isfinite(period_return)) {
54 if (max_return <= 0.0) {
59 const double raw_beta = std::abs(period_return) / max_return;
60 return ratio_to_beta(raw_beta);
67 double time_delta)
noexcept {
68 if (prices.size() < 2) {
71 if (time_delta <= 0.0) {
76 for (
double p : prices) {
77 if (!std::isfinite(p)) {
82 const std::size_t n = prices.size();
83 double total_abs_v = 0.0;
84 std::size_t count = 0;
86 for (std::size_t i = 0; i < n; ++i) {
90 v = (prices[1] - prices[0]) / time_delta;
91 }
else if (i == n - 1) {
93 v = (prices[n - 1] - prices[n - 2]) / time_delta;
96 v = (prices[i + 1] - prices[i - 1]) / (2.0 * time_delta);
98 total_abs_v += std::abs(v);
102 return total_abs_v /
static_cast<double>(count);
107std::optional<BetaVelocity>
111 double time_delta)
noexcept {
115 if (window > prices.size()) {
118 if (max_velocity <= 0.0) {
123 const std::size_t offset = prices.size() - window;
124 auto recent = prices.subspan(offset, window);
126 auto vel = meanAbsVelocity(recent, time_delta);
131 return fromPriceVelocity(*vel, max_velocity);
136std::optional<std::vector<BetaVelocity>>
138 double time_delta)
noexcept {
139 if (prices.size() < 2) {
142 if (time_delta <= 0.0) {
147 for (
double p : prices) {
148 if (!std::isfinite(p)) {
153 const std::size_t n = prices.size();
154 std::vector<BetaVelocity> result;
157 double running_max = 0.0;
159 for (std::size_t i = 0; i < n; ++i) {
170 v = std::abs((prices[1] - prices[0]) / time_delta);
173 v = std::abs((prices[1] - prices[0]) / time_delta);
177 v = std::abs((prices[i] - prices[i - 1]) / time_delta);
181 if (v > running_max) {
187 if (running_max < 1e-15) {
191 const double raw_beta = v / running_max;
192 beta = ratio_to_beta(raw_beta);
195 result.push_back(beta);
208 return !isNewtonian(beta);
220 const double clamped = std::clamp(raw_beta, -limit, limit);
224 if (clamped >= limit) {
227 if (clamped <= -limit) {
237 double effective_mass,
238 double c_market)
noexcept {
239 if (effective_mass <= 0.0) {
252 return (g->value - 1.0) * effective_mass * c_market * c_market;
270 const double numerator = 1.0 + beta.value;
271 const double denominator = 1.0 - beta.value;
274 if (denominator <= 0.0 || numerator <= 0.0) {
278 return std::sqrt(numerator / denominator);
static std::optional< double > meanAbsVelocity(std::span< const double > prices, double time_delta) noexcept
static std::optional< BetaVelocity > fromReturn(double period_return, double max_return) noexcept
static bool isRelativistic(BetaVelocity beta) noexcept
static std::optional< BetaVelocity > fromRollingWindow(std::span< const double > prices, std::size_t window, double max_velocity, double time_delta) noexcept
static std::optional< double > kineticEnergy(BetaVelocity beta, double effective_mass, double c_market=constants::SPEED_OF_INFORMATION) noexcept
static std::optional< BetaVelocity > fromPriceVelocity(double price_velocity, double max_velocity) noexcept
static bool isNewtonian(BetaVelocity beta) noexcept
static std::optional< std::vector< BetaVelocity > > fromPriceVelocityOnline(std::span< const double > prices, double time_delta) noexcept
static std::optional< double > dopplerFactor(BetaVelocity beta) noexcept
static BetaVelocity clamp(double raw_beta) noexcept
static bool isValid(BetaVelocity beta) noexcept
Return true if β is in the valid safe range (|β| < BETA_MAX_SAFE).
static constexpr double BETA_NEWTONIAN_THRESHOLD
Below this β, relativistic corrections are negligible (γ ≈ 1 + β²/2).
static constexpr double BETA_MAX_SAFE
BetaCalculator — financial-to-physics velocity mapping (AGT-01).