Special Relativity in Financial Modeling 1.0.0
Lorentz transforms, spacetime classification, and geodesic price paths for quantitative finance
Loading...
Searching...
No Matches
relativistic_optimizer.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file include/relativistic_optimizer.hpp
4/// @brief Relativistic Portfolio Optimization on the Financial Manifold.
5///
6/// # Module: Relativistic Portfolio Optimizer
7///
8/// ## Responsibility
9/// Formulate the Markowitz mean-variance portfolio optimization problem as a
10/// geodesic problem on the N-asset financial manifold, replacing the Euclidean
11/// variance risk measure with the geodesic distance in the Lorentzian manifold.
12///
13/// ## Key Idea
14/// Classical Markowitz minimises w^T Σ w subject to w^T μ = r_target, Σw = 1.
15/// Here we replace the quadratic risk measure w^T Σ w with the spacetime
16/// geodesic distance between the current portfolio state and the target return
17/// state on the financial manifold. This penalises large displacements in the
18/// "causal" (TIMELIKE) direction more heavily than classical variance.
19///
20/// Additionally, expected returns are corrected by the Lorentz factor γ(β):
21/// μ_rel_i = γ(β_i) · μ_i
22/// where β_i is the normalised price velocity for asset i, computed from its
23/// AssetEvent. High-velocity (noisy) assets are down-weighted; causal
24/// (low-β) assets retain full expected return.
25///
26/// ## Optimization Problem
27/// minimise d_geo(w, w_0)² (geodesic risk measure)
28/// subject to w^T μ_rel ≥ r_target (relativistic return constraint)
29/// Σ_i w_i = 1 (full investment)
30/// w_i ≥ 0 (long-only)
31///
32/// Solved via projected gradient descent on the simplex.
33///
34/// ## Guarantees
35/// - Returns nullopt rather than throwing on degenerate inputs.
36/// - No raw pointers; Eigen3 owns all matrix storage.
37/// - All iterative algorithms are bounded (max_iterations parameter).
38///
39/// ## Dependencies
40/// - Eigen3
41/// - include/portfolio_manifold.hpp (AssetEvent, MinkowskiCovariance)
42/// - srfm/constants.hpp
43
45
46#include <Eigen/Dense>
47#include <optional>
48#include <vector>
49
50namespace srfm::portfolio {
51
52// ─── OptimizerConfig ──────────────────────────────────────────────────────────
53
54/// Tuning parameters for the relativistic portfolio optimizer.
56 /// Maximum number of projected gradient descent iterations.
57 int max_iterations = 1000;
58
59 /// Step size for gradient descent (learning rate).
60 double step_size = 1e-3;
61
62 /// Convergence tolerance: stop when ||w_{k+1} − w_k||₂ < tol.
63 double convergence_tol = 1e-8;
64
65 /// Tikhonov regularisation strength added to the geodesic metric.
66 /// Prevents degenerate geodesic distances when assets are nearly collinear.
67 double regularisation = 1e-6;
68
69 /// Speed-of-information parameter for Lorentz factor computation.
71};
72
73// ─── OptimizationResult ───────────────────────────────────────────────────────
74
75/// Result of a single portfolio optimization run.
77 Eigen::VectorXd weights; ///< Optimal asset weights (sum to 1, >= 0)
78 double geodesic_risk; ///< Achieved geodesic risk d_geo²
79 double expected_return; ///< w^T μ_rel (relativistic expected return)
80 int iterations; ///< Number of gradient descent iterations
81 bool converged; ///< True iff convergence_tol was reached
82};
83
84// ─── RelativisticPortfolio ────────────────────────────────────────────────────
85
86/// Relativistic portfolio optimizer: Markowitz on the financial manifold.
87///
88/// ## Workflow
89/// 1. Construct with a list of AssetEvents (one per asset in the portfolio).
90/// 2. Set expected returns via set_expected_returns().
91/// 3. Call optimize_weights(target_return, risk_tolerance).
92///
93/// The spacetime covariance matrix Σ_st is computed internally from the
94/// AssetEvents using MinkowskiCovariance and used as the geodesic metric.
95///
96/// ## Example
97/// ```cpp
98/// RelativisticPortfolio rp;
99/// rp.add_asset(AssetEvent{"AAPL", 1.0, 150.0, 1e8, 2.4e12}, 0.12);
100/// rp.add_asset(AssetEvent{"MSFT", 1.0, 290.0, 8e7, 2.1e12}, 0.10);
101/// auto result = rp.optimize_weights(0.08, 0.5);
102/// if (result) {
103/// std::cout << result->weights << "\n";
104/// }
105/// ```
107public:
108 /// Construct with optional configuration.
109 explicit RelativisticPortfolio(OptimizerConfig config = OptimizerConfig{}) noexcept;
110
111 /// Add an asset with its annualised expected return.
112 ///
113 /// @param event AssetEvent providing spacetime coordinates.
114 /// @param expected_return Annualised expected return for this asset (e.g. 0.10 = 10%).
115 void add_asset(AssetEvent event, double expected_return);
116
117 /// Return the number of assets currently in the portfolio.
118 [[nodiscard]] std::size_t n_assets() const noexcept;
119
120 /// Compute the gamma-weighted (relativistic) expected return vector.
121 ///
122 /// For each asset i:
123 /// μ_rel_i = γ(β_i) · μ_i
124 /// where β_i = |ΔP_i| / (c_market · |Δt_i|) approximated from the event
125 /// coordinates relative to a reference event at the origin.
126 ///
127 /// @return Vector of length n_assets(), or nullopt if no assets added.
128 [[nodiscard]] std::optional<Eigen::VectorXd>
129 relativistic_returns() const noexcept;
130
131 /// Compute the NxN spacetime covariance matrix Σ_st.
132 ///
133 /// Uses MinkowskiCovariance internally. Returns nullopt if fewer than 2
134 /// assets are loaded.
135 ///
136 /// @return NxN Eigen::MatrixXd, or nullopt on failure.
137 [[nodiscard]] std::optional<Eigen::MatrixXd>
138 spacetime_covariance() const noexcept;
139
140 /// Run the relativistic portfolio optimization.
141 ///
142 /// Formulates the problem as a geodesic minimization on the financial
143 /// manifold and solves it via projected gradient descent on the simplex.
144 ///
145 /// @param target_return Minimum required relativistic expected return.
146 /// @param risk_tolerance Scalar multiplier on the geodesic risk term
147 /// (higher = more risk-averse; default 1.0).
148 /// @return OptimizationResult, or nullopt if fewer than 2
149 /// assets are loaded or the covariance is degenerate.
150 [[nodiscard]] std::optional<OptimizationResult>
151 optimize_weights(double target_return,
152 double risk_tolerance = 1.0) const noexcept;
153
154 /// Remove all assets from the portfolio.
155 void clear() noexcept;
156
157private:
158 /// Compute β_i for asset i using the price/time coordinates of its event.
159 [[nodiscard]] double compute_beta(const AssetEvent& e) const noexcept;
160
161 /// Compute the Lorentz factor γ(β) clamped to BETA_MAX_SAFE.
162 [[nodiscard]] static double gamma_factor(double beta) noexcept;
163
164 /// Project a weight vector onto the probability simplex
165 /// { w : Σw_i = 1, w_i >= 0 }.
166 /// Uses the O(N log N) algorithm of Duchi et al. (2008).
167 [[nodiscard]] static Eigen::VectorXd
168 project_simplex(const Eigen::VectorXd& v) noexcept;
169
170 /// Compute the geodesic risk gradient:
171 /// ∇_w d²_geo(w) = 2 · Σ_st · w (quadratic form with spacetime metric)
172 [[nodiscard]] static Eigen::VectorXd
173 geodesic_gradient(const Eigen::MatrixXd& sigma_st,
174 const Eigen::VectorXd& w) noexcept;
175
176 std::vector<AssetEvent> events_; ///< Per-asset spacetime events
177 std::vector<double> expected_returns_; ///< Per-asset expected returns
178 OptimizerConfig config_; ///< Optimizer tuning parameters
179};
180
181} // namespace srfm::portfolio
std::size_t n_assets() const noexcept
Return the number of assets currently in the portfolio.
std::optional< Eigen::MatrixXd > spacetime_covariance() const noexcept
std::optional< Eigen::VectorXd > relativistic_returns() const noexcept
void add_asset(AssetEvent event, double expected_return)
void clear() noexcept
Remove all assets from the portfolio.
std::optional< OptimizationResult > optimize_weights(double target_return, double risk_tolerance=1.0) const noexcept
static constexpr double SPEED_OF_INFORMATION
Definition constants.hpp:37
N-Asset Minkowski Covariance Matrix and Spacetime Causal Graph.
Result of a single portfolio optimization run.
int iterations
Number of gradient descent iterations.
Eigen::VectorXd weights
Optimal asset weights (sum to 1, >= 0)
double expected_return
w^T μ_rel (relativistic expected return)
double geodesic_risk
Achieved geodesic risk d_geo²
bool converged
True iff convergence_tol was reached.
Tuning parameters for the relativistic portfolio optimizer.
double step_size
Step size for gradient descent (learning rate).
double c_market
Speed-of-information parameter for Lorentz factor computation.
int max_iterations
Maximum number of projected gradient descent iterations.
double convergence_tol
Convergence tolerance: stop when ||w_{k+1} − w_k||₂ < tol.