
🚀 Your Algo Edge Just Leveled Up — Premium Plans Are Here!🚀
A year in, our Starter, Pro, and Elite Quant Plans are crushing it—members are live-trading bots and booking 1-on-1 wins. Now with annual + lifetime deals for max savings.
Every premium member gets: ✅ Full code from every article ✅ Private GitHub repos + templates ✅ 3–5 deep-dive paid articles/mo ✅ Early access + live strategy teardowns
Pick your edge:
Starter (€20/mo) → 1 paid article + public repos
Builder (€30/mo) → Full code + private repos (most popular)
Master (€50/mo) → Two 1-on-1 calls + custom bot built for you
Best deals: 📅 Annual: 2 months FREE 🔒 Lifetime: Own it forever + exclusive perks
First 50 annual/lifetime signups get a free 15-min audit. Don’t wait—the market won’t.
— AlgoEdge Insights Team

Elaborated with Python
Introduction
In quantitative finance, risk management and volatility forecasting play a crucial role in designing trading strategies. This article explores a systematic approach to take-profit decisions using the Conditional Value at Risk (CVaR) on the right tail, also known as the Expected Upside Potential (EUP), combined with a Heterogeneous Auto-Regressive (HAR) model for volatility prediction.
We will analyze an equally weighted portfolio of the “Magnificent Seven” stocks and implement a data-driven methodology to determine dynamic sell signals.
The full end-to-end workflow is available in a Google Colab notebook, exclusively for paid subscribers of my newsletter. Paid subscribers also gain access to the complete article, including the full code snippet in the Google Colab notebook, which is accessible below the paywall at the end of the article. Subscribe now to unlock these benefits!
1. Data and Portfolio Construction
We start by selecting seven major tech stocks: Apple (AAPL), Microsoft (MSFT), NVIDIA (NVDA), Amazon (AMZN), Tesla (TSLA), Meta (META), and Alphabet (GOOGL). Using Yahoo Finance, we fetch historical adjusted closing prices from January 1, 2020, to March 15, 2025 and compute their daily returns.
import numpy as np
import pandas as pd
import yfinance as yf
import statsmodels.api as sm
import matplotlib.pyplot as plt
plt.close('all')
tickers = ["AAPL", "MSFT", "NVDA", "AMZN", "TSLA", "META", "GOOGL"]
data = yf.download(tickers, start="2020-01-01", end="2025-03-15", auto_adjust=False)["Close"]
returns = data.pct_change().dropna()
# Equally weighted portfolio
weights = np.ones(len(tickers)) / len(tickers)
portfolio_returns = returns.dot(weights)
portfolio_prices = (1 + portfolio_returns).cumprod() * 100 # Base 1002. Calculating VaR (95%) and Expected Upside Potential (EUP)
To quantify the risk and potential upside, we use:
VaR (95%): The 95th percentile of rolling 60-day returns.
EUP (Right-Tail CVaR): The average return of observations exceeding the 95th percentile.
window_eup = 60
rolling_var = portfolio_returns.rolling(window=window_eup).quantile(0.95)
def eup_cvar(x, alpha=95):
threshold = np.percentile(x, alpha)
tail = x[x >= threshold]
return tail.mean() if len(tail) > 0 else np.nan
eup_series = portfolio_returns.rolling(window=window_eup).apply(lambda x: eup_cvar(x, alpha=95), raw=True)
signal = portfolio_returns > rolling_var # Take-profit trigger3. HAR Model for Volatility Prediction
The Heterogeneous Auto-Regressive (HAR) Model is useful for forecasting daily volatility based on:
Daily volatility (2-day window)
Weekly volatility (5-day window)
Monthly volatility (22-day window)
vol_daily = portfolio_returns.rolling(window=2).std()
vol_weekly = portfolio_returns.rolling(window=5).std()
vol_monthly = portfolio_returns.rolling(window=22).std()
vol_data = pd.DataFrame({
'vol_daily': vol_daily,
'vol_weekly': vol_weekly,
'vol_monthly': vol_monthly
}).dropna()
X = sm.add_constant(vol_data[['vol_daily', 'vol_weekly', 'vol_monthly']])
y = vol_data['vol_daily'].shift(-1)
data_valid = pd.concat([X, y], axis=1).dropna()
X_valid = data_valid.iloc[:, :-1]
y_valid = data_valid.iloc[:, -1]
if len(X_valid) > 0:
model = sm.OLS(y_valid, X_valid).fit()
vol_data.loc[X_valid.index, 'vol_forecast'] = model.predict(X_valid)
else:
vol_data['vol_forecast'] = np.nan4. Calculating the Sell Ratio and Sale Percentage
We compute the sell ratio as:

The ratio is mapped to a sale percentage between 0% and 100%, based on predefined thresholds:
Sell Ratio ≤ 1.0 → 0% Sale
Sell Ratio ≥ 3.0 → 100% Sale
Between 1.0 and 3.0 → Interpolated proportionally
common_index = portfolio_returns.index.intersection(vol_data['vol_forecast'].dropna().index)
eup_aligned = eup_series.loc[common_index]
signal_aligned = signal.loc[common_index]
vol_forecast_aligned = vol_data['vol_forecast'].loc[common_index]
ratio = pd.Series(np.nan, index=common_index)
for date in common_index:
if signal_aligned.loc[date]:
if not pd.isna(eup_aligned.loc[date]) and not pd.isna(vol_forecast_aligned.loc[date]):
ratio.loc[date] = eup_aligned.loc[date] / vol_forecast_aligned.loc[date]
def sale_percentage(r, threshold_min=1.0, threshold_max=3.0):
if r <= threshold_min:
return 0.0
elif r >= threshold_max:
return 1.0
else:
return (r - threshold_min) / (threshold_max - threshold_min)
sales_percentage = ratio.dropna().apply(sale_percentage)5. Printing and Visualizing Sell Signals
print("Last 10 Sell Ratios (EUP / Volatility Forecast):")
print(ratio.dropna().tail(10))
print("\nLast 10 Sale Percentages:")
print(sales_percentage.tail(10))We plot the portfolio price evolution, highlighting sell signals with red markers:
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(portfolio_prices.index, portfolio_prices, label="Portfolio Price", color="blue")
sales_dates = sales_percentage.index
if not sales_dates.empty:
ax.scatter(sales_dates, portfolio_prices.loc[sales_dates],
color="red", marker="v", s=100, label="Sell Signal")
for date in sales_dates:
perc = sales_percentage.loc[date] * 100
ax.annotate(f"{perc:.0f}%", (date, portfolio_prices.loc[date]),
textcoords="offset points", xytext=(0,10), ha="center", color="red")
ax.set_title("Sell Signals Based on EUP (Right-Tail CVaR) and HAR Volatility Model")
ax.set_xlabel("Date")
ax.set_ylabel("Portfolio Price (Base 100)")
ax.legend()
ax.grid(True)
plt.show()Conclusion
This approach integrates EUP-based take-profit signals with a HAR volatility model to adaptively determine optimal sell percentages. Unlike fixed thresholds, this data-driven strategy adjusts dynamically to market conditions, offering a more systematic way to take profits based on expected upside potential and forecasted risk.
Subscribe to our premium content to read the rest.
Become a paying subscriber to get access to this post and other subscriber-only content.
Upgrade
