@zimezone/z-command 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +57 -38
  2. package/dist/cli.js +14 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts +1 -7
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +101 -23
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.d.ts +11 -0
  9. package/dist/commands/update.d.ts.map +1 -0
  10. package/dist/commands/update.js +88 -0
  11. package/dist/commands/update.js.map +1 -0
  12. package/dist/platforms.d.ts +21 -0
  13. package/dist/platforms.d.ts.map +1 -0
  14. package/dist/platforms.js +137 -0
  15. package/dist/platforms.js.map +1 -0
  16. package/dist/types.d.ts +44 -0
  17. package/dist/types.d.ts.map +1 -0
  18. package/dist/types.js +6 -0
  19. package/dist/types.js.map +1 -0
  20. package/package.json +13 -5
  21. package/templates/agents/api-documenter.agent.md +161 -0
  22. package/templates/agents/architect-review.agent.md +146 -0
  23. package/templates/agents/arm-cortex-expert.agent.md +288 -0
  24. package/templates/agents/backend-architect.agent.md +309 -0
  25. package/templates/agents/backend-security-coder.agent.md +152 -0
  26. package/templates/agents/bash-pro.agent.md +285 -0
  27. package/templates/agents/c-pro.agent.md +35 -0
  28. package/templates/agents/c4-code.agent.md +320 -0
  29. package/templates/agents/c4-component.agent.md +227 -0
  30. package/templates/agents/c4-container.agent.md +248 -0
  31. package/templates/agents/c4-context.agent.md +235 -0
  32. package/templates/agents/conductor-validator.agent.md +245 -0
  33. package/templates/agents/csharp-pro.agent.md +38 -0
  34. package/templates/agents/customer-support.agent.md +148 -0
  35. package/templates/agents/database-admin.agent.md +142 -0
  36. package/templates/agents/database-architect.agent.md +238 -0
  37. package/templates/agents/database-optimizer.agent.md +144 -0
  38. package/templates/agents/debugger.agent.md +30 -0
  39. package/templates/agents/deployment-engineer.agent.md +0 -0
  40. package/templates/agents/devops-troubleshooter.agent.md +138 -0
  41. package/templates/agents/django-pro.agent.md +159 -0
  42. package/templates/agents/docs-architect.agent.md +77 -0
  43. package/templates/agents/dotnet-architect.agent.md +175 -0
  44. package/templates/agents/dx-optimizer.agent.md +63 -0
  45. package/templates/agents/elixir-pro.agent.md +38 -0
  46. package/templates/agents/error-detective.agent.md +32 -0
  47. package/templates/agents/event-sourcing-architect.agent.md +42 -0
  48. package/templates/agents/fastapi-pro.agent.md +171 -0
  49. package/templates/agents/firmware-analyst.agent.md +330 -0
  50. package/templates/agents/frontend-security-coder.agent.md +149 -0
  51. package/templates/agents/haskell-pro.agent.md +37 -0
  52. package/templates/agents/hr-pro.agent.md +105 -0
  53. package/templates/agents/incident-responder.agent.md +190 -0
  54. package/templates/agents/ios-developer.agent.md +198 -0
  55. package/templates/agents/java-pro.agent.md +156 -0
  56. package/templates/agents/javascript-pro.agent.md +35 -0
  57. package/templates/agents/julia-pro.agent.md +187 -0
  58. package/templates/agents/legal-advisor.agent.md +49 -0
  59. package/templates/agents/malware-analyst.agent.md +272 -0
  60. package/templates/agents/mermaid-expert.agent.md +39 -0
  61. package/templates/agents/minecraft-bukkit-pro.agent.md +104 -0
  62. package/templates/agents/mobile-security-coder.agent.md +163 -0
  63. package/templates/agents/monorepo-architect.agent.md +44 -0
  64. package/templates/agents/observability-engineer.agent.md +228 -0
  65. package/templates/agents/performance-engineer.agent.md +167 -0
  66. package/templates/agents/php-pro.agent.md +43 -0
  67. package/templates/agents/posix-shell-pro.agent.md +284 -0
  68. package/templates/agents/quant-analyst.agent.md +32 -0
  69. package/templates/agents/reference-builder.agent.md +167 -0
  70. package/templates/agents/reverse-engineer.agent.md +202 -0
  71. package/templates/agents/risk-manager.agent.md +41 -0
  72. package/templates/agents/ruby-pro.agent.md +35 -0
  73. package/templates/agents/rust-pro.agent.md +156 -0
  74. package/templates/agents/sales-automator.agent.md +35 -0
  75. package/templates/agents/scala-pro.agent.md +60 -0
  76. package/templates/agents/search-specialist.agent.md +59 -0
  77. package/templates/agents/security-auditor.agent.md +138 -0
  78. package/templates/agents/seo-authority-builder.agent.md +116 -0
  79. package/templates/agents/seo-cannibalization-detector.agent.md +103 -0
  80. package/templates/agents/seo-content-auditor.agent.md +63 -0
  81. package/templates/agents/seo-content-planner.agent.md +88 -0
  82. package/templates/agents/seo-content-refresher.agent.md +98 -0
  83. package/templates/agents/seo-content-writer.agent.md +76 -0
  84. package/templates/agents/seo-keyword-strategist.agent.md +75 -0
  85. package/templates/agents/seo-meta-optimizer.agent.md +72 -0
  86. package/templates/agents/seo-snippet-hunter.agent.md +94 -0
  87. package/templates/agents/seo-structure-architect.agent.md +88 -0
  88. package/templates/agents/service-mesh-expert.agent.md +41 -0
  89. package/templates/agents/sql-pro.agent.md +146 -0
  90. package/templates/agents/tdd-orchestrator.agent.md +183 -0
  91. package/templates/agents/temporal-python-pro.agent.md +349 -0
  92. package/templates/agents/terraform-specialist.agent.md +137 -0
  93. package/templates/agents/test-automator.agent.md +203 -0
  94. package/templates/agents/threat-modeling-expert.agent.md +44 -0
  95. package/templates/agents/tutorial-engineer.agent.md +118 -0
  96. package/templates/agents/ui-ux-designer.agent.md +188 -0
  97. package/templates/agents/ui-visual-validator.agent.md +192 -0
  98. package/templates/agents/vector-database-engineer.agent.md +43 -0
  99. package/templates/skills/angular-migration/SKILL.md +410 -0
  100. package/templates/skills/api-design-principles/SKILL.md +528 -0
  101. package/templates/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  102. package/templates/skills/api-design-principles/assets/rest-api-template.py +182 -0
  103. package/templates/skills/api-design-principles/references/graphql-schema-design.md +583 -0
  104. package/templates/skills/api-design-principles/references/rest-best-practices.md +408 -0
  105. package/templates/skills/architecture-decision-records/SKILL.md +428 -0
  106. package/templates/skills/architecture-patterns/SKILL.md +494 -0
  107. package/templates/skills/async-python-patterns/SKILL.md +694 -0
  108. package/templates/skills/auth-implementation-patterns/SKILL.md +634 -0
  109. package/templates/skills/changelog-automation/SKILL.md +552 -0
  110. package/templates/skills/code-review-excellence/SKILL.md +520 -0
  111. package/templates/skills/competitive-landscape/SKILL.md +479 -0
  112. package/templates/skills/context-driven-development/SKILL.md +385 -0
  113. package/templates/skills/cost-optimization/SKILL.md +274 -0
  114. package/templates/skills/cqrs-implementation/SKILL.md +554 -0
  115. package/templates/skills/data-quality-frameworks/SKILL.md +587 -0
  116. package/templates/skills/data-storytelling/SKILL.md +453 -0
  117. package/templates/skills/database-migration/SKILL.md +424 -0
  118. package/templates/skills/dbt-transformation-patterns/SKILL.md +561 -0
  119. package/templates/skills/debugging-strategies/SKILL.md +527 -0
  120. package/templates/skills/defi-protocol-templates/SKILL.md +454 -0
  121. package/templates/skills/dependency-upgrade/SKILL.md +409 -0
  122. package/templates/skills/deployment-pipeline-design/SKILL.md +359 -0
  123. package/templates/skills/distributed-tracing/SKILL.md +438 -0
  124. package/templates/skills/dotnet-backend-patterns/SKILL.md +815 -0
  125. package/templates/skills/dotnet-backend-patterns/assets/repository-template.cs +523 -0
  126. package/templates/skills/dotnet-backend-patterns/assets/service-template.cs +336 -0
  127. package/templates/skills/dotnet-backend-patterns/references/dapper-patterns.md +544 -0
  128. package/templates/skills/dotnet-backend-patterns/references/ef-core-best-practices.md +355 -0
  129. package/templates/skills/e2e-testing-patterns/SKILL.md +547 -0
  130. package/templates/skills/employment-contract-templates/SKILL.md +507 -0
  131. package/templates/skills/error-handling-patterns/SKILL.md +636 -0
  132. package/templates/skills/event-store-design/SKILL.md +437 -0
  133. package/templates/skills/fastapi-templates/SKILL.md +567 -0
  134. package/templates/skills/git-advanced-workflows/SKILL.md +400 -0
  135. package/templates/skills/github-actions-templates/SKILL.md +333 -0
  136. package/templates/skills/go-concurrency-patterns/SKILL.md +655 -0
  137. package/templates/skills/grafana-dashboards/SKILL.md +369 -0
  138. package/templates/skills/helm-chart-scaffolding/SKILL.md +544 -0
  139. package/templates/skills/helm-chart-scaffolding/assets/Chart.yaml.template +42 -0
  140. package/templates/skills/helm-chart-scaffolding/assets/values.yaml.template +185 -0
  141. package/templates/skills/helm-chart-scaffolding/references/chart-structure.md +500 -0
  142. package/templates/skills/helm-chart-scaffolding/scripts/validate-chart.sh +244 -0
  143. package/templates/skills/javascript-testing-patterns/SKILL.md +1025 -0
  144. package/templates/skills/langchain-architecture/SKILL.md +338 -0
  145. package/templates/skills/llm-evaluation/SKILL.md +471 -0
  146. package/templates/skills/microservices-patterns/SKILL.md +595 -0
  147. package/templates/skills/modern-javascript-patterns/SKILL.md +911 -0
  148. package/templates/skills/monorepo-management/SKILL.md +622 -0
  149. package/templates/skills/nextjs-app-router-patterns/SKILL.md +544 -0
  150. package/templates/skills/nodejs-backend-patterns/SKILL.md +1020 -0
  151. package/templates/skills/nx-workspace-patterns/SKILL.md +452 -0
  152. package/templates/skills/openapi-spec-generation/SKILL.md +1028 -0
  153. package/templates/skills/paypal-integration/SKILL.md +467 -0
  154. package/templates/skills/pci-compliance/SKILL.md +466 -0
  155. package/templates/skills/postgresql/SKILL.md +204 -0
  156. package/templates/skills/projection-patterns/SKILL.md +490 -0
  157. package/templates/skills/prometheus-configuration/SKILL.md +392 -0
  158. package/templates/skills/prompt-engineering-patterns/SKILL.md +201 -0
  159. package/templates/skills/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
  160. package/templates/skills/prompt-engineering-patterns/assets/prompt-template-library.md +246 -0
  161. package/templates/skills/prompt-engineering-patterns/references/chain-of-thought.md +399 -0
  162. package/templates/skills/prompt-engineering-patterns/references/few-shot-learning.md +369 -0
  163. package/templates/skills/prompt-engineering-patterns/references/prompt-optimization.md +414 -0
  164. package/templates/skills/prompt-engineering-patterns/references/prompt-templates.md +470 -0
  165. package/templates/skills/prompt-engineering-patterns/references/system-prompts.md +189 -0
  166. package/templates/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
  167. package/templates/skills/python-packaging/SKILL.md +870 -0
  168. package/templates/skills/python-performance-optimization/SKILL.md +869 -0
  169. package/templates/skills/python-testing-patterns/SKILL.md +907 -0
  170. package/templates/skills/rag-implementation/SKILL.md +403 -0
  171. package/templates/skills/react-modernization/SKILL.md +513 -0
  172. package/templates/skills/react-native-architecture/SKILL.md +671 -0
  173. package/templates/skills/react-state-management/SKILL.md +429 -0
  174. package/templates/skills/risk-metrics-calculation/SKILL.md +555 -0
  175. package/templates/skills/rust-async-patterns/SKILL.md +517 -0
  176. package/templates/skills/secrets-management/SKILL.md +346 -0
  177. package/templates/skills/security-requirement-extraction/SKILL.md +677 -0
  178. package/templates/skills/shellcheck-configuration/SKILL.md +454 -0
  179. package/templates/skills/similarity-search-patterns/SKILL.md +558 -0
  180. package/templates/skills/slo-implementation/SKILL.md +329 -0
  181. package/templates/skills/sql-optimization-patterns/SKILL.md +493 -0
  182. package/templates/skills/stripe-integration/SKILL.md +442 -0
  183. package/templates/skills/tailwind-design-system/SKILL.md +666 -0
  184. package/templates/skills/temporal-python-testing/SKILL.md +158 -0
  185. package/templates/skills/temporal-python-testing/resources/integration-testing.md +455 -0
  186. package/templates/skills/temporal-python-testing/resources/local-setup.md +553 -0
  187. package/templates/skills/temporal-python-testing/resources/replay-testing.md +462 -0
  188. package/templates/skills/temporal-python-testing/resources/unit-testing.md +328 -0
  189. package/templates/skills/terraform-module-library/SKILL.md +249 -0
  190. package/templates/skills/terraform-module-library/references/aws-modules.md +63 -0
  191. package/templates/skills/threat-mitigation-mapping/SKILL.md +745 -0
  192. package/templates/skills/track-management/SKILL.md +593 -0
  193. package/templates/skills/typescript-advanced-types/SKILL.md +717 -0
  194. package/templates/skills/ui-ux-pro-max/SKILL.md +352 -0
  195. package/templates/skills/ui-ux-pro-max/data/charts.csv +26 -0
  196. package/templates/skills/ui-ux-pro-max/data/colors.csv +97 -0
  197. package/templates/skills/ui-ux-pro-max/data/icons.csv +101 -0
  198. package/templates/skills/ui-ux-pro-max/data/landing.csv +31 -0
  199. package/templates/skills/ui-ux-pro-max/data/products.csv +97 -0
  200. package/templates/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  201. package/templates/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  202. package/templates/skills/ui-ux-pro-max/data/styles.csv +59 -0
  203. package/templates/skills/ui-ux-pro-max/data/typography.csv +58 -0
  204. package/templates/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  205. package/templates/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  206. package/templates/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  207. package/templates/skills/ui-ux-pro-max/scripts/core.py +258 -0
  208. package/templates/skills/ui-ux-pro-max/scripts/design_system.py +547 -0
  209. package/templates/skills/ui-ux-pro-max/scripts/search.py +76 -0
  210. package/templates/skills/uv-package-manager/SKILL.md +831 -0
  211. package/templates/skills/vector-index-tuning/SKILL.md +521 -0
  212. package/templates/skills/wcag-audit-patterns/SKILL.md +555 -0
  213. package/templates/skills/workflow-orchestration-patterns/SKILL.md +316 -0
  214. package/templates/skills/workflow-patterns/SKILL.md +623 -0
  215. package/templates/agents/game-developer.agent.md +0 -57
  216. package/templates/agents/kubernetes-specialist.agent.md +0 -56
  217. package/templates/agents/market-researcher.agent.md +0 -47
@@ -0,0 +1,555 @@
1
+ ---
2
+ name: risk-metrics-calculation
3
+ description: Calculate portfolio risk metrics including VaR, CVaR, Sharpe, Sortino, and drawdown analysis. Use when measuring portfolio risk, implementing risk limits, or building risk monitoring systems.
4
+ ---
5
+
6
+ # Risk Metrics Calculation
7
+
8
+ Comprehensive risk measurement toolkit for portfolio management, including Value at Risk, Expected Shortfall, and drawdown analysis.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Measuring portfolio risk
13
+ - Implementing risk limits
14
+ - Building risk dashboards
15
+ - Calculating risk-adjusted returns
16
+ - Setting position sizes
17
+ - Regulatory reporting
18
+
19
+ ## Core Concepts
20
+
21
+ ### 1. Risk Metric Categories
22
+
23
+ | Category | Metrics | Use Case |
24
+ |----------|---------|----------|
25
+ | **Volatility** | Std Dev, Beta | General risk |
26
+ | **Tail Risk** | VaR, CVaR | Extreme losses |
27
+ | **Drawdown** | Max DD, Calmar | Capital preservation |
28
+ | **Risk-Adjusted** | Sharpe, Sortino | Performance |
29
+
30
+ ### 2. Time Horizons
31
+
32
+ ```
33
+ Intraday: Minute/hourly VaR for day traders
34
+ Daily: Standard risk reporting
35
+ Weekly: Rebalancing decisions
36
+ Monthly: Performance attribution
37
+ Annual: Strategic allocation
38
+ ```
39
+
40
+ ## Implementation
41
+
42
+ ### Pattern 1: Core Risk Metrics
43
+
44
+ ```python
45
+ import numpy as np
46
+ import pandas as pd
47
+ from scipy import stats
48
+ from typing import Dict, Optional, Tuple
49
+
50
+ class RiskMetrics:
51
+ """Core risk metric calculations."""
52
+
53
+ def __init__(self, returns: pd.Series, rf_rate: float = 0.02):
54
+ """
55
+ Args:
56
+ returns: Series of periodic returns
57
+ rf_rate: Annual risk-free rate
58
+ """
59
+ self.returns = returns
60
+ self.rf_rate = rf_rate
61
+ self.ann_factor = 252 # Trading days per year
62
+
63
+ # Volatility Metrics
64
+ def volatility(self, annualized: bool = True) -> float:
65
+ """Standard deviation of returns."""
66
+ vol = self.returns.std()
67
+ if annualized:
68
+ vol *= np.sqrt(self.ann_factor)
69
+ return vol
70
+
71
+ def downside_deviation(self, threshold: float = 0, annualized: bool = True) -> float:
72
+ """Standard deviation of returns below threshold."""
73
+ downside = self.returns[self.returns < threshold]
74
+ if len(downside) == 0:
75
+ return 0.0
76
+ dd = downside.std()
77
+ if annualized:
78
+ dd *= np.sqrt(self.ann_factor)
79
+ return dd
80
+
81
+ def beta(self, market_returns: pd.Series) -> float:
82
+ """Beta relative to market."""
83
+ aligned = pd.concat([self.returns, market_returns], axis=1).dropna()
84
+ if len(aligned) < 2:
85
+ return np.nan
86
+ cov = np.cov(aligned.iloc[:, 0], aligned.iloc[:, 1])
87
+ return cov[0, 1] / cov[1, 1] if cov[1, 1] != 0 else 0
88
+
89
+ # Value at Risk
90
+ def var_historical(self, confidence: float = 0.95) -> float:
91
+ """Historical VaR at confidence level."""
92
+ return -np.percentile(self.returns, (1 - confidence) * 100)
93
+
94
+ def var_parametric(self, confidence: float = 0.95) -> float:
95
+ """Parametric VaR assuming normal distribution."""
96
+ z_score = stats.norm.ppf(confidence)
97
+ return self.returns.mean() - z_score * self.returns.std()
98
+
99
+ def var_cornish_fisher(self, confidence: float = 0.95) -> float:
100
+ """VaR with Cornish-Fisher expansion for non-normality."""
101
+ z = stats.norm.ppf(confidence)
102
+ s = stats.skew(self.returns) # Skewness
103
+ k = stats.kurtosis(self.returns) # Excess kurtosis
104
+
105
+ # Cornish-Fisher expansion
106
+ z_cf = (z + (z**2 - 1) * s / 6 +
107
+ (z**3 - 3*z) * k / 24 -
108
+ (2*z**3 - 5*z) * s**2 / 36)
109
+
110
+ return -(self.returns.mean() + z_cf * self.returns.std())
111
+
112
+ # Conditional VaR (Expected Shortfall)
113
+ def cvar(self, confidence: float = 0.95) -> float:
114
+ """Expected Shortfall / CVaR / Average VaR."""
115
+ var = self.var_historical(confidence)
116
+ return -self.returns[self.returns <= -var].mean()
117
+
118
+ # Drawdown Analysis
119
+ def drawdowns(self) -> pd.Series:
120
+ """Calculate drawdown series."""
121
+ cumulative = (1 + self.returns).cumprod()
122
+ running_max = cumulative.cummax()
123
+ return (cumulative - running_max) / running_max
124
+
125
+ def max_drawdown(self) -> float:
126
+ """Maximum drawdown."""
127
+ return self.drawdowns().min()
128
+
129
+ def avg_drawdown(self) -> float:
130
+ """Average drawdown."""
131
+ dd = self.drawdowns()
132
+ return dd[dd < 0].mean() if (dd < 0).any() else 0
133
+
134
+ def drawdown_duration(self) -> Dict[str, int]:
135
+ """Drawdown duration statistics."""
136
+ dd = self.drawdowns()
137
+ in_drawdown = dd < 0
138
+
139
+ # Find drawdown periods
140
+ drawdown_starts = in_drawdown & ~in_drawdown.shift(1).fillna(False)
141
+ drawdown_ends = ~in_drawdown & in_drawdown.shift(1).fillna(False)
142
+
143
+ durations = []
144
+ current_duration = 0
145
+
146
+ for i in range(len(dd)):
147
+ if in_drawdown.iloc[i]:
148
+ current_duration += 1
149
+ elif current_duration > 0:
150
+ durations.append(current_duration)
151
+ current_duration = 0
152
+
153
+ if current_duration > 0:
154
+ durations.append(current_duration)
155
+
156
+ return {
157
+ "max_duration": max(durations) if durations else 0,
158
+ "avg_duration": np.mean(durations) if durations else 0,
159
+ "current_duration": current_duration
160
+ }
161
+
162
+ # Risk-Adjusted Returns
163
+ def sharpe_ratio(self) -> float:
164
+ """Annualized Sharpe ratio."""
165
+ excess_return = self.returns.mean() * self.ann_factor - self.rf_rate
166
+ vol = self.volatility(annualized=True)
167
+ return excess_return / vol if vol > 0 else 0
168
+
169
+ def sortino_ratio(self) -> float:
170
+ """Sortino ratio using downside deviation."""
171
+ excess_return = self.returns.mean() * self.ann_factor - self.rf_rate
172
+ dd = self.downside_deviation(threshold=0, annualized=True)
173
+ return excess_return / dd if dd > 0 else 0
174
+
175
+ def calmar_ratio(self) -> float:
176
+ """Calmar ratio (return / max drawdown)."""
177
+ annual_return = (1 + self.returns).prod() ** (self.ann_factor / len(self.returns)) - 1
178
+ max_dd = abs(self.max_drawdown())
179
+ return annual_return / max_dd if max_dd > 0 else 0
180
+
181
+ def omega_ratio(self, threshold: float = 0) -> float:
182
+ """Omega ratio."""
183
+ returns_above = self.returns[self.returns > threshold] - threshold
184
+ returns_below = threshold - self.returns[self.returns <= threshold]
185
+
186
+ if returns_below.sum() == 0:
187
+ return np.inf
188
+
189
+ return returns_above.sum() / returns_below.sum()
190
+
191
+ # Information Ratio
192
+ def information_ratio(self, benchmark_returns: pd.Series) -> float:
193
+ """Information ratio vs benchmark."""
194
+ active_returns = self.returns - benchmark_returns
195
+ tracking_error = active_returns.std() * np.sqrt(self.ann_factor)
196
+ active_return = active_returns.mean() * self.ann_factor
197
+ return active_return / tracking_error if tracking_error > 0 else 0
198
+
199
+ # Summary
200
+ def summary(self) -> Dict[str, float]:
201
+ """Generate comprehensive risk summary."""
202
+ dd_stats = self.drawdown_duration()
203
+
204
+ return {
205
+ # Returns
206
+ "total_return": (1 + self.returns).prod() - 1,
207
+ "annual_return": (1 + self.returns).prod() ** (self.ann_factor / len(self.returns)) - 1,
208
+
209
+ # Volatility
210
+ "annual_volatility": self.volatility(),
211
+ "downside_deviation": self.downside_deviation(),
212
+
213
+ # VaR & CVaR
214
+ "var_95_historical": self.var_historical(0.95),
215
+ "var_99_historical": self.var_historical(0.99),
216
+ "cvar_95": self.cvar(0.95),
217
+
218
+ # Drawdowns
219
+ "max_drawdown": self.max_drawdown(),
220
+ "avg_drawdown": self.avg_drawdown(),
221
+ "max_drawdown_duration": dd_stats["max_duration"],
222
+
223
+ # Risk-Adjusted
224
+ "sharpe_ratio": self.sharpe_ratio(),
225
+ "sortino_ratio": self.sortino_ratio(),
226
+ "calmar_ratio": self.calmar_ratio(),
227
+ "omega_ratio": self.omega_ratio(),
228
+
229
+ # Distribution
230
+ "skewness": stats.skew(self.returns),
231
+ "kurtosis": stats.kurtosis(self.returns),
232
+ }
233
+ ```
234
+
235
+ ### Pattern 2: Portfolio Risk
236
+
237
+ ```python
238
+ class PortfolioRisk:
239
+ """Portfolio-level risk calculations."""
240
+
241
+ def __init__(
242
+ self,
243
+ returns: pd.DataFrame,
244
+ weights: Optional[pd.Series] = None
245
+ ):
246
+ """
247
+ Args:
248
+ returns: DataFrame with asset returns (columns = assets)
249
+ weights: Portfolio weights (default: equal weight)
250
+ """
251
+ self.returns = returns
252
+ self.weights = weights if weights is not None else \
253
+ pd.Series(1/len(returns.columns), index=returns.columns)
254
+ self.ann_factor = 252
255
+
256
+ def portfolio_return(self) -> float:
257
+ """Weighted portfolio return."""
258
+ return (self.returns @ self.weights).mean() * self.ann_factor
259
+
260
+ def portfolio_volatility(self) -> float:
261
+ """Portfolio volatility."""
262
+ cov_matrix = self.returns.cov() * self.ann_factor
263
+ port_var = self.weights @ cov_matrix @ self.weights
264
+ return np.sqrt(port_var)
265
+
266
+ def marginal_risk_contribution(self) -> pd.Series:
267
+ """Marginal contribution to risk by asset."""
268
+ cov_matrix = self.returns.cov() * self.ann_factor
269
+ port_vol = self.portfolio_volatility()
270
+
271
+ # Marginal contribution
272
+ mrc = (cov_matrix @ self.weights) / port_vol
273
+ return mrc
274
+
275
+ def component_risk(self) -> pd.Series:
276
+ """Component contribution to total risk."""
277
+ mrc = self.marginal_risk_contribution()
278
+ return self.weights * mrc
279
+
280
+ def risk_parity_weights(self, target_vol: float = None) -> pd.Series:
281
+ """Calculate risk parity weights."""
282
+ from scipy.optimize import minimize
283
+
284
+ n = len(self.returns.columns)
285
+ cov_matrix = self.returns.cov() * self.ann_factor
286
+
287
+ def risk_budget_objective(weights):
288
+ port_vol = np.sqrt(weights @ cov_matrix @ weights)
289
+ mrc = (cov_matrix @ weights) / port_vol
290
+ rc = weights * mrc
291
+ target_rc = port_vol / n # Equal risk contribution
292
+ return np.sum((rc - target_rc) ** 2)
293
+
294
+ constraints = [
295
+ {"type": "eq", "fun": lambda w: np.sum(w) - 1}, # Weights sum to 1
296
+ ]
297
+ bounds = [(0.01, 1.0) for _ in range(n)] # Min 1%, max 100%
298
+ x0 = np.array([1/n] * n)
299
+
300
+ result = minimize(
301
+ risk_budget_objective,
302
+ x0,
303
+ method="SLSQP",
304
+ bounds=bounds,
305
+ constraints=constraints
306
+ )
307
+
308
+ return pd.Series(result.x, index=self.returns.columns)
309
+
310
+ def correlation_matrix(self) -> pd.DataFrame:
311
+ """Asset correlation matrix."""
312
+ return self.returns.corr()
313
+
314
+ def diversification_ratio(self) -> float:
315
+ """Diversification ratio (higher = more diversified)."""
316
+ asset_vols = self.returns.std() * np.sqrt(self.ann_factor)
317
+ weighted_vol = (self.weights * asset_vols).sum()
318
+ port_vol = self.portfolio_volatility()
319
+ return weighted_vol / port_vol if port_vol > 0 else 1
320
+
321
+ def tracking_error(self, benchmark_returns: pd.Series) -> float:
322
+ """Tracking error vs benchmark."""
323
+ port_returns = self.returns @ self.weights
324
+ active_returns = port_returns - benchmark_returns
325
+ return active_returns.std() * np.sqrt(self.ann_factor)
326
+
327
+ def conditional_correlation(
328
+ self,
329
+ threshold_percentile: float = 10
330
+ ) -> pd.DataFrame:
331
+ """Correlation during stress periods."""
332
+ port_returns = self.returns @ self.weights
333
+ threshold = np.percentile(port_returns, threshold_percentile)
334
+ stress_mask = port_returns <= threshold
335
+ return self.returns[stress_mask].corr()
336
+ ```
337
+
338
+ ### Pattern 3: Rolling Risk Metrics
339
+
340
+ ```python
341
+ class RollingRiskMetrics:
342
+ """Rolling window risk calculations."""
343
+
344
+ def __init__(self, returns: pd.Series, window: int = 63):
345
+ """
346
+ Args:
347
+ returns: Return series
348
+ window: Rolling window size (default: 63 = ~3 months)
349
+ """
350
+ self.returns = returns
351
+ self.window = window
352
+
353
+ def rolling_volatility(self, annualized: bool = True) -> pd.Series:
354
+ """Rolling volatility."""
355
+ vol = self.returns.rolling(self.window).std()
356
+ if annualized:
357
+ vol *= np.sqrt(252)
358
+ return vol
359
+
360
+ def rolling_sharpe(self, rf_rate: float = 0.02) -> pd.Series:
361
+ """Rolling Sharpe ratio."""
362
+ rolling_return = self.returns.rolling(self.window).mean() * 252
363
+ rolling_vol = self.rolling_volatility()
364
+ return (rolling_return - rf_rate) / rolling_vol
365
+
366
+ def rolling_var(self, confidence: float = 0.95) -> pd.Series:
367
+ """Rolling historical VaR."""
368
+ return self.returns.rolling(self.window).apply(
369
+ lambda x: -np.percentile(x, (1 - confidence) * 100),
370
+ raw=True
371
+ )
372
+
373
+ def rolling_max_drawdown(self) -> pd.Series:
374
+ """Rolling maximum drawdown."""
375
+ def max_dd(returns):
376
+ cumulative = (1 + returns).cumprod()
377
+ running_max = cumulative.cummax()
378
+ drawdowns = (cumulative - running_max) / running_max
379
+ return drawdowns.min()
380
+
381
+ return self.returns.rolling(self.window).apply(max_dd, raw=False)
382
+
383
+ def rolling_beta(self, market_returns: pd.Series) -> pd.Series:
384
+ """Rolling beta vs market."""
385
+ def calc_beta(window_data):
386
+ port_ret = window_data.iloc[:, 0]
387
+ mkt_ret = window_data.iloc[:, 1]
388
+ cov = np.cov(port_ret, mkt_ret)
389
+ return cov[0, 1] / cov[1, 1] if cov[1, 1] != 0 else 0
390
+
391
+ combined = pd.concat([self.returns, market_returns], axis=1)
392
+ return combined.rolling(self.window).apply(
393
+ lambda x: calc_beta(x.to_frame()),
394
+ raw=False
395
+ ).iloc[:, 0]
396
+
397
+ def volatility_regime(
398
+ self,
399
+ low_threshold: float = 0.10,
400
+ high_threshold: float = 0.20
401
+ ) -> pd.Series:
402
+ """Classify volatility regime."""
403
+ vol = self.rolling_volatility()
404
+
405
+ def classify(v):
406
+ if v < low_threshold:
407
+ return "low"
408
+ elif v > high_threshold:
409
+ return "high"
410
+ else:
411
+ return "normal"
412
+
413
+ return vol.apply(classify)
414
+ ```
415
+
416
+ ### Pattern 4: Stress Testing
417
+
418
+ ```python
419
+ class StressTester:
420
+ """Historical and hypothetical stress testing."""
421
+
422
+ # Historical crisis periods
423
+ HISTORICAL_SCENARIOS = {
424
+ "2008_financial_crisis": ("2008-09-01", "2009-03-31"),
425
+ "2020_covid_crash": ("2020-02-19", "2020-03-23"),
426
+ "2022_rate_hikes": ("2022-01-01", "2022-10-31"),
427
+ "dot_com_bust": ("2000-03-01", "2002-10-01"),
428
+ "flash_crash_2010": ("2010-05-06", "2010-05-06"),
429
+ }
430
+
431
+ def __init__(self, returns: pd.Series, weights: pd.Series = None):
432
+ self.returns = returns
433
+ self.weights = weights
434
+
435
+ def historical_stress_test(
436
+ self,
437
+ scenario_name: str,
438
+ historical_data: pd.DataFrame
439
+ ) -> Dict[str, float]:
440
+ """Test portfolio against historical crisis period."""
441
+ if scenario_name not in self.HISTORICAL_SCENARIOS:
442
+ raise ValueError(f"Unknown scenario: {scenario_name}")
443
+
444
+ start, end = self.HISTORICAL_SCENARIOS[scenario_name]
445
+
446
+ # Get returns during crisis
447
+ crisis_returns = historical_data.loc[start:end]
448
+
449
+ if self.weights is not None:
450
+ port_returns = (crisis_returns @ self.weights)
451
+ else:
452
+ port_returns = crisis_returns
453
+
454
+ total_return = (1 + port_returns).prod() - 1
455
+ max_dd = self._calculate_max_dd(port_returns)
456
+ worst_day = port_returns.min()
457
+
458
+ return {
459
+ "scenario": scenario_name,
460
+ "period": f"{start} to {end}",
461
+ "total_return": total_return,
462
+ "max_drawdown": max_dd,
463
+ "worst_day": worst_day,
464
+ "volatility": port_returns.std() * np.sqrt(252)
465
+ }
466
+
467
+ def hypothetical_stress_test(
468
+ self,
469
+ shocks: Dict[str, float]
470
+ ) -> float:
471
+ """
472
+ Test portfolio against hypothetical shocks.
473
+
474
+ Args:
475
+ shocks: Dict of {asset: shock_return}
476
+ """
477
+ if self.weights is None:
478
+ raise ValueError("Weights required for hypothetical stress test")
479
+
480
+ total_impact = 0
481
+ for asset, shock in shocks.items():
482
+ if asset in self.weights.index:
483
+ total_impact += self.weights[asset] * shock
484
+
485
+ return total_impact
486
+
487
+ def monte_carlo_stress(
488
+ self,
489
+ n_simulations: int = 10000,
490
+ horizon_days: int = 21,
491
+ vol_multiplier: float = 2.0
492
+ ) -> Dict[str, float]:
493
+ """Monte Carlo stress test with elevated volatility."""
494
+ mean = self.returns.mean()
495
+ vol = self.returns.std() * vol_multiplier
496
+
497
+ simulations = np.random.normal(
498
+ mean,
499
+ vol,
500
+ (n_simulations, horizon_days)
501
+ )
502
+
503
+ total_returns = (1 + simulations).prod(axis=1) - 1
504
+
505
+ return {
506
+ "expected_loss": -total_returns.mean(),
507
+ "var_95": -np.percentile(total_returns, 5),
508
+ "var_99": -np.percentile(total_returns, 1),
509
+ "worst_case": -total_returns.min(),
510
+ "prob_10pct_loss": (total_returns < -0.10).mean()
511
+ }
512
+
513
+ def _calculate_max_dd(self, returns: pd.Series) -> float:
514
+ cumulative = (1 + returns).cumprod()
515
+ running_max = cumulative.cummax()
516
+ drawdowns = (cumulative - running_max) / running_max
517
+ return drawdowns.min()
518
+ ```
519
+
520
+ ## Quick Reference
521
+
522
+ ```python
523
+ # Daily usage
524
+ metrics = RiskMetrics(returns)
525
+ print(f"Sharpe: {metrics.sharpe_ratio():.2f}")
526
+ print(f"Max DD: {metrics.max_drawdown():.2%}")
527
+ print(f"VaR 95%: {metrics.var_historical(0.95):.2%}")
528
+
529
+ # Full summary
530
+ summary = metrics.summary()
531
+ for metric, value in summary.items():
532
+ print(f"{metric}: {value:.4f}")
533
+ ```
534
+
535
+ ## Best Practices
536
+
537
+ ### Do's
538
+ - **Use multiple metrics** - No single metric captures all risk
539
+ - **Consider tail risk** - VaR isn't enough, use CVaR
540
+ - **Rolling analysis** - Risk changes over time
541
+ - **Stress test** - Historical and hypothetical
542
+ - **Document assumptions** - Distribution, lookback, etc.
543
+
544
+ ### Don'ts
545
+ - **Don't rely on VaR alone** - Underestimates tail risk
546
+ - **Don't assume normality** - Returns are fat-tailed
547
+ - **Don't ignore correlation** - Increases in stress
548
+ - **Don't use short lookbacks** - Miss regime changes
549
+ - **Don't forget transaction costs** - Affects realized risk
550
+
551
+ ## Resources
552
+
553
+ - [Risk Management and Financial Institutions (John Hull)](https://www.amazon.com/Risk-Management-Financial-Institutions-5th/dp/1119448115)
554
+ - [Quantitative Risk Management (McNeil, Frey, Embrechts)](https://www.amazon.com/Quantitative-Risk-Management-Techniques-Princeton/dp/0691166277)
555
+ - [pyfolio Documentation](https://quantopian.github.io/pyfolio/)