{"id":"empyrical-metrics","card_id":"card_empyrical_metrics","name":"empyrical metrics","description":"Computes deterministic empyrical-style portfolio metrics from supplied returns: annual return, cumulative return, Sharpe, Sortino, max drawdown, Calmar, downside risk, and tail ratio. TS reimplementation of OSS empyrical 0.5.5 conventions; DATA ONLY.","stage":1,"safety_level":"data_only_read_only","auth":{"type":"hmac-sha256","required_headers":["x-apex-tool-timestamp","x-apex-tool-nonce","x-apex-tool-content-sha256","x-apex-tool-signature"],"canonical_payload":"APEX-TOOL-V1\\n{tool_id}\\n{timestamp}\\n{nonce}\\n{sha256(canonical_json(body))}"},"permissionless":{"enabled":true,"tier":"bounded_public","rate_limit":"Shared 20 calls per IP per hour across all permissionless bounded tools.","review_required":false,"note":"First-run DATA ONLY tier: no HMAC required. Supplying an Agent Passport attributes the receipt to that agent and uses the signed-agent lane."},"input_schema":{"type":"object","required":["returns"],"properties":{"returns":{"type":"array","minItems":2,"maxItems":10000,"items":{"type":"number"}},"risk_free":{"type":"number","default":0,"description":"Per-period required/risk-free return used for Sharpe, Sortino, and downside risk."},"period":{"type":"string","enum":["daily","weekly","monthly","quarterly","yearly"],"default":"daily"},"annualization":{"type":"number","minimum":0,"description":"Overrides period-derived annualization when supplied."}}},"output_schema":{"type":"object","properties":{"annual_return":{"type":["number","null"]},"cumulative_return":{"type":["number","null"]},"sharpe_ratio":{"type":["number","null"]},"sortino_ratio":{"type":["number","null"]},"max_drawdown":{"type":["number","null"]},"calmar_ratio":{"type":["number","null"]},"downside_risk":{"type":["number","null"]},"tail_ratio":{"type":["number","null"]},"conventions":{"type":"object"}}},"sample_input":{"returns":[0.01,-0.02,0.015,0,0.007,-0.004,0.012],"period":"daily","risk_free":0},"test_vectors":[{"input":{"returns":[0.01,-0.02,0.015,0,0.007,-0.004,0.012],"period":"daily","risk_free":0},"expected":{"result":{"schema":"apex-empyrical-metrics/1","annual_return":1.020139103999,"cumulative_return":0.019724404615,"sharpe_ratio":3.751832396884,"sortino_ratio":5.883484054146,"max_drawdown":-0.02,"calmar_ratio":51.006955199966,"downside_risk":0.122376468326,"tail_ratio":0.927631578947}},"match":"subset","verified_at":"2026-07-04T06:30:00.000Z"},{"input":{"returns":[0.02,0.01,-0.005,0.03,-0.01,0.004],"period":"weekly","risk_free":0.001},"expected":{"result":{"schema":"apex-empyrical-metrics/1","annual_return":0.519054093934,"cumulative_return":0.049423435161,"sharpe_ratio":3.421312768037,"sortino_ratio":10.102867936978,"max_drawdown":-0.01,"calmar_ratio":51.905409393398,"downside_risk":0.036887215491,"tail_ratio":3.142857142857}},"match":"subset","verified_at":"2026-07-04T06:30:00.000Z"},{"input":{"returns":[-0.03,0.01,0.02,-0.01,0.015,0.005,-0.02,0.025],"annualization":12,"risk_free":0},"expected":{"result":{"schema":"apex-empyrical-metrics/1","annual_return":0.02062400631,"cumulative_return":0.013702504534,"sharpe_ratio":0.32788493778,"sortino_ratio":0.490990253031,"max_drawdown":-0.03,"calmar_ratio":0.687466877012,"downside_risk":0.04582575695,"tail_ratio":0.877358490566}},"match":"subset","verified_at":"2026-07-04T06:30:00.000Z"}]}