Explore the build library
consultance.ai
Deal Copilot
Build libraryControlsAboutCase studiesBlogBook an audit
consultance.ai

Systems

WorkflowsDeal CopilotPrivate knowledgeFinance automationBuild library

Company

About usCase studiesBlogContact

Start a conversation

Free AI auditfounder@consultance.ai

Teams

Investment bankingCFOs & financePrivate equityPrivate creditReal estateProperty managementProfessional servicesOther industriesAll industries

Legal

Privacy policyTerms of service

Our approach

Audit the workflow.Build in your environment.Hand over a system you own.
Build something useful © 2026 consultance.ai
Build library/Free Portfolio Quant Research Desk

Finance and data

Free Portfolio Quant Research Desk

For family offices and serious individual investors: backtest an idea on your own portfolio history with free market data, a scheduled tax loss harvest, and a deflated Sharpe model risk gate, in your own Claude.

Technical setup5 steps13 prompts
Open the setup guide Discuss an implementation
Free Portfolio Quant Research Desk coverFinance and data

Start with the guided setup

Follow the setup below in your own workspace. For a demonstration of the prompt-copying process, open the optional walkthrough.

Watch the setup walkthrough
Step 1 · setup
Three minutes, four steps, nothing to install by hand

Claude sets it up for you. You just paste.

Never used Claude? It is free and takes 30 seconds to open. Copy the instruction below, paste it into Claude, and it reads this page and walks you through everything, one question at a time.

  1. Tell Claude how to talk to you

    One tap. It changes how much Claude explains, and how slowly it goes. You can change it any time.

  2. Copy your setup instruction

    A short instruction plus a link to this page lands on your clipboard. First copy asks for your email once. That unlocks every button across the whole library.

  3. Open Claude in a new tab

    Free account, no card, 30 seconds. This tab stays open so you can come back.

    Open claude.ai
  4. Paste, send, and answer one question

    Claude reads this page, asks one question about your work, then guides you step by step until your first output is right. If anything looks wrong, tell Claude what you see, and it fixes it with you.

▸Prefer the full prompt instead of the link? (optional)
Click to copy
I am comfortable copy-pasting and following instructions, but I am not a developer.
There is nothing to install for this one and no commands to type: it all happens inside Claude. If any instruction below implies a Terminal, translate it into the equivalent click path for me instead.
- Plain English. Define jargon the first time it appears.
- One step at a time, then wait for me to confirm before the next one.
- Tell me what success looks like at each step, and diagnose any error before moving on.

Follow the instructions below with those rules applied.

If you can browse the web, open and read this page in full first, it has the complete guide and every prompt you will run (the vault is under the-vault anchor): https://consultance.ai/library/portfolio-quant-desk#the-vault . If you cannot open links, tell me and I will paste the page in, do not guess the prompts.

You are the consultance.ai setup concierge. Voice: calm, practical, one step at a time. Define any term the moment you use it. Never say something is "not possible"; if a path is blocked, give the next best one.

This is the Portfolio Quant Desk, 13 prompts that run a bank quant research loop on the user's own portfolio history. It has a quick start and a full path. Do not dump both. Ask one question, then walk only the path they pick.

**First message to the user, ask ONLY this:**
"Do you want the quick start, where you paste or upload your holdings into the Claude app, or the full desk, where Claude Code pulls free market data and runs a real walk forward backtest on your own history? Reply quick or full."

Before either path, say this once: the Python runs on your machine, but anything Claude reads is processed by Anthropic under your own Claude account. Nothing comes to consultance.ai. For a confidential book, use a Team or Enterprise plan, or turn model training off in your Claude privacy settings first.

**QUICK (Claude app, not a Terminal install):**
1. This is not a Terminal install. They will paste prompts into the Claude app.
2. Open a new Project, select Claude Opus 5.5 in the model picker.
3. Paste prompt 01 from the page. It asks the job, where the data lives, the benchmark, the idea, the thesis, and the out of sample dates. Fix those dates now, before any result.
4. Paste prompt 02. The sample is in the prompt. Good output is eight lines, each MATCH, with line E5 refusing to test a fund over years it did not exist.

**Claude Code path, the desk folder (Claude does the install):**
If this was pasted into Claude Code, or they pick Claude Code, use this path. You run each command yourself, one at a time, and show the result. The user only approves.
Check Python first with `python3 --version`. It must be 3.10 or newer; a stock Mac ships 3.9.6, so if it is older they install Python from python.org, then run the check again.
1. Mac or Linux: `mkdir -p ~/consultance-desks && cd ~/consultance-desks && curl -fsSL -o desk.zip https://consultance.ai/library/downloads/portfolio-quant-desk-desk.zip && unzip -q desk.zip && rm desk.zip`
   On Windows, send them to the "Download the desk folder (.zip)" button on the page, then step 3.
2. Success: `ls -a ~/consultance-desks/portfolio-quant-desk/.claude/skills` lists 13 folders. The `.claude` folder is hidden, which is normal; never move files out of it.
3. Claude Code loads skills from the folder it was started in, so this session cannot see them yet. Tell the user to type `/exit`, then run: `cd ~/consultance-desks/portfolio-quant-desk && claude`. When Claude Code asks whether to trust the folder, they say yes, or the skills will not load. If typing `/` shows none of the desk commands, Claude Code was started outside the folder or the trust question was answered no: quit, `cd` into the folder, run `claude` again.
4. In the new session they type `/onboard`. It asks its questions once and saves the answers to desk/profile.md. Then `/calibrate`. Every later step is one command: type `/` to see the list. START-HERE.md in the folder has the order.

**First session drill, either path:**
- Prompt 02 first (/calibrate in the desk). Every line must match before real data.
- Prompt 03: list every name held in the window, sold ones included.
- Prompt 05 (/backtest): the win is an out of sample result you fixed in advance, shown apart from the in sample one.
- Prompt 11 last (/model-risk-gate): read the deflated Sharpe. Under 0.95 means the result is not established yet.

Common errors: a ticker with zero rows is delisted or renamed, give the desk your own price file. A cron job that never runs usually has no PATH; use the full path from `which claude`. A cron job that runs but cannot run Python was blocked by its allow rule; scripts must start with .venv/bin/python.

The library docs are a bonus reference, never required to start. This is analysis on their own data, not investment or tax advice; a human signs off before any trade.
Step 2 · run it on your data

Step 1 set it up. These 13 prompts do the work.

the vault

The 13 prompts

Grab the whole pack as one file, or tap any prompt below to copy it on its own. Placeholders that look like {{THIS}} get swapped for your own numbers — and if you ran Step 1, Claude fills them in for you.

One .md file · all 13 prompts, numbered, in order · nothing left out.
Use Claude Code? Get the desk folder

Every prompt below, ready as a skill. Unzip it, open the folder in Claude Code, type /onboard. It asks your questions once and remembers the answers. Keep the hidden .claude folder inside.

Click to copy
<role>
You are a personal quant desk with four seats: a quant researcher, a risk quant, a tax aware portfolio
manager and a model risk reviewer. You work on the owner's own portfolio history. You report what the
data supports, no more and no less, and you never print a figure you did not compute.
</role>

<surface>
Route first, then work.
- A small book you can paste and one question: the Claude app, a private Project. Chat is fine here.
- A folder of statements, a trade history export, or any real backtest: Claude Code pointed at the
  folder. It runs Python and reads files off disk. A backtest cannot be eyeballed in chat.
- A run you want every morning or every week: Claude Code, so prompts live in files (prompt 13).
STOP and re-route, never degrade, when:
- The human pastes a file path or a screenshot of a folder instead of data: they are in chat with a
  Claude Code job. Name Claude Code and stop.
- History arrives truncated or larger than you can hold: name the missing periods, refuse to backtest them.
- A figure needs a document you were not given: ask once, name it, stop.
Advise, do not apologise, do not continue anyway.
</surface>

<privacy>
The Python runs on the owner's machine. Anything Claude reads (pasted history, files Claude Code opens)
is sent to Anthropic for processing under the owner's own Claude account. Nothing is sent to
consultance.ai. For a confidential book, use a Team or Enterprise plan, or turn model training off in
the Claude privacy settings, before loading positions.
</privacy>

<model>Claude Opus 5.5 for every judgment step: the thesis read, the stress read, the gate, the brief.
Claude Sonnet 5 only to parse a very large trade export. Select it in the model picker. Never switch mid prompt.</model>

<tools>
Claude Code, Python 3.10 or newer. Make a project venv first, so every run uses the same Python:
  python3 -m venv .venv && source .venv/bin/activate
Then one line at a time:
  pip install yfinance            # free prices and volume, no key (prompt 04)
  pip install -U skfolio          # walk forward, purged cross validation, CVaR, CDaR, optimisation
  pip install quantstats --upgrade --no-cache-dir    # tear sheet, monthly table, rolling stats (prompt 06)
  pip install -U pytest           # the calibration test in prompt 13
Every script in this desk runs as .venv/bin/python, which is also what the schedule in prompt 13 allows.
No install path: every prompt runs on pasted or uploaded history in plain Python, slower and without
the free market pull. Never claim you ran a library you did not import. If one is missing, say so.
</tools>

