xiaohongshu
xiaohongshu
financial-time-series
Use when working with price data, trading signals, or implementing momentum strategies. Covers returns calculation, volatility targeting, momentum factors, MACD indicators, time-series momentum (TSMOM), portfolio construction, futures contracts, and risk-adjusted returns for trend-following strat...
Full skill instructions
Comprehensive guide for processing financial time-series data and implementing trend-following strategies, based on the X-Trend model and Deep Momentum Networks framework.
Activate this skill when:
Returns linearly de-trend the price series:
def calculate_returns(prices, lookback=1):
"""
Calculate returns over specified lookback period.
Args:
prices: Array of daily close prices p[t]
lookback: Number of days (t') for return calculation
Returns:
returns: r[t-t', t] = (p[t] - p[t-t']) / p[t-t']
"""
return (prices - prices.shift(lookback)) / prices.shift(lookback)
Key Points:
Normalize positions by ex-ante volatility to ensure equal risk contribution:
def volatility_targeting(position, realized_vol, target_vol=0.15):
"""
Scale position by volatility targeting leverage factor.
Args:
position: Raw trading signal z[t] in [-1, 1]
realized_vol: Ex-ante volatility σ[t] (60-day EWMA)
target_vol: Annual target volatility σ_tgt (typically 15%)
Returns:
scaled_position: Volatility-adjusted position
"""
leverage = target_vol / realized_vol
return position * leverage
Implementation:
Classic momentum signal based on historical returns:
def tsmom_signal(returns_252):
"""
Simple 1-year momentum signal.
Args:
returns_252: 252-day (1-year) returns
Returns:
signal: +1 (long) or -1 (short)
"""
return np.sign(returns_252)
Combine signals at different timescales:
def multi_scale_momentum(prices):
"""
Weighted combination of momentum at multiple timescales.
Timescales:
- 21 days (1-month)
- 63 days (3-month)
- 126 days (6-month)
- 252 days (12-month)
"""
timescales = [21, 63, 126, 252]
weights = [0.25, 0.25, 0.25, 0.25] # Equal weighting
signals = []
for t in timescales:
ret = calculate_returns(prices, lookback=t)
signals.append(np.sign(ret))
return np.average(signals, weights=weights)
Compare exponentially weighted signals at two timescales:
def macd_factor(prices, short=8, long=24, lookback_std=252):
"""
Calculate MACD momentum indicator.
MACD = (EWMA_short - EWMA_long) / std(prices_60)
Normalized by std of past year returns
Common timescale pairs: (8,24), (16,28), (32,96)
Returns:
macd: Normalized MACD signal
> 0 indicates buy, < 0 indicates sell
Magnitude indicates conviction
"""
ewma_short = prices.ewm(span=short).mean()
ewma_long = prices.ewm(span=long).mean()
price_std = prices.ewm(span=60).std()
m = (ewma_short - ewma_long) / price_std
m_std = m.rolling(lookback_std).std()
return m / m_std
MACD to Position Conversion:
def macd_to_position(macd_signal):
"""Convert MACD signal to position using response function."""
return macd_signal * np.exp(-macd_signal**2 / 4) / 0.89
Normalized returns at multiple timescales for neural network inputs:
def normalized_returns(prices, volatility, timescales=[1, 21, 63, 126, 252]):
"""
Calculate volatility-normalized returns for deep learning models.
r_hat[t-t', t] = r[t-t', t] / (σ[t] * sqrt(t'))
This normalization ensures returns are comparable across timescales.
"""
factors = []
for t in timescales:
ret = calculate_returns(prices, lookback=t)
r_normalized = ret / (volatility * np.sqrt(t))
factors.append(r_normalized)
return np.column_stack(factors)
Full Feature Vector:
def create_feature_vector(prices):
"""
Create input features x[t] for deep momentum models.
Includes:
- Normalized returns at multiple timescales
- MACD indicators at multiple (S, L) pairs
"""
volatility = prices.pct_change().ewm(span=60).std()
# Normalized returns
norm_returns = normalized_returns(prices, volatility)
# MACD features
macd_features = [
macd_factor(prices, 8, 24),
macd_factor(prices, 16, 28),
macd_factor(prices, 32, 96)
]
return np.concatenate([norm_returns, macd_features])
Calculate portfolio returns with volatility targeting and transaction costs:
def portfolio_returns(positions, returns, volatility, target_vol=0.15,
transaction_costs=0.0):
"""
Calculate portfolio returns with volatility targeting.
R_portfolio[t+1] = (1/N) * Σ R[i, t+1]
where for each asset i:
R[i,t+1] = z[i,t] * (σ_tgt/σ[i,t]) * r[i,t+1]
- C[i] * σ_tgt * |z[i,t]/σ[i,t] - z[i,t-1]/σ[i,t-1]|
Args:
positions: z[i,t] for each asset (N × T)
returns: r[i,t+1] for each asset
volatility: σ[i,t] for each asset
target_vol: Annual target volatility σ_tgt
transaction_costs: C[i] per asset
Returns:
portfolio_returns: R_portfolio[t+1]
IMPORTANT: Transaction cost calculation uses position_changes which is
already scaled by (target_vol / volatility), so we DON'T multiply by
target_vol again. The formula is C * |scaled_pos[t] - scaled_pos[t-1]|,
where scaled_pos = z * (σ_tgt/σ). This gives C * σ_tgt * |z/σ - z_prev/σ_prev|
as per the paper's Eq. (2).
"""
N = len(positions)
# Scale by volatility targeting: scaled_pos = z * (σ_tgt/σ)
scaled_positions = positions * (target_vol / volatility)
# Asset returns
asset_returns = scaled_positions * returns
# Transaction costs
# position_changes is already in units of σ_tgt * |z/σ - z_prev/σ_prev|
# So we only multiply by transaction_costs C, NOT by target_vol again
position_changes = np.abs(
scaled_positions - scaled_positions.shift(1)
)
costs = transaction_costs * position_changes
# Net returns per asset
net_returns = asset_returns - costs
# Equal-weighted portfolio
return net_returns.mean(axis=0)
Primary metric for strategy evaluation:
def sharpe_ratio(returns, periods_per_year=252):
"""
Calculate annualized Sharpe ratio.
Sharpe = sqrt(252) * mean(returns) / std(returns)
Measures returns per unit volatility.
"""
return np.sqrt(periods_per_year) * returns.mean() / returns.std()
Differentiable loss function for direct Sharpe optimization:
def sharpe_loss(positions, returns, volatility, target_vol=0.15):
"""
Negative Sharpe ratio loss for gradient descent.
L_Sharpe = -sqrt(252) * mean_batch(R[t+1]) / std_batch(R[t+1])
where R[t+1] = (σ_tgt/σ[t]) * r[t+1] * position[t]
This is the loss function used in Deep Momentum Networks.
"""
scaled_returns = (target_vol / volatility) * returns * positions
mean_ret = scaled_returns.mean()
std_ret = scaled_returns.std()
return -np.sqrt(252) * mean_ret / std_ret
def create_continuous_contract(contracts, method='ratio_adjusted'):
"""
Chain futures contracts into continuous series.
Methods:
- 'ratio_adjusted' (backwards): Multiply historical prices by ratio
- 'difference_adjusted': Add price differences
Ratio-adjusted method:
- Preserves percentage returns
- Preferred for momentum strategies
- Used in Pinnacle Data CLC Database
"""
if method == 'ratio_adjusted':
# When rolling from contract C1 to C2:
# Adjustment_ratio = P_C1(roll_date) / P_C2(roll_date)
# Apply ratio to all historical prices before roll_date
pass # Implementation details
return continuous_prices
def calculate_metrics(returns):
"""
Calculate comprehensive performance metrics.
Returns:
metrics: Dict with Sharpe, returns, volatility, drawdown
"""
cumulative_returns = (1 + returns).cumprod()
running_max = cumulative_returns.expanding().max()
drawdown = (cumulative_returns - running_max) / running_max
return {
'sharpe': sharpe_ratio(returns),
'annual_return': returns.mean() * 252,
'annual_volatility': returns.std() * np.sqrt(252),
'max_drawdown': drawdown.min(),
'cumulative_return': cumulative_returns.iloc[-1] - 1
}
def tsmom_strategy(prices, target_vol=0.15):
"""Implement basic time-series momentum strategy."""
# 1. Calculate 1-year returns
returns_252 = calculate_returns(prices, lookback=252)
# 2. Generate signal
signal = np.sign(returns_252)
# 3. Calculate realized volatility (60-day EWMA)
realized_vol = prices.pct_change().ewm(span=60).std()
# 4. Apply volatility targeting
position = volatility_targeting(signal, realized_vol, target_vol)
# 5. Calculate returns
next_day_returns = prices.pct_change().shift(-1)
strategy_returns = position * next_day_returns * (target_vol / realized_vol)
return strategy_returns
def multi_asset_portfolio(asset_prices_dict, target_vol=0.15):
"""
Construct equal-risk portfolio across multiple assets.
Args:
asset_prices_dict: {'ASSET1': prices1, 'ASSET2': prices2, ...}
"""
asset_returns = {}
for asset, prices in asset_prices_dict.items():
# Generate signal for each asset
signal = tsmom_signal(calculate_returns(prices, 252))
volatility = prices.pct_change().ewm(span=60).std()
position = volatility_targeting(signal, volatility, target_vol)
# Calculate asset returns
next_ret = prices.pct_change().shift(-1)
asset_returns[asset] = position * next_ret * (target_vol / volatility)
# Equal-weighted portfolio
portfolio = pd.DataFrame(asset_returns).mean(axis=1)
return portfolio
✅ Always use volatility targeting for risk normalization ✅ Calculate ex-ante volatility using 60-day EWMA of returns ✅ Use backward ratio-adjusted continuous futures for consistent returns ✅ Test on out-of-sample data with expanding window approach ✅ Monitor drawdowns especially during regime changes ✅ Use multiple timescales to balance trend capture vs. responsiveness
❌ Don't assume Gaussian returns - especially in tails ❌ Don't ignore transaction costs - they compound over time ❌ Don't overfit to training period - financial markets are non-stationary ❌ Don't use look-ahead data - ensure causality in backtests ❌ Don't neglect correlation in tail events across assets
| Concept | Formula | Notes |
|---|---|---|
| Returns | r[t-t',t] = (p[t] - p[t-t']) / p[t-t'] | Simple returns over t' days |
| Normalized Returns | r_hat[t-t',t] = r[t-t',t] / (σ[t] * sqrt(t')) | For neural network inputs |
| Volatility Targeting | leverage = σ_tgt / σ[t] | Ex-ante vol σ[t] from 60-day EWMA |
| TSMOM Signal | z[t] = sign(r[t-252,t]) | +1 for uptrend, -1 for downtrend |
| MACD | (EWMA_S - EWMA_L) / std(m[-252:]) | Compare short/long EWMAs |
| Portfolio Return | R_port = (1/N) * Σ R[i,t+1] | Equal-weighted across N assets |
| Sharpe Ratio | sqrt(252) * mean(R) / std(R) | Annualized risk-adjusted returns |
Last Updated: Based on X-Trend paper (March 2024) Skill Type: Domain Knowledge Line Count: ~490 (under 500-line rule ✅)
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience