Risk Management
Portfolio-Level Risk: Multiple Algos
You have two strategies running. Each has a 2% daily loss limit, a maximum drawdown limit, and a position sizing rule. Each is performing within its individual risk parameters. The account is down 8% on the week.
This is the scenario that confuses traders who learned risk management one strategy at a time. Individual limits are necessary but not sufficient. When strategies move together — because they are exposed to the same underlying risk — combined losses exceed what any single strategy's parameters would imply.
Multi-strategy risk management is a different discipline from single-strategy risk management. The additional variables are correlation, capital allocation across strategies, and portfolio-level monitoring that aggregates across everything running simultaneously.
Why Individual Limits Are Not Enough
Consider two mean-reversion strategies. Strategy A trades AAPL reversions. Strategy B trades MSFT reversions. Each has a $500 daily loss limit and a 3% maximum drawdown. On paper, worst-case combined daily loss is $1,000.
In practice, when a macro event hits — a Fed announcement, a market-wide selloff, a credit event — AAPL and MSFT do not mean-revert independently. They both trend sharply in the same direction as institutional traders de-risk. Both strategies trigger their individual stop-losses simultaneously. The "$1,000 worst case" has a hidden assumption: that the two strategies' losses are independent. They are not.
The same problem applies to theta-harvesting strategies on different underlyings, to gap trading strategies across correlated sectors, to any pair of strategies that share a common risk factor. The moment you run more than one strategy, correlation analysis is not optional — it is the primary portfolio risk management task.
Two strategies with a return correlation above 0.7 should be treated as a single position for sizing purposes. Their risk parameters should be combined, not summed independently.
Strategy Correlation Analysis
To measure correlation between strategies, you need a time series of daily returns for each strategy — not individual trade returns, but daily P&L as a percentage of allocated capital.
Given two series r_A and r_B, the Pearson correlation is:
ρ = cov(r_A, r_B) / (σ_A × σ_B)
Values above 0.7 indicate high correlation. Above 0.85 is nearly redundant — you are essentially running the same strategy twice with different tickers.
The practical implication: when strategies A and B have correlation 0.75, their combined variance is not the sum of individual variances. It is:
σ_portfolio² = w_A²σ_A² + w_B²σ_B² + 2·w_A·w_B·ρ·σ_A·σ_B
At high correlation, the cross-term 2·w_A·w_B·ρ·σ_A·σ_B inflates total portfolio variance well beyond what each strategy contributes independently. A portfolio of five highly correlated strategies can have nearly the same risk as a single strategy at full size.
Correlation also shifts in regimes. Strategies that show 0.3 correlation in normal markets may show 0.8 correlation in a crisis. The trailing correlation over the last 30 days is more relevant than the 252-day figure when assessing current portfolio risk. Both figures are worth tracking.
Capital Allocation Methods
How you allocate capital across strategies affects both expected returns and portfolio risk.
Equal-weight allocation distributes capital uniformly. If you have four strategies and $100,000, each gets $25,000. This is simple and avoids concentration. The problem: it ignores that strategies have different volatilities. A strategy with 8% annualized return volatility allocated $25,000 contributes more portfolio risk than a strategy with 3% volatility at the same allocation.
Volatility-parity allocation adjusts capital so that each strategy contributes equal risk. The lower the strategy's volatility, the more capital it receives; higher-volatility strategies receive less. The formula for target allocation weight is:
w_i = (1/σ_i) / Σ(1/σ_j)
Where σ_i is the annualized return volatility of strategy i. In a four-strategy portfolio with volatilities of 3%, 5%, 8%, and 12%, the capital weights would be roughly 42%, 25%, 16%, and 11% respectively. The low-volatility strategy gets the largest allocation even if its raw return is lower, because it contributes less portfolio variance per dollar.
Kelly-adjusted portfolio allocation extends the single-strategy Kelly criterion to the multi-strategy case. Each strategy's Kelly fraction is computed from its expected return and variance, then the portfolio weights are set proportional to the individual Kelly fractions, scaled down to a target utilization (typically 25–50% of full Kelly). This is theoretically optimal for growth but practically sensitive to estimation error in expected returns. In live trading, conservative Kelly fractions are strongly preferred over full Kelly.
For most systematic retail traders, volatility-parity is the right starting point. It is implementable with basic statistics, it adapts as strategy volatilities change, and it avoids the estimation error problems of Kelly without being as naive as equal-weight.
Portfolio-Level Kill Switches
Individual strategy kill switches pause or halt a single strategy when it hits its loss limit. Portfolio-level kill switches halt all strategies when combined losses exceed a threshold.
The typical structure has two layers:
Daily portfolio loss limit. If combined P&L across all running strategies reaches -3% (or whatever portfolio-level threshold is set), all strategies stop entering new positions. Existing positions may be managed to close or held per their exit rules, but no new entries occur until the next trading session.
Combined drawdown threshold. If the portfolio-level drawdown from its all-time high exceeds a defined percentage (typically 10–15%), all strategies are halted until a review determines whether the drawdown reflects normal variance or structural degradation.
The second layer is more difficult to implement and more important. A strategy can be within its individual drawdown limit while the portfolio is in a severe combined drawdown — because multiple strategies are all pulling back simultaneously, each within their own limits. The portfolio-level threshold catches this.
One additional rule that is underused: if any two strategies are both in their maximum individual drawdown simultaneously, halt both. Two strategies hitting their worst-case simultaneously is a strong signal that a correlated risk factor is driving losses — the exact regime where running both independently is most dangerous.
Monitoring Infrastructure
Running multiple strategies without monitoring is operating blind. The minimum viable monitoring setup for a multi-strategy account tracks:
- Daily P&L per strategy — absolute dollars and percentage of allocated capital
- Running drawdown per strategy — current peak-to-trough from each strategy's equity curve
- Combined portfolio P&L — weighted sum across all strategies
- Correlation matrix — rolling 30-day correlation between all strategy pairs
- Portfolio-level max drawdown — from the combined equity curve's all-time high
At minimum, this should be computed at end of day and stored to a file or database. In live trading, real-time P&L per strategy is essential because individual kill switches need to trigger intraday.
A secondary monitoring layer worth building is a regime detector. Trailing 20-day realized volatility on the SPY or QQQ is a reasonable proxy for market regime: volatility above a threshold (typically 25–30% annualized) signals that correlation assumptions are likely shifting. When the regime detector flags elevated market volatility, tighten portfolio-level thresholds proactively rather than waiting for the combined loss limit to trigger.
The cost of over-monitoring is minimal. The cost of under-monitoring in a correlated drawdown is an account that takes months to recover.
Python Implementation
import pandas as pd
import numpy as np
class PortfolioRiskTracker:
def __init__(self, daily_portfolio_limit: float = 0.03):
self.daily_portfolio_limit = daily_portfolio_limit
self.strategy_returns: dict = {}
self.halted = False
def record_strategy_return(self, strategy: str, pnl_pct: float):
if strategy not in self.strategy_returns:
self.strategy_returns[strategy] = []
self.strategy_returns[strategy].append(pnl_pct)
def portfolio_daily_pnl(self) -> float:
if not self.strategy_returns:
return 0.0
return sum(v[-1] for v in self.strategy_returns.values() if v) / len(self.strategy_returns)
def correlation_matrix(self) -> pd.DataFrame:
df = pd.DataFrame(self.strategy_returns)
return df.corr()
def check_halt(self) -> bool:
daily_pnl = self.portfolio_daily_pnl()
if abs(daily_pnl) >= self.daily_portfolio_limit and daily_pnl < 0:
self.halted = True
return self.halted
def max_drawdown(self) -> float:
if not self.strategy_returns:
return 0.0
portfolio_returns = pd.DataFrame(self.strategy_returns).mean(axis=1)
cumulative = (1 + portfolio_returns).cumprod()
peak = cumulative.cummax()
drawdown = (cumulative - peak) / peak
return float(drawdown.min())
def simultaneous_drawdown_strategies(self, drawdown_threshold: float = -0.05) -> list:
at_drawdown = []
for strategy, returns in self.strategy_returns.items():
if len(returns) < 2:
continue
s = pd.Series(returns)
cum = (1 + s).cumprod()
dd = (cum.iloc[-1] - cum.max()) / cum.max()
if dd <= drawdown_threshold:
at_drawdown.append(strategy)
return at_drawdown
The check_halt method enforces the daily portfolio loss limit and sets self.halted = True. Any strategy that queries this flag before entering a new trade will skip entry. The simultaneous_drawdown_strategies method returns a list of strategies currently in drawdown beyond the threshold — when two or more appear, the halt condition triggers.
To use this in a live system, call record_strategy_return at the end of each trading day (or at regular intervals intraday), then query check_halt before each strategy's signal evaluation loop.
Extend the tracker with alerting: when check_halt returns True or simultaneous_drawdown_strategies returns two or more strategies, send a notification via Telegram, email, or SMS before halting execution.
The correlation matrix output from correlation_matrix() should be reviewed weekly, not daily. Correlations shift gradually under normal conditions. A weekly review catches drift before it creates an undetected concentration. Daily review is noise. Monthly review may catch it too late.
One practical calibration note: daily_portfolio_limit of 0.03 (3%) is appropriate for a mature multi-strategy setup. For early-stage testing, set it at 1.5–2%. The more strategies are running and the more validated each is, the more you can reasonably allow in a single day. Start tighter and widen based on observed behavior, not anticipated behavior.
The Oyamori Approach
Oyamori's risk management layer operates at two levels simultaneously. Each strategy has its own position sizing rules, drawdown limits, and daily loss caps — the individual layer. The portfolio layer monitors aggregated P&L, rolling correlation, and combined drawdown across everything that is running.
The platform surfaces correlation warnings when a new strategy being added shares significant return correlation with existing active strategies. This is not a hard block — a trader may choose to run correlated strategies with reduced combined allocation — but it is a required acknowledgment. Running correlated strategies without awareness of the combined risk is the primary way multi-algo accounts fail.
Capital allocation defaults are volatility-parity at the portfolio level. Traders can override this per strategy, but the default ensures no single high-volatility strategy dominates the account's risk profile without an explicit decision.