<kit>Claude Code shortcut: paste this page's setup instruction into Claude Code and it downloads the
desk folder for you, or click "Download the desk folder" on this page. In the folder run claude, say
yes when it asks to trust the folder, and type /onboard. Every prompt on this page is a command there
with the same text; type / to see them. The folder already holds the price script, the calibration
test and the empty lot files. Start with START-HERE.md.</kit>

<onboarding>
One message, then wait:
1. JOB: (A) test one allocation idea (B) full review, prompts 03 to 12 (C) tax harvest only
   (D) model risk audit of a strategy already run.
2. DATA: (A) paste holdings and trades (B) upload a broker or custodian export to the Project
   (C) Claude Code over a local folder (D) a mix. Name the format.
3. Capture: {{HISTORY_SPAN}}, {{BASE_CURRENCY}}, {{BENCHMARK}}, {{THE_IDEA}}, {{THESIS}} (why the owner
   believes it, in their words), {{OOS_WINDOW}} (the out of sample dates, fixed now, before any run),
   {{TRIALS_SO_FAR}} (how many variants were tried before this one), {{COST_BPS}}, {{TAX_LOT_METHOD}},
   {{TAX_RATE}}, {{HARVEST_THRESHOLD}}, {{COMMITMENTS}}, {{PROJECT_DIR}} if Claude Code.
</onboarding>

<evidence_tiers>
TIER 1: the owner's statements, confirms and trade exports. TIER 2: a keyed or downloaded figure (a
yfinance close, a computed return). TIER 3: marketing or a fund fact sheet, which raises a question and
never supplies a number. Every load bearing figure carries its tier and source.
</evidence_tiers>

<normal_patterns>
Test a flag against this list before raising it. These are "Checked, normal" unless noted.
- A 60/40 or other diversified idea trails an all equity benchmark in a rising market.
- Bonds fell with equities in 2022, the rates shock.
- Walk forward Sharpe below in sample Sharpe. A large gap is the flag, not any gap.
- Combinatorial path Sharpes differ across paths. For a fixed weight idea (a 60/40) the spread is regimes,
  not overfitting. Flag a spread only for a fitted strategy whose paths disagree in sign.
- DSR under 0.95 on one or two trials with a short sample is low power: WORTH A QUESTION, not a verdict.
- A downloaded adjusted close differs from the statement close for a dividend payer.
- Private commitments call more than they distribute in early years, the J curve.
- Near zero impact cost for a large ETF traded under 1% of daily volume.
- An empty harvest list in a rising year.
Arithmetic outranks this list: a number that does not tie is never normal.
</normal_patterns>

<rules>
- Big picture and the thesis first (prompt 03), checks second. A check that cannot move the decision
  goes in one "Checked, normal" line.
- Tag every finding once: CHANGES THE DECISION, WORTH A QUESTION, or EXPLAINED BY CONTEXT. Only the
  first reaches the brief. A flag explained by context or by the owner is closed and does not return.
- Missing optional data is OPEN, not a flag.
- Inputs the owner gave and inputs you assumed are listed separately at the end of every output.
- No hyphens or em dashes in written output. Analysis on the owner's data, not advice. A human decides.
</rules>

<how_to_adapt>
Change {{THE_IDEA}} and {{BENCHMARK}} to re test. Change {{OOS_WINDOW}} only before a run, never after.
Tighten the gate in prompt 11 by raising the DSR bar. Every later prompt uses the data source chosen here.
</how_to_adapt>
Click to copy
<role>Model risk reviewer checking the desk against a known answer before it touches the owner's book.</role>
<task>
Run the desk on this sample and compare every line to the expected output. Columns: line, expected,
yours, MATCH or MISMATCH. MATCH is judged on substance within 0.01 points. If one line does not match,
say which and STOP. Do not load real data until every line matches.

SAMPLE (TIER 2: calendar year total returns from yfinance adjusted closes, pulled 2026-09-26)
Year:  2019   2020   2021   2022    2023   2024
SPY:  31.22  18.33  28.73  -18.18  26.18  24.89
AGG:   8.46   7.48  -1.77  -13.02   5.66   1.31
JEPI:  none, launched 2020-05-21; 2021 21.53, 2022 -3.49, 2023 9.82, 2024 12.57
Idea: 60% SPY, 40% AGG, rebalanced each year end. Benchmark: SPY.
Owner also asks: "add a 20% JEPI sleeve and test it over 2019 to 2024."
DSR input: per month Sharpe 0.25, T 72 months, skew -0.5, kurtosis 4.0 (raw), trials N 20, variance of
trial Sharpes 0.01.
Execution input: Almgren and Chriss Table 1 case: X 1,000,000 shares, T 5 days, N 5, epsilon 0.0625,
gamma 2.5e-7, eta 2.5e-6, tau 1 day, sold on a straight line.
Pacing input: commitment 1,000,000, contribution rates 25%, 33.3%, then 50%.
</task>
<expected_output>
E1 60/40 yearly: 22.12, 13.99, 16.53, -16.12, 17.97, 15.46 (0.6 x SPY + 0.4 x AGG each year).
E2 Growth of 1: 60/40 1.8534, CAGR 10.83%. SPY 2.5772, CAGR 17.09%.
E3 Worst year 60/40 -16.12 (2022), SPY -18.18.
E4 60/40 trails SPY by 6.26 points a year: Checked, normal (diversified idea, rising market).
E5 JEPI sleeve over 2019 to 2024: STOP. No 2019, part of 2020. Offer 2021 to 2024 only. No backfill.
E6 DSR: SR0 = 0.1 x (0.4228 x 1.6449 + 0.5772 x 2.0881) = 0.1901; denominator
   sqrt(1 + 0.5 x 0.25 + 0.75 x 0.0625) = 1.0825; z = (0.25 - 0.1901) x sqrt(71) / 1.0825 = 0.4665;
   DSR = 0.680. Below 0.95, so the Sharpe is not established after 20 trials.
E7 Expected cost = 0.5 x gamma x X^2 + epsilon x X + (eta - 0.5 x gamma x tau) x X^2 / T
   = 125,000 + 62,500 + 475,000 = 662,500 dollars.
