Skip to content

Instantly share code, notes, and snippets.

View quantra-go-algo's full-sized avatar

Algorithmic Trading quantra-go-algo

View GitHub Profile
@quantra-go-algo
quantra-go-algo / step_9_results_and_performance_metrics_2.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 9: Results and Performance Metrics (snippet 2)
# Plot all three curves
plt.figure(figsize=(12, 5))
plt.plot(eq_agent_oos.index, eq_agent_oos.values,
label='Agent-only (LLM policy)')
plt.plot(eq_guard_oos.index, eq_guard_oos.values,
label='Agent + Guardrails')
plt.plot(eq_bh_oos.index, eq_bh_oos.values,
label='Buy & Hold AAPL', linestyle='--', color='gray')
plt.title(f'{SYMBOL}: OOS equity curves (from {OOS_START})')
plt.xlabel('Date'); plt.ylabel('Equity (rebased to 1.0)')
@quantra-go-algo
quantra-go-algo / step_9_results_and_performance_metrics_1.py
Last active June 24, 2026 01:45
guardrailed-llm-agent — Step 9: Results and Performance Metrics (snippet 1)
mt = metrics_table({
'Agent-only': eq_agent_oos,
'Agent + Guardrails': eq_guard_oos,
'Buy & Hold AAPL': eq_bh_oos,
})
# Expected output (approximate: depends on your LLM's policy calls):
#
# Sharpe CAGR Ann.Vol MaxDD
# Agent-only 1.066 19.83% 18.60% -23.58%
@quantra-go-algo
quantra-go-algo / step_8_the_walk_forward_loop_keeping_it__2.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 8: The Walk-Forward Loop: Keeping It Honest (snippet 2)
# One continuous agent position series across the whole OOS window
agent_parts = []
params_by_day = {}
for idx, policy, guard in month_blocks:
seg = feat_all.loc[idx]
agent_parts.append(build_agent_positions(
seg, policy,
state_lag = state_lag_full.loc[idx], # cross-month continuity
vol_lag = vol_lag_full.loc[idx],
))
@quantra-go-algo
quantra-go-algo / step_8_the_walk_forward_loop_keeping_it__1.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 8: The Walk-Forward Loop: Keeping It Honest (snippet 1)
def run_walk_forward_oos(feat_all):
oos_start = pd.to_datetime(OOS_START)
months = month_starts(feat_all.index, oos_start)
cache = load_cache(POLICY_CACHE_FILE)
# Compute lags over FULL history so month boundaries never force flat.
# state_lag[t] = state at close of t-1, available before t opens.
state_lag_full = feat_all['state'].shift(1)
vol_lag_full = feat_all['vol'].shift(1)
@quantra-go-algo
quantra-go-algo / step_7_hard_guardrails_when_the_llm_isn__2.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 7: Hard Guardrails: When the LLM Isn't Enough (snippet 2)
# A4: re-optimize guardrails every month (OPT_FREQ_MONTHS=1)
if best_guard is None or ((m.month - 1) % OPT_FREQ_MONTHS == 0):
best_guard = optimize_guardrails(train, policy)
print('Re-opt guardrails @', m.date(), '->', best_guard)
@quantra-go-algo
quantra-go-algo / step_7_hard_guardrails_when_the_llm_isn__1.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 7: Hard Guardrails: When the LLM Isn't Enough (snippet 1)
flat_days = 0 # counts consecutive days at zero exposure
for t in df_seg.index:
dd = equity / peak - 1.0
target = float(proposed_pos.loc[t])
if cooldown > 0:
target = 0.0
cooldown -= 1
else:
@quantra-go-algo
quantra-go-algo / step_6_from_policy_to_position_sizing_wi_4.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 6: From Policy to Position: Sizing with Volatility Targeting (snippet 4)
def build_agent_positions(df_seg, policy, state_lag=None, vol_lag=None, mom_lag=None):
if state_lag is None: state_lag = df_seg['state'].shift(1)
if vol_lag is None: vol_lag = df_seg['vol'].shift(1)
pos = pd.Series(0.0, index=df_seg.index)
for t in df_seg.index:
s = state_lag.loc[t]
if pd.isna(s): continue
rec = policy.get(s, {'action': 'LONG', 'size': 0.5})
base = action_to_base_exposure(rec['action'], rec['size'])
@quantra-go-algo
quantra-go-algo / step_6_from_policy_to_position_sizing_wi_3.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 6: From Policy to Position: Sizing with Volatility Targeting (snippet 3)
def mom_tilt(base, m):
if pd.isna(m): return base
tilt = 1.15 if float(m) >= 0 else 0.85
return base * tilt
@quantra-go-algo
quantra-go-algo / step_6_from_policy_to_position_sizing_wi_2.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 6: From Policy to Position: Sizing with Volatility Targeting (snippet 2)
def vol_scale(base_exposure, realized_vol):
# Scale toward TARGET_VOL=0.25 using yesterday's realized vol.
# Yesterday's vol avoids lookahead: we only know today's vol at close.
if not USE_VOL_TARGET or base_exposure == 0.0:
return base_exposure
if pd.isna(realized_vol) or realized_vol <= 0:
return base_exposure
return base_exposure * min(TARGET_VOL / realized_vol, MAX_LEVERAGE)
@quantra-go-algo
quantra-go-algo / step_6_from_policy_to_position_sizing_wi_1.py
Created June 24, 2026 01:29
guardrailed-llm-agent — Step 6: From Policy to Position: Sizing with Volatility Targeting (snippet 1)
def action_to_base_exposure(action, size):
# Maps LLM output to a base exposure in [0.5, 1.0]. No shorts.
if action == 'LONG':
return LONG_FULL_EXP if size >= 1.0 else LONG_HALF_EXP # 1.0 or 0.8
return FLAT_EXP # 0.5: never fully exit