Skip to content
Ahmed Hamza

Work in progress / independent research system

QAP Crypto CLI

Work-in-progress Python CLI that compares spot crypto pairs, checks whether the data and setup are trustworthy, and uses copula-based dependency evidence before paper-run decision workflows.

PythonTyperuvPytestStudent-t CopulaQuant ResearchCrypto

QAP Crypto CLI

Summary: Most crypto tools make it easy to chase a signal. QAP asks a harder question first: which pairs are actually worth trusting, and which only look good on a chart?

QAP is a work-in-progress Python CLI that compares spot crypto pairs, checks the data behind them, tests whether the relationship holds up, and uses advanced dependency models before moving into paper-run decision workflows. It is the most complex independent research system I have taken on because it turns research papers, market data, pair comparison, validation rules, and proof artifacts into one command-line workflow.

Why I built it

Crypto has been my longest-running technical interest. I have followed the market for more than 10 years, first as curiosity, then as a deeper attempt to understand why some strategies sound convincing but fail once costs, volatility, missing data, and execution reality are included.

At some point I wanted to move past chart-watching and indicator stacking. I started reading and decoding research papers around pairs trading, cointegration, z-score diagnostics, copulas, tail dependence, walk-forward validation, and portfolio-style accumulation.

QAP came from that decision: if I care about crypto this much, I should build a system that tells me when an idea is weak, not just when it looks exciting.

What it does

QAP is a Python CLI for spot crypto pair analysis and forward-proof preparation. It is not just a research notebook in terminal form. The tool helps answer practical questions:

The current direction is not live order routing. QAP is the decision and proof layer before any external execution path.

The workflow is deliberately phase-based:

Pipeline Architecture

 $ qap validate BTC-USDT --freshness-check
 
 ┌──────────────┐
 │ 1. DISCOVER  │ ──➔ (Spot pair correlation & eligibility)
 └──────┬───────┘

 ┌──────────────┐
 │  2. INGEST   │ ──➔ (Freshness audit: cached & live provider sync)
 └──────┬───────┘

 ┌──────────────┐
 │ 3. COPULA    │ ──➔ (Tail dependence & Mispricing Index model)
 └──────┬───────┘

 ┌──────────────┐
 │ 4. VETO GATE │ ──➔ (Checks z-score, cointegration & risk rules)
 └──────┬───────┘

 [Actionable / Blocked report + Paper-run bundle manifest]

Terminal Session Output

$ qap validate BTC-USDT --freshness-check
[INFO] Loading config from ~/.qap/config.json
[DATA] Cache age: 4m (freshness limit: 15m) -> Ingestion skipped.
[COPULA] Fitting Student-t Copula for BTC-USDT tail correlation...
[COPULA] Tail-dependence parameter: 0.81 (Signal: mispriced / candidate)
[VETO] Cointegration p-value: 0.12 (limit: 0.05) -> [VETO TRIGGERED]
[VETO] Relationship non-stationary; high probability of random walk divergence.
[REPORT] Validation completed.
  Pair status: BLOCKED
  Veto matches: 1 (Stationarity test failure)
  Action: No trade allowed. Saved manifest to ~/.qap/runs/blocked_BTC-USDT.json

The goal is not a flashy win-rate screenshot. QAP is built around a more useful question: after fees and slippage, did the system accumulate more coin pieces than simply holding?

Tech stack

QAP is a Python 3.11+ CLI managed with uv. The command surface uses Typer, while the domain logic sits under a core layer for models, validation, backtests, risk gates, configuration, ledgers, registries, reporting, and paper execution contracts.

The testing surface is a major part of the project. The repo includes unit, CLI, integration, invariant, architecture, ops, performance, reference, stress, and characterization tests. That matters because this project is easy to make impressive-looking and wrong. The tests are there to defend boundaries such as copula-only signal authority, simulation-only execution, and thin CLI adapters.

Key engineering decisions

The biggest decision is that Student-t Copula Mispricing Index is the canonical signal authority. In simpler terms: QAP does not let a basic chart signal decide by itself.

It still studies spreads, hedge ratios, z-score diagnostics, cointegration, tail behavior, and pair eligibility, but those mechanisms have different jobs. Z-score and spread diagnostics can help explain structure, but they are not allowed to become the trade trigger.

That choice forced the architecture to separate responsibilities clearly:

This is why QAP has phase enforcement, explicit no-trade explanations, paper-only bundles, pair eligibility rules, and governance checks. The goal is to make the system honest when it says no.

Problems I ran into

The hardest part is that every useful idea adds another way to be wrong.

Student-t copula work needs enough aligned data and careful probability handling. Z-score diagnostics are useful, but dangerous if they leak into signal authority. Pair eligibility needs structure, not just correlation. Backtests need fees, slippage, warmup behavior, and walk-forward checks. Shadow runs need provenance. Paper artifacts need enough metadata to be evaluated later. Tests need to catch architecture drift before the CLI becomes a pile of command adapters.

That is why this project has been difficult: it is not one algorithm. It is many integrations that have to agree with each other.

Engineering Notes & Lessons Learned

Validation Notes

What I would improve next

The next work is to keep tightening the forward paper-run path, improve copula readiness reporting, expand deterministic test coverage around edge cases, and make the CLI output clearer for the difference between structural eligibility, signal evidence, and current actionability.

I also want to keep translating the research-paper side into practical engineering notes, because this project is partly a tool and partly my way of learning crypto market structure with real code.