Analyze

SkillProductivity

Use when tasks need factor diagnostics, IC/grouped return analysis, attribution, robustness checks, deterministic factor-mining evaluation, or time-series distribution and stationarity checks.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Analyze skill

What this skill tells your AI

The instructions your AI receives, as published by quantskills/agent-quantspace in skills/analyze/SKILL.md and read by ahel’s review.

Analyze is the research diagnostics boundary. Use it to understand factors, returns, attribution, robustness, and time-series behavior after data and signals have been produced. Strategy execution and portfolio construction live in skills.backtest.

Phase 03 adds a deterministic AnalyzeFacade for factor-mining preflight, evaluation, and explicit pool comparison. The facade is read-only (no implicit I/O), fails fast on hard preflight/alignment/causality failures before return evaluation, and returns analyze-native structured results. Formal portfolio returns and costs always call skills.backtest.VectorBacktester.

skills.analyze must not import skills.factor_mining, strategies, store global paths, report rendering, controller/role/workflow code, or LLM SDKs.

Install plotting and parallel-analysis dependencies with uv sync --extra analyze.

Public API

from skills.analyze import AnalyzeFacade, ProtocolSnapshot, SpecSnapshot
from skills.analyze.factor_analysis import IC_stat, group_stat, full_stat
from skills.analyze.factor_information import (
    ICInformationResult,
    compute_horizon_ic,
    compute_ic_information_surface,
    compute_lagged_ic,
    rolling_factor_rank_correlation,
)
from skills.analyze.ts_analysis import TimeSeriesAnalyzer, analyze_time_series
from skills.analyze.attribution_counterfactual import performance_metrics

Components

Module familyPurpose
facade / contractsDeterministic Phase 03 entrypoint and analyze-native snapshots
validation / spec_checks / causalityPanel, formula structure, parameter, and prefix-causality checks
factor_evaluation / factor_robustness / factor_incrementalIC/quantiles/turnover, robustness, pool incremental
factor_analysisLegacy IC statistics, grouped returns, winsorization helpers
factor_informationHorizon/Lag IC surfaces, HAC summaries, rank correlation, rolling correlation, and Top-N overlap
ts_analysisKDE/QQ plots, Hurst, ADF, KPSS, trend scoring
attribution_*Symbol/category PnL, Brinson, decision edges, ranking buckets, Shapley, robustness, stat tests
tearsheetFactor and artifact-namespace summary report helpers

Recipes

Deterministic factor-mining evaluation (via Phase 02 adapter)

from skills.analyze import AnalyzeFacade
from skills.factor_mining.adapters.analyze import (
    AnalyzeAdapter,
    build_prefix_recompute_capability,
)

# Official issuer signature: FactorSpec + optional verified FactorExecutionResult.
# Preflight (no execution): build_prefix_recompute_capability(factor=spec)
# Evaluate: build_prefix_recompute_capability(factor=spec, execution=execution)
# AnalyzeAdapter.preflight / evaluate wire this automatically.
# The snippet below is illustrative (loaders/request omitted); production code
# injects real resolvers and must not treat ellipsis as runnable.

adapter = AnalyzeAdapter(
    facade=AnalyzeFacade(),
    resolve_brief=resolve_brief,
    resolve_factor=resolve_factor,
    resolve_protocol=resolve_protocol,
    resolve_execution=resolve_execution,
    load_series=load_series,
    load_panel=load_panel,
)
preflight_report = adapter.preflight(evaluation_request)
assert preflight_report.failure is None
# After Phase02 execute(...):
eval_report = adapter.evaluate(evaluation_request_with_execution_ref)
assert eval_report.engine_version

Trust boundary (prefix recompute). BoundPrefixRecompute cannot be constructed publicly. The only production issuer is build_prefix_recompute_capability(factor: FactorSpec, execution=None) — it compiles the exact FactorSpec and optionally checks execution.callable_fingerprint. Analyze does not expose a public API that seals arbitrary callables with hash strings. Process trust boundary: private helpers remain importable in-process; orchestration policy must only use the Phase02 adapter builder. Evaluate additionally requires an issued recompute to reproduce evaluated values (CAUSALITY_RECOMPUTE_VALUE_MISMATCH).

