39 double expected_return) {
40 events_.push_back(std::move(event));
41 expected_returns_.push_back(expected_return);
45 return events_.size();
50 expected_returns_.clear();
55double RelativisticPortfolio::compute_beta(
const AssetEvent& e)
const noexcept {
58 const double c = config_.c_market;
62 const double beta = std::abs(e.P) / (c * std::abs(e.t));
67double RelativisticPortfolio::gamma_factor(
double beta)
noexcept {
70 const double denom = std::sqrt(1.0 - beta_clamped * beta_clamped);
81std::optional<Eigen::VectorXd>
83 const std::size_t N = events_.size();
88 Eigen::VectorXd mu_rel(
static_cast<int>(N));
89 for (std::size_t i = 0; i < N; ++i) {
90 const double beta = compute_beta(events_[i]);
91 const double gamma = gamma_factor(beta);
92 mu_rel(
static_cast<int>(i)) = gamma * expected_returns_[i];
99std::optional<Eigen::MatrixXd>
101 if (events_.size() < 2) {
105 for (
const auto& ev : events_) {
114RelativisticPortfolio::project_simplex(
const Eigen::VectorXd& v)
noexcept {
117 const int n =
static_cast<int>(v.size());
120 Eigen::VectorXd u = v;
121 std::sort(u.data(), u.data() + n, std::greater<double>());
126 for (
int j = 0; j < n; ++j) {
128 if (u(j) - (cumsum - 1.0) /
static_cast<double>(j + 1) > 0.0) {
134 double cumsum_rho = 0.0;
135 for (
int j = 0; j <= rho; ++j) {
138 const double theta = (cumsum_rho - 1.0) /
static_cast<double>(rho + 1);
141 Eigen::VectorXd w(n);
142 for (
int i = 0; i < n; ++i) {
143 w(i) = std::max(v(i) - theta, 0.0);
151RelativisticPortfolio::geodesic_gradient(
const Eigen::MatrixXd& sigma_st,
152 const Eigen::VectorXd& w)
noexcept {
154 return 2.0 * sigma_st * w;
159std::optional<OptimizationResult>
161 double risk_tolerance)
const noexcept {
162 const std::size_t N = events_.size();
168 auto sigma_opt = spacetime_covariance();
172 Eigen::MatrixXd sigma_st = *sigma_opt;
176 sigma_st += config_.regularisation *
177 Eigen::MatrixXd::Identity(
static_cast<int>(N),
178 static_cast<int>(N));
181 auto mu_opt = relativistic_returns();
185 const Eigen::VectorXd mu_rel = *mu_opt;
188 Eigen::VectorXd w = Eigen::VectorXd::Constant(
189 static_cast<int>(N), 1.0 /
static_cast<double>(N));
191 const double alpha = config_.step_size;
192 const double tol = config_.convergence_tol;
193 const int max_iter = config_.max_iterations;
196 bool converged =
false;
198 for (iter = 0; iter < max_iter; ++iter) {
200 Eigen::VectorXd grad = risk_tolerance * geodesic_gradient(sigma_st, w);
205 const double current_return = w.dot(mu_rel);
206 if (current_return < target_return) {
208 const double penalty = risk_tolerance;
209 grad -= penalty * mu_rel;
213 Eigen::VectorXd w_new = project_simplex(w - alpha * grad);
216 const double step_norm = (w_new - w).norm();
219 if (step_norm < tol) {
227 const double geo_risk = risk_tolerance * w.dot(sigma_st * w);
228 const double exp_ret = w.dot(mu_rel);
232 .geodesic_risk = geo_risk,
233 .expected_return = exp_ret,
235 .converged = converged,
std::optional< Eigen::MatrixXd > compute_spacetime_covariance() const noexcept
void add_asset(AssetEvent event)
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
RelativisticPortfolio(OptimizerConfig config=OptimizerConfig{}) noexcept
Construct with optional configuration.
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
Physical and financial constants for the SRFM system.
static constexpr double FLOAT_EPSILON
General floating-point comparison epsilon.
static constexpr double BETA_MAX_SAFE
Relativistic Portfolio Optimization on the Financial Manifold.
Result of a single portfolio optimization run.
Eigen::VectorXd weights
Optimal asset weights (sum to 1, >= 0)
Tuning parameters for the relativistic portfolio optimizer.
double c_market
Speed-of-information parameter for Lorentz factor computation.