1. Portfolio Rebalancing on the Probability Simplex
Let $\mathbf{w}_t \in \Delta^N$ be the portfolio allocation vector across $N$ assets satisfying $\sum w_{i,t} = 1$ and $w_{i,t} \ge 0$. Jiang et al. (2017) formulated continuous portfolio rebalancing as a deterministic policy gradient over historical price tensors.
2. Wealth Compounding & Proportional Transaction Costs
Let $\mathbf{y}_t$ be the asset return vector. Wealth updates as:
$$W_{t+1} = W_t \cdot \left[ \mathbf{w}_t \cdot \mathbf{y}_t - c \sum_{i=1}^N \left| w_{i,t} - w_{i,t-1}' \right| \right]$$import torch
import torch.nn as nn
import torch.nn.functional as F
class SimplexPortfolioPolicyNet(nn.Module):
"""
Continuous-control portfolio policy outputting allocation weights on unit simplex.
"""
def __init__(self, n_assets: int = 10, hidden_dim: int = 64):
super().__init__()
self.net = nn.Sequential(
nn.Linear(n_assets * 5, hidden_dim),
nn.LayerNorm(hidden_dim),
nn.SiLU(),
nn.Linear(hidden_dim, n_assets)
)
def forward(self, state: torch.Tensor) -> torch.Tensor:
logits = self.net(state)
# Softmax enforces non-negative budget sum to 1.0
return F.softmax(logits, dim=-1)
3. Institutional Summary
- Softmax Simplex Output: Always pass network logits through a Softmax layer to guarantee valid portfolio weights.