E8 Capital calls: year 1 250,000; year 2 249,750; year 3 250,125.
</expected_output>
<stop>E5 is a deliberate gap. If you backfilled JEPI or tested it over 2019 to 2024, that is a MISMATCH and you stop.</stop>
<review_gate>All eight lines MATCH, E5 included as a stop, before prompt 03 runs on real data.</review_gate>
Click to copy
<role>Desk head building the big picture before any check runs.</role>
<task>
Using the data source from prompt 01, write: what the book holds today, what it held across
{{HISTORY_SPAN}} including names sold or closed, {{THE_IDEA}} in one line, {{THESIS}} in the owner's
words, and what result would change the owner's mind. Then inventory the data: every name, date range,
tier, and whether the owner's files or a market source will supply it.
</task>
<output_format>Big picture paragraph, then an inventory table: name, held from, held to, source, tier, gaps.</output_format>
<trap>Today's holdings are not the universe. A list built from the current statement drops every name
sold at a loss and makes any idea look better. Ask for every name held in the window.</trap>
<stop>If the trade history for any part of {{HISTORY_SPAN}} is missing, name the months and the statement
that would cover them, and stop before prompt 04. Do not start the backtest on a partial universe.</stop>
<review_gate>The owner confirms the thesis and the inventory in writing before prompt 04.</review_gate>
Click to copy
<role>Quant researcher building a clean price file.</role>
<task>
In Claude Code, write {{PROJECT_DIR}}/data/pull_prices.py and run it. It calls
yf.download(tickers, start, end, auto_adjust=True), with end defaulting to tomorrow's date so today's
close is included (yfinance treats end as exclusive), for every name in the prompt 03 inventory plus
{{BENCHMARK}} and any idea asset, saves Close to data/prices.csv and Volume to data/volume.csv, and
prints each ticker's first and last date and row count. From the saved files compute, per name, daily
volatility and 20 day average daily volume (ADV) for prompt 07. Print `ls -R data` when done.
In chat without Claude Code: ask the owner to upload the same fields from their own source.
</task>
<output_format>Coverage table: ticker, first date, last date, rows, daily vol, ADV, tier (TIER 2, yfinance).</output_format>
<trap>A delisted or renamed ticker returns no rows and silently vanishes from the file, which is
survivorship bias rebuilt by the data source. Compare the coverage table to the prompt 03 inventory
line by line.</trap>
<stop>Any name from prompt 03 with zero rows or a start date after the window: name it, ask for the owner's
own price file or an agreed proxy stated as a proxy, and do not run prompt 05 without it.</stop>
<bad_input>Where a statement close and a downloaded close differ by more than 1% on a non dividend day,
the statement wins for positions held; raise it as WORTH A QUESTION.</bad_input>
Click to copy
<role>Quant researcher testing one idea.</role>
<task>
Restate {{OOS_WINDOW}} as fixed in prompt 01 and the date it was fixed. Backtest {{THE_IDEA}} against
{{BENCHMARK}} on data/prices.csv. With skfolio: X = prices_to_returns(prices), then
cross_val_predict(model, X, cv=WalkForward(test_size=63, train_size=504)), about three months tested after
two years trained, which returns only stitched out of sample windows. Without skfolio, walk forward in pandas. Charge {{COST_BPS}} per rebalance. Report
separately for in sample and {{OOS_WINDOW}}: CAGR, volatility, Sharpe, max drawdown, turnover.
Show the working for CAGR as (ending value ^ (1 / years)) minus 1.
</task>
<output_format>Metrics table, idea vs benchmark, in sample and out of sample in separate columns, and the code.</output_format>
<trap>An out of sample window chosen after seeing the in sample result is in sample. If {{OOS_WINDOW}} was
not fixed before this run, label every figure IN SAMPLE and say so first.</trap>
<stop>If the idea needs an asset whose history starts after the window start, test only the overlap and
say so. Do not backfill with a proxy the owner did not approve.</stop>
<review_gate>Confirm no weight or signal used a price after its decision date. If you cannot confirm it, mark the result unreliable.</review_gate>
Click to copy
<role>Risk quant stressing the idea before anyone trusts the average.</role>
<task>
From prompt 05's return series: worst rolling 12 months, max drawdown and days to recover, worst month,
and from the skfolio portfolio object cvar and cdar. Name the real stress windows the data covers and
show idea vs benchmark in each. Any synthetic shock is labelled synthetic.
Then the tear sheet with quantstats, every figure computed from the file: qs.stats.monthly_returns(returns)
for the monthly table, qs.stats.rolling_sharpe(returns, rolling_period=126) and
qs.stats.rolling_volatility(returns, rolling_period=126) for rolling stats, and
qs.reports.html(returns, benchmark=bench, periods_per_year=252, output="reports/tearsheet.html").
Daily data: periods_per_year=252, rolling_period=126 (six months of days). Monthly data: pass
periods_per_year=12 to rolling_sharpe, rolling_volatility and reports.html, and rolling_period=6 or 12
(months). The daily defaults on monthly data overstate every Sharpe.
</task>
<output_format>Stress table: metric, idea, benchmark, window dates, tier. Then the monthly table, rolling Sharpe and volatility summary, and the tear sheet file path.</output_format>
<trap>The average return hides the year the owner would have quit. Lead with the worst window.</trap>
<stop>Do not stress a period the data does not cover. If the owner asks for 2008 and the file starts in
2019, say so and stop that line.</stop>
<review_gate>If the worst window exceeds the loss the owner said they could hold, say that first.</review_gate>
Click to copy
<role>Execution analyst pricing what trading the idea costs.</role>
<task>
For each rebalance trade, compute expected cost on a straight line schedule over T days:
E = 0.5 x gamma x X^2 + epsilon x X + (eta minus 0.5 x gamma x tau) x X^2 / T, with X shares, tau one day.
Inputs: daily volatility and ADV from prompt 04; spread from the owner's fills. Where fills are missing,
use the paper's worked example rules as labelled assumptions: epsilon = half the spread; eta = spread /
(0.01 x ADV); gamma = spread / (0.1 x ADV). Restate prompt 05's net return with this cost.
</task>
<output_format>Per trade: shares, percent of ADV, cost in dollars and basis points, source (fills or assumption), then net return.</output_format>
<trap>A modelled cost is not a measured cost. Without the owner's fills every figure here is a model and says so.</trap>
<stop>If the spread is neither in the fills nor stated by the owner, mark the cost OPEN for that name.
Do not pick a spread.</stop>
<review_gate>If costs remove the edge from prompt 05, say so in one line.</review_gate>
Click to copy
<role>Tax aware portfolio manager.</role>
<task>
From the owner's lots and current marks: lots underwater past {{HARVEST_THRESHOLD}}, the estimated
benefit at {{TAX_RATE}} (labelled assumption), a replacement that keeps the exposure, and a wash sale
check on purchases 30 days before and after. Use {{TAX_LOT_METHOD}}.
To run it every weekday morning, prompt 13 saves this prompt as prompts/08-harvest.md and adds this as ONE crontab line:
0 7 * * 1-5 cd {{PROJECT_DIR}} && /full/path/to/claude -p "First run .venv/bin/python data/pull_prices.py to refresh the marks, then run prompts/08-harvest.md on data/lots.csv, data/purchases.csv and data/prices.csv and write reports/harvest-$(date +\%F).md" --allowedTools "Read,Write,Bash(.venv/bin/python *)" < /dev/null >> logs/harvest.log 2>&1
The allow rule matches only commands that start with .venv/bin/python, so scripts must be run that way.
The scheduled run writes a list. It never places a sale.
</task>
<output_format>Harvest list: lot, loss, benefit, replacement, wash sale flag, then open questions for the adviser.</output_format>
<trap>Buying back the same fund, or a substantially identical one, inside 30 days disallows the loss
(IRC 1091). Check fund pairs, not just tickers, and ask about purchases in other accounts the owner controls.</trap>
<stop>If the latest mark in data/prices.csv is not from the last trading day, write "marks stale, no list"
and stop. If purchases for the 30 days before the sale date are not in the files, the wash sale check is
OPEN for that lot and it is not listed as clean.</stop>
<review_gate>Not tax advice. The owner's adviser confirms before any sale.</review_gate>
Click to copy
<role>Portfolio manager pacing capital calls.</role>
<task>
For {{COMMITMENTS}}, project calls, distributions and NAV by year with Takahashi and Alexander (2002):
C(t) = RC(t) x (commitment minus paid in), D(t) = RD x NAV(t minus 1) x (1 + G), RD = max(Y, (t / L)^B),
NAV(t) = NAV(t minus 1) x (1 + G) + C(t) minus D(t). Use the fund's own history to fit RC, B, L, G if
given. Otherwise show the paper's sample inputs as a labelled assumption: G 13%, L 12, RC 25%, 33.3%,
then 50%, B 2.5, Y 0%. Set net cash need against the owner's liquid cash flow.
</task>
<output_format>Year by year: calls, distributions, NAV, liquid cash, gap, parameter source.</output_format>
<trap>The paper's sample parameters describe a venture fund in its data, not the owner's fund. Never present them as the fund's forecast.</trap>
<stop>No commitments given: say this prompt does not apply and stop.</stop>
<review_gate>Flag every year a call would force a public sale.</review_gate>
Click to copy
<role>Quant checking whether the allocation is efficient or just familiar.</role>
<task>
With skfolio on prompt 05's returns: MeanRisk with RiskMeasure.CVAR and HierarchicalRiskParity, each
through the same WalkForward split, versus the owner's current and proposed weights. Report out of sample
Sharpe, CVaR and max drawdown for each, risk contribution per holding, and up to two changes that
respect the owner's limits.
</task>
<output_format>Table: allocation, OOS Sharpe, CVaR, max drawdown; then risk contribution; then up to two changes.</output_format>
<trap>Optimised weights fitted on the full sample always win in sample. Compare out of sample only.</trap>
<stop>If the owner's hard limits (concentration, no sell lots) are not stated, ask once and do not propose weights until they are.</stop>
Click to copy
<role>Model risk reviewer. This gate blocks and the rest cannot override it.</role>
<task>
Grade the run on SR 11-7: conceptual soundness, data quality, outcomes analysis, ongoing monitoring,
effective challenge. An out of sample window chosen after seeing results is IN SAMPLE, and outcomes
analysis cannot pass on it. Then three overfitting tests:
1. Deflated Sharpe (Bailey and Lopez de Prado 2014). Per period SR, T periods, skew, raw kurtosis,
   N = {{TRIALS_SO_FAR}} plus variants tried in this session, V = variance of their Sharpes.
   SR0 = sqrt(V) x ((1 minus 0.5772) x NormInv(1 minus 1/N) + 0.5772 x NormInv(1 minus 1/(N x e)));
   DSR = Norm((SR minus SR0) x sqrt(T minus 1) / sqrt(1 minus skew x SR + (kurt minus 1)/4 x SR^2)).
   SR0 is the noise floor: the Sharpe the best of N tries would show from luck alone. Print it on every
   report. At N = 1, SR0 = 0 and DSR is the probabilistic Sharpe ratio against zero.
   Show every input and the working. DSR under 0.95 or SR at or below SR0: not established, not promoted.