FunctionRef has no module allowlist. It may point to generated strategy code, skills.compute, or another importable local dependency. Analyze checks the research contract—fields, parameter/window/lag consistency, output alignment, and time causality—rather than treating the local Python module as untrusted.

Trust boundary (resolvers / artifact loaders). Production resolve_brief / resolve_factor / resolve_execution / load_series ports are trusted orchestration inputs. ArtifactRef.content_hash must be verified by a store-backed loader (e.g. DataManagerArtifactStore.get). Arbitrary in-process malicious reflection is outside the security boundary; private issuers only prevent accidental public-API misuse, not same-process attackers.

Trust boundary (formal pool pair). Portfolio deltas require an officially issued FormalBacktestPair from run_official_formal_backtest_pair, which constructs module VectorBacktester twice on explicit before/after target weights (no caller factory). Issuance is a canonical digest over before/after result_df/executed_weights plus panel/candidate/pool/protocol/shared-sample/ target-weight hashes and engine name/version. The pair rejects ordinary setattr after freeze; is_issued() recomputes the digest so object.__setattr__ tampering invalidates compare. There is no helper that accepts caller-supplied BacktestResult objects as verified.

Protocol vs Brief authority. Brief owns horizon/rebalance/cost/universe/ execution_delay_bars (mapped to signal_lag). trade_at and return_mode are Analyze/ProtocolSnapshot fields with no Brief counterpart — they are not silently inferred from Brief; callers must set them on the protocol.

Execution-aligned labels. Predictive IC, group returns, and pool residual / R² use one canonical label: forward P[t+L+H]/P[t+L]-1 or backward P[t+L]/P[t+L-H]-1 on protocol.trade_at prices, with signal_lag=L and holding window horizon_bars=H. Formal trading asserts the same semantics and is unavailable for horizon_bars != 1 (one-bar VectorBacktester limit).

Overlapping horizons (horizon_bars > 1) mark iid IC t-tests unavailable and report Newey–West HAC t/se/p instead. Pool marginal value is joint CS R² delta / residual IC under residual df and full-rank checks — never candidate IC minus mean member IC, and never saturated n == n_params mechanical R²=1.

Horizon IC and Lagged IC

from skills.analyze.factor_information import compute_horizon_ic, compute_lagged_ic

horizon_result = compute_horizon_ic(
    factors,
    close_prices,
    horizons=[1, 3, 5, 10, 20, 40, 60],
    signal_lag=1,
)
lagged_result = compute_lagged_ic(
    factors,
    close_prices,
    horizons=[1, 5, 10, 20],
    lags=[0, 1, 2, 3, 5, 10, 20, 40, 60],
    signal_lag=1,
)

Both return ICInformationResult(summary, daily_ic). Horizon IC fixes lag=0; Lagged IC changes signal-use delay independently of the return horizon. The execution-aligned return is P[t+signal_lag+lag+horizon] / P[t+signal_lag+lag] - 1, and each summary row uses Newey-West lag horizon-1.

Factor evaluation (legacy helpers)

from skills.analyze.factor_analysis import IC_stat, group_stat

ic_stat_dict, ic_series = IC_stat(df, rank_IC=True, n=5)
group_return, turnover = group_stat(df, n=5, g=5, verbose=True)

Time-series stationarity check

from skills.analyze.ts_analysis import TimeSeriesAnalyzer

analyzer = TimeSeriesAnalyzer(price_series)
analyzer.analyze_windows([60, 120, 240])
results_df = analyzer.get_results_dataframe()

Return-distribution KDE and QQ analysis

from skills.analyze.ts_analysis import ts_analysis

fig, axes = ts_analysis(
    price_series,
    plot_title="asset",
    plot_path="reports/asset.png",
    show=False,
    save_csv=True,
)

The input is a price-level series. The combined chart and CSV summarize standardized log-return distributions for lags 1 through 34; QQ theoretical quantiles are deterministic standard-normal quantiles.

Signals

GitHub stars
57
Forks
11
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
analyze-quantskills
Source
github.com/quantskills/agent-quantspace