Special Relativity in Financial Modeling 1.0.0
Lorentz transforms, spacetime classification, and geodesic price paths for quantitative finance
Loading...
Searching...
No Matches
engine.cpp
Go to the documentation of this file.
1/**
2 * @file engine.cpp
3 * @brief Full SRFM pipeline engine implementation (AGT-13 / SRFM).
4 *
5 * See engine.hpp for the full module contract.
6 */
7
8#include "engine.hpp"
9
10#include "../beta_calculator/beta_calculator.hpp"
11#include "../geodesic/geodesic_solver.hpp"
12#include "../manifold/spacetime_manifold.hpp"
13#include "../momentum/momentum.hpp"
14
15#include <cctype>
16#include <charconv>
17#include <cmath>
18#include <cstring>
19
20namespace srfm::engine {
21
22// ── Price parsing ─────────────────────────────────────────────────────────────
23
24std::vector<double>
25Engine::parse_prices(std::string_view data) const noexcept {
26 std::vector<double> prices;
27 prices.reserve(64);
28
29 const char* ptr = data.data();
30 const char* end = ptr + data.size();
31
32 while (ptr < end) {
33 // Skip non-numeric leading characters (delimiters and garbage)
34 while (ptr < end && !std::isdigit(static_cast<unsigned char>(*ptr))
35 && *ptr != '-' && *ptr != '+' && *ptr != '.') {
36 ++ptr;
37 }
38 if (ptr >= end) break;
39
40 // Attempt to parse a double
41 double value = 0.0;
42 auto [next_ptr, ec] = std::from_chars(ptr, end, value);
43 if (ec == std::errc{} && std::isfinite(value) && value > 0.0) {
44 prices.push_back(value);
45 }
46 // Advance past the attempted token (at least one char to avoid infinite loop)
47 if (next_ptr == ptr) {
48 ++ptr;
49 } else {
50 ptr = next_ptr;
51 }
52 }
53
54 return prices;
55}
56
57// ── Engine::process ───────────────────────────────────────────────────────────
58
59std::optional<PipelineResult>
60Engine::process(std::string_view data) const noexcept {
61 // Step 1: Parse prices
62 const auto prices = parse_prices(data);
63 if (prices.size() < 2) return std::nullopt;
64
65 // Step 2: BetaCalculator — compute β from streaming prices
67 auto beta_result = calc.fromPriceVelocityOnline(prices, 1.0);
68 if (!beta_result) return std::nullopt;
69
70 // Step 3: SpacetimeManifold — classify regime using mean price as event x
72 double mean_price = 0.0;
73 for (const double p : prices) mean_price += p;
74 mean_price /= static_cast<double>(prices.size());
75
77 static_cast<double>(prices.size()), // t = time index
78 beta_result->beta, // x = beta (velocity proxy)
79 mean_price, // y = mean price
80 beta_result->gamma - 1.0 // z = Lorentz excess
81 };
82
83 auto regime_opt = mfld.process(event);
84 if (!regime_opt) return std::nullopt;
85
86 // Step 4: GeodesicSolver — integrate one geodesic in flat spacetime
87 // (verifies the solver doesn't crash; result is a straight line in flat space)
89 const auto flat_metric = manifold::MetricTensor::minkowski();
90 geodesic::GeodesicState init_state{};
91 init_state.x[0] = event.t;
92 init_state.x[1] = event.x;
93 init_state.x[2] = event.y > 0.0 ? std::log(event.y) : 0.0;
94 init_state.x[3] = event.z;
95 init_state.u[0] = 1.0; // proper-time flow
96 init_state.u[1] = beta_result->beta;
97 init_state.u[2] = 0.0;
98 init_state.u[3] = 0.0;
99
100 // Use 10 steps — enough to verify no crash, not enough to be slow
101 const auto geo_result = solver.solve(init_state, flat_metric, 10, 0.01);
102 if (!geo_result) return std::nullopt;
103
104 // Step 5: RelativisticSignalProcessor — compute γ-corrected signal
106 auto bv = momentum::BetaVelocity::make(beta_result->beta);
107 if (!bv) return std::nullopt;
108 // Use mean_price as the effective-mass proxy (a natural liquidity-weighted
109 // scale factor). γ was incorrect: it is dimensionless and already applied
110 // inside RelativisticSignalProcessor, so using it here caused γ²·price output.
111 auto meff = momentum::EffectiveMass::make(mean_price > 0.0 ? mean_price : 1.0);
112 if (!meff) {
114 if (!meff) return std::nullopt;
115 }
116
117 const momentum::RawSignal raw_sig{mean_price};
118 auto sig_result = proc.process_one(raw_sig, *bv, *meff);
119 if (!sig_result) return std::nullopt;
120
121 return PipelineResult{
122 beta_result->beta,
123 beta_result->gamma,
124 beta_result->rapidity,
125 beta_result->doppler,
126 *regime_opt,
127 sig_result->adjusted_value,
128 prices.size()
129 };
130}
131
132} // namespace srfm::engine
std::optional< BetaVelocityResult > fromPriceVelocityOnline(const std::vector< double > &prices, double c_market=1.0) const noexcept
Compute BetaVelocityResult from a streaming price series.
std::optional< PipelineResult > process(std::string_view data) const noexcept
Process a CSV-like byte sequence through the full pipeline.
Definition engine.cpp:60
std::optional< GeodesicState > solve(const GeodesicState &initial, const MetricTensor &metric, int steps, double dt) const noexcept
Integrate the geodesic equation for steps RK4 steps.
std::optional< Regime > process(const SpacetimeEvent &event) const noexcept
Classify a spacetime event into a relativistic regime.
static std::optional< BetaVelocity > make(double value) noexcept
Validate and construct a BetaVelocity.
Definition momentum.cpp:18
static std::optional< EffectiveMass > make(double value) noexcept
Validate and construct an EffectiveMass.
Definition momentum.cpp:27
std::optional< RelativisticSignal > process_one(RawSignal signal, BetaVelocity beta, EffectiveMass m_eff) const noexcept
Process a single raw signal (convenience wrapper).
Definition momentum.cpp:101
Full SRFM pipeline engine: CSV → relativistic signal (AGT-13 / SRFM)
Full output of one Engine pipeline run.
Definition engine.hpp:48
double beta
Normalised market velocity β
Definition engine.hpp:49
State of a particle on a geodesic: position x^μ and 4-velocity u^μ.
std::array< double, DIM > x
Position x^μ (μ = 0…3)
static MetricTensor minkowski() noexcept
Construct the flat Minkowski metric η = diag(−1,+1,+1,+1).
A point in 4D spacetime (t, x, y, z).
A raw (pre-correction) market signal value.
Definition momentum.hpp:157