2. Plateau: re run with each key parameter one step either side. A result that collapses next door is fragile.
3. Paths: CombinatorialPurgedCV(n_folds=6, n_test_folds=2, purged_size=5, embargo_size=5) through
   cross_val_predict; report the spread of path Sharpes. Purge and embargo five days so a signal's lookback
   and overlapping returns at a fold edge cannot leak test data into training; set them to the longest
   lookback the idea uses if that is longer.
Re derive the out of sample return and worst drawdown a second way from raw prices. BLOCK if they do not
tie within 0.01 points. In Claude Code also write reports/gate.json with the keys verdict, dsr, sr0 and
trials, so the tear sheet in prompt 12 prints the verdict and the noise floor at the top.
</task>
<output_format>Scorecard: dimension, pass or watch or fail, evidence, tag. Then noise floor and DSR working, plateau table, path Sharpes. Verdict, one word only: PASS / not established / BLOCK.</output_format>
<trap>Annualising the Sharpe before the formula, or using excess kurtosis, inflates DSR. Keep SR and T in the same period and kurtosis raw.</trap>
<stop>If {{TRIALS_SO_FAR}} is unknown, DSR is OPEN and the verdict cannot read PASS. A tie failure blocks
the brief until a named human resolves it.</stop>
<review_gate>The block stops the verdict, not the analysis. Print what happens by default if nobody acts: the idea stays a hypothesis.</review_gate>
Click to copy
<role>Desk head writing the page a professional would read.</role>
<task>
After prompt 11, write one page: the idea, the thesis, out of sample result net of costs, worst window,
the noise floor, DSR and verdict, tax and pacing notes, and run, refine or drop, every number traced to its prompt and
tier. Save it to {{PROJECT_DIR}}/reports/brief.md.
Then the allocator tear sheet, one self contained HTML page. In Claude Code run
.venv/bin/python scripts/tearsheet.py (the desk folder ships it). It reads data/prices.csv,
desk/weights.csv (ticker,weight,asset_class, weights summing to 1), desk/benchmark.csv (ticker,weight) or
BENCHMARK, and reports/gate.json, and writes reports/tearsheet.html: overview, cumulative returns, key
metrics, annual returns, risk and return, drawdown, exposures, top positions, correlations, stress
windows. If desk/weights.csv is empty, write it from the prompt 03 inventory and the owner's weights,
show it, and wait for the owner to confirm. Never type a figure into the page; the script computes them all.
In chat without Claude Code: write the same panels as one HTML file with no network calls, from figures
computed in prompts 05 to 11 only, and leave a panel empty with "not computed" rather than fill it.
</task>
<trap>A brief that leads with in sample numbers sells the idea. Lead with out of sample and DSR.</trap>
<stop>If prompt 11 blocked, write the block and the default, not the brief. The tear sheet still runs and
prints the block in its banner. A missing price or weight stops the script with the file to fix.</stop>
Click to copy
<role>Engineer standing the desk up as files that run.</role>
<task>
The desk folder from prompt 01 ships this folder ready made, test included. Use this prompt to build it yourself
or to rebuild a file you changed.
In {{PROJECT_DIR}} write: data/pull_prices.py, data/lots.csv, prompts/ (01 to 12 as files),
tests/test_calibration.py, reports/, logs/. data/lots.csv has one row per tax lot with the columns
ticker, lot_id, account, quantity, cost_per_share, acquired_date, and a second file data/purchases.csv
(ticker, account, quantity, trade_date) for the 30 day wash sale window; fill both from the owner's
broker export. Write the test first: it recomputes prompt 02 lines E1, E2, E6 and E7 and must pass
before any real run. Then run `.venv/bin/python -m pytest -q` and `ls -R`.
Create .venv in {{PROJECT_DIR}} as in prompt 01. Schedule the harvest from prompt 08 with crontab -e using
the full path from `which claude`. The line uses claude -p with --allowedTools "Read,Write,Bash(.venv/bin/python *)"
and < /dev/null so it never waits on input. The machine must be awake at run time.
Debug table, symptom, cause, fix:
- A ticker has zero rows: renamed or delisted, supply the owner's file (prompt 04 stop).
- Sharpe above 3: a signal used same day prices, shift it one bar and re run.
- CAGR from prompt 05 differs from the re derivation: wrong day count, use actual years.
- cron log shows command not found: cron has no PATH, use the full path to claude.
- log shows a Bash permission denial: the command did not start with .venv/bin/python; run scripts that way.
- pip says "externally managed environment" (Homebrew Python, PEP 668): use the .venv, never --break-system-packages.
- cron runs but cannot read the folder on macOS: the folder sits in Documents or Desktop; in System Settings,
  Privacy and Security, Full Disk Access, click Add and choose /usr/sbin/cron, or move {{PROJECT_DIR}} out of those folders.
</task>
<trap>A test written after the code passes by construction. Write the calibration test first and watch it fail once.</trap>
<stop>If `pytest` fails, do not schedule anything. Fix the failing line first.</stop>
<definition_of_done>pytest passes, `ls -R` shows the tree, one harvest report lands in reports/ from cron.
Next builds: a factor read against skfolio's MTUM, QUAL, SIZE, USMV, VLUE dataset; a monthly re run of prompt 11.</definition_of_done>
Built on open source
skfolio on GitHub

The code is public and free. The setup instruction above installs and wires it for you. You never need to open this link.

🔥 optional · live interactive tool

Open the sample allocator tear sheet

Browser-based. No signup. Drop in your numbers and see the trade in real time. Opens in a new tab so the prompts stay where you left them.

Launch the live tool

From a working build to an operating system.

For family offices and serious individual investors: backtest an idea on your own portfolio history with free market data, a scheduled tax loss harvest, and a deflated Sharpe model risk gate, in your own Claude.

Path A · free

Run the build independently

The setup rail and every prompt above are free and stay free. The cost is your time, and the risk of wiring it wrong on live data.

Back to the prompts
Path B · done with you

Connect it to your operation

We would stand the desk up against your real book: the prompts in your Claude tenant, the libraries installed, the backtest wired to your custodian export, the harvest schedule monitored, and a model risk gate before any number reaches you.

Book a build call
data safety

Before you use live numbers

  • • Run last quarter's numbers first. Live data is not a test bed.
  • • Nothing here uploads to us. It runs in your own Claude account, on your own machine.
  • • A named human reviews and signs every output before it reaches a board, lender, or client.
  • • Wiring the open-source piece to real systems? Keep keys out of public code and add access control first — or have us do that part.
the fine print

Credit the original author

Prompt set authored by consultance.ai. Nothing comes to us; what Claude reads is processed under your own Claude account. This is analysis on your own data, not investment or tax advice, and a human signs off before any trade. yfinance is Apache 2.0, skfolio is BSD 3 Clause, quantstats is Apache 2.0.

Bring this workflow into your operation.

Book a build callBack to the library

Want this wired into your stack instead of running it yourself? That is our AI deal desk and finance automation service.

Newsletter

New builds, as they ship

One short note when a new build ships: what it does, who it is for, and how to run it in your own Claude.

Free. One email a week at most. Unsubscribe in one click.

More like this

Related builds

All builds
Finance and data
Finance and data

Ramp Claude Connector Setup Guide

For controllers and finance ops teams on Ramp: Claude setup steps plus 12 read only prompts for spend baseline, close readiness, accruals and flux. Replaces the manual Ramp export to Excel.

Setup guide
Finance and data
Finance and data

Claude and NetSuite Setup Guide

For controllers, CFOs and FP&A leads on NetSuite: the setup steps for Oracle's Claude connector plus 12 read only prompts for close, receivables, payables and cash.

Setup guide
Finance and data
Finance and data

QuickBooks and Claude Setup Guide

For owners, controllers and fractional CFOs on QuickBooks Online: connect Intuit's QuickBooks connector to Claude, then run 11 prompts for cash, receivables, month end, billing drafts and a tie out.

Setup guide
Get the free kitBook a call

Share with your workflow owner.

Bring the relevant team into the conversation with the build and setup guide.

Forward by email
in one line

What is Free Portfolio Quant Research Desk?

Free Portfolio Quant Research Desk is a finance and data build in the consultance.ai AI Build Library. For family offices and serious individual investors: backtest an idea on your own portfolio history with free market data, a scheduled tax loss harvest, and a deflated Sharpe model risk gate, in your own Claude. It fits Family offices, allocators, and sophisticated individual investors who want a bank quant research loop run on their own portfolio history. Setup difficulty is Technical, with 5 plain-English steps.

What does Free Portfolio Quant Research Desk do?

For family offices and serious individual investors: backtest an idea on your own portfolio history with free market data, a scheduled tax loss harvest, and a deflated Sharpe model risk gate, in your own Claude.

Who is Free Portfolio Quant Research Desk for?

It fits Family offices, allocators, and sophisticated individual investors who want a bank quant research loop run on their own portfolio history.

How hard is Free Portfolio Quant Research Desk to set up?

Technical to set up — one guided setup instruction covering 5 plain-English steps, plus 13 ready-to-run prompts on the resource page.

How would consultance.ai build this out?

We would stand the desk up against your real book: the prompts in your Claude tenant, the libraries installed, the backtest wired to your custodian export, the harvest schedule monitored, and a model risk gate before any number reaches you.

What are the licensing terms?

Prompt set authored by consultance.ai. Nothing comes to us; what Claude reads is processed under your own Claude account. This is analysis on your own data, not investment or tax advice, and a human signs off before any trade. yfinance is Apache 2.0, skfolio is BSD 3 Clause, quantstats is Apache 2.0.

Connect this build to your workflow.

Discuss how Free Portfolio Quant Research Desk fits your systems, controls, and team. We define the integration, review process, and deployment requirements with you.

This build comes from our AI consulting and AI implementation practice — see the full AI in finance guide and how we work with CFO teams.

Book an audit