AssayIndependent adversarial validation
Report A-0001 · rev. 3Subject: WILL 4.0 17 Aug 2026 · engine 501696cSelf-audit — no external client

Strategy autopsy: WILL 4.0

9 OF 21 KARATS

ASSAY Karat

One karat for every checkable claim that survives its attack. It does not measure future returns and it certifies nothing: it measures how much of what the strategy claims is still standing after scrutiny.

All 21 karats were contested: the engine's seven attacks ran against the record and the configuration, coverage 7 of 7. Nine survive. That full coverage is not a merit of the record: it is a consequence of H-07. A record with observed exit prices does not allow all seven attacks to run — one of them abstains in the face of real execution, and rightly so — so the ceiling for an honest record is 6 of 7 and 18 karats. WILL 4.0 reaches 7 of 7 because its exits are computed. Measured on 20 August 2026, after this report was issued. The ceiling is 21 and not 24 because the board defines eight roles and the engine covers five: the remaining three require mechanism and pre-registration this material does not contain, and they are not scored as failures — they leave the denominator.

A high karat count without coverage means nothing — it is obtained by not attacking. That is why both figures are always published together. Formula fixed in writing in QUILATES.md before being applied.

With the exit defect corrected, the strategy produces a profit factor below 1 in 12 of 14 pair-window combinations and −489.59 USD aggregated over 353 trades. And the record behind those figures does not describe execution: the exit prices are derived, not observed. Of the 21 karats contested, 9 survive — the figures are reproducible from the files and the declared geometry is internally coherent. Nothing else survives.

The 14 result sets were generated on 2 Aug 2026 between 09:28 and 09:29, two minutes after the exit_logic.py fix was saved. They are not the original run: they are the counterfactual.

Before reading the findings

What this report proves and what it does not

Everything marked PROVEN ON DISK rests on a file that exists and a command that regenerates it. Everything marked REPORTED comes from the manager's own account and has not been verified in this audit; it appears because it gives context, not because it is demonstrated.

Seven of the auditor's own hypotheses died against the disk during this session, and they are worth writing down because they are the argument for the method:

1. "32 directories in projects/ are 32 research threads with a high cumulative trial count" → false. The weight sits in four directories; the rest are barely used.
2. "The four config_4_0.yaml.bak_* and three exit_logic.py.bak_* files are a parameter sweep" → false. Three backups are byte-for-byte identical; there was a single real change.
3. "The trades.csv header is offset from the rows" → false. 12 fields in both.
4. "The rows with a well-formed date are the signature of the H-01 global stop" → false. All seven are part_a, none part_b.
5. "Grouping by (entry_date, pair) yields the real trades" → false. It returns 398 because it uses the column with no entry data. The correct count is 353.
6. "The bar index reconstructs the date from the same origin in both windows" → false. It gets 410 of 410 right in 2023–2025 and 241 of 241 wrong in 2021–2022, which has a different origin per pair.
7. "The cross-pair correlation of results will resemble the 0.665 of prices and multiply the adjustment by ~2.2" → false. It is 0.043 and 0.088; the adjustment multiplies by 1.12 and 1.24. The attack assumed to be the strongest turned out to be the weakest against this strategy.

And two arithmetic corrections, published rather than buried: the count of rows with the wrong type was first given as 593 and is 651; and it was claimed that H-05 invalidated the counterfactual table, which proved false when measured. A report that does not publish its own errors cannot be audited.

Reconstructed from timestamps · the project uses no version control

What happened on 2 August

The bot directory is not a git repository. Even so, the full working session can be reconstructed from the file system, which is where the real trace survives in most small quantitative projects.

TimeArtefactReading
08:55config_4_0.yaml.bak_feescopy taken before touching fees
09:09config_4_0.yaml.bak_btsecond configuration copy
09:13exit_logic.py.bak_stopcopy before the single real logic change
09:15exit_logic.py.bak_sweepdefensive copy — identical to the final file
09:21exit_logic.py.bak_rrdefensive copy — identical to the final file
09:27exit_logic.pyglobal stop relocated
09:28–09:2914 × metrics.json + trades.csvfull re-run
09:29config_4_0.yamlfinal configuration
Regenerable with ls -l projects/will/core/. Timestamps verified directly for the BTC results in both windows; the rest are assumed to belong to the same batch by proximity of generation and remain to be confirmed file by file.

Ten findings · nine proven on disk, one reported

Findings

H-01

The global stop was unreachable

Proven on disk

If part_b_active was false, the function returned before evaluating the hard stop. A trade with trend strength below the minimum that never reached target_a had no way to close: it stayed open indefinitely. And since the results record only counts trades with an exit, those never appeared in any computation. The patch's own comment puts the impact at −169 R.

$ diff exit_logic.py.bak_stop exit_logic.py
70,73d69
<     # PART B — dynamic stop
<     if not part_b_active:
<         return exits if exits else None, position
77a74,85
>     # STOP GLOBAL — aplica aunque Part B no esté activa.
>     # Sin esto, un trade con trend_strength < min y sin tocar target_a
>     # queda abierto indefinidamente (bug forced_exit -169R).
>     if not part_a_closed and bar_low <= hard_stop:
>         exits.append(("part_a", hard_stop))
>         exits.append(("part_b", hard_stop))
>         return exits, None
16 lines of difference. Prior state preserved in projects/will/core/exit_logic.py.bak_stop (09:13).
H-02

There is no record of the entry time

Proven on disk

The entry_date column does not hold the entry time: it holds the exit bar index, duplicating the adjacent column. Checked across both windows without a single exception — 410 of 410 rows in 2023–2025 with origin 1 Jan 2023 at 00:00 UTC, and 241 of 241 in 2021–2022 with a single origin per pair, matching each asset's first available bar. In total, 651 of 701 rows have no entry data.

# solve for the implicit origin: origin = exit - index x 1h
2023_2025  origen 2023-01-01 00:00   match=410  fail=0
2021_2022/BTC   n= 27  origins=1  →  2021-01-01 06:00
2021_2022/AVAX  n= 40  origins=1  →  2021-03-05 10:00  # listing start
2021_2022/SOL   n=  4  origins=1  →  2021-08-04 10:00  # listing start

A consequence beyond formatting. Without an entry time, trade duration cannot be computed; without duration there is no time exposure, no real turnover, and no correct funding cost on perpetuals. The execution cost floor depends on annual turnover: on these files, that figure cannot be computed. The data is only recoverable if the original price panel has been kept.

H-03

The counterfactual is negative

Proven on disk

With the H-01 defect already corrected, the strategy loses money in 12 of the 14 pair-window combinations. The two cases above unity support no conclusion: BNB gives 1.008 — indistinguishable from zero — and SOL gives 1.326 over 18 trades, with no statistical power to claim anything.

Full table in the next section. Regenerable by reading the 14 metrics.json files.
H-04

No version control, and a parallel history

Proven on disk

The bot directory is not a git repository, so there is no record of how many configurations were tried or in what order. The trace survives indirectly: five major versions in versions/, and 12 oos_trades files in an auxiliary directory with subversions reaching v10 on the same asset and the same out-of-sample window.

This is a crude lower bound on the trial count, not the count. A script may have run once or two hundred times, and an overwritten file leaves no trace. Without that number, the multiple-testing-corrected statistic cannot be computed rigorously — and that, not the sign of the result, is the underlying methodological problem.

$ git log --oneline
fatal: not a git repository
$ ls versions/
2_8   3_0   3_3   4_0   will_2_8
$ ls ChatGPT/ | grep -c oos_trades
12   # subversions up to v10, same asset, same sample
H-05

The unit of analysis is not the trade

Proven on disk

Each trade is recorded in two rows, one per position leg (part_a and part_b), and the metrics computation treats every row as an independent trade. Across the 14 files, total_trades equals the row count and never the trade count. The real trades are 353, not the 701 reported.

The two legs of one trade are not independent observations: they share entry, direction and instrument, and the second is the continuation of the first. It is the effective sample size problem applied inside the unit of analysis.

$ for f in */*/trades.csv; do
    a=$(awk -F, 'NR>1 && $5=="part_a"' "$f" | wc -l)
    t=$(tail -n +2 "$f" | wc -l)
    echo "$f part_a=$a rows=$t"
  done
2023_2025/BTC/trades.csv   part_a=52  rows=103  reports=103
2023_2025/ETH/trades.csv   part_a=41  rows=81   reports=81
2021_2022/AVAX/trades.csv  part_a=21  rows=42   reports=42
... 14 of 14 report rows, none reports trades

Scope of the effect, measured and not assumed. The profit factor turns out to be insensitive to this aggregation, being a ratio of sums that do not change when grouped: BTC 2023–2025 moves from 0.489 to 0.482 and six of the fourteen do not move at all. The counterfactual table holds. What is inflated is anything that scales with sample size — the t statistic, the Sharpe ratio and any significance test.

Measured factor, adding cross-pair dependence. Rebuilding the daily result series per pair from the exit column, the mean cross-pair result correlation across the seven pairs is 0.043 in 2021–2022 and 0.088 in 2023–2025 — far below the price correlation, because each pair enters and exits at different moments. The resulting design factor is 1.26 and 1.53. Combined with the double counting of legs, the total inflation of the significance statistics is 1.59 in the first window and 1.75 in the second.

Reliable count: rows with part=part_a. Grouping by (entry_date, pair) returns 398 and is wrong, because that column is the one H-02 documents as having no entry data.
H-07

The record describes the design, not the execution

Proven on disk

The r_multiple column takes four values across the whole sample: the design's three exit levels plus the second leg's target. Solving for the risk unit R from each leg of the same trade, 293 of 293 pairs give a 0.0000 % discrepancy. Two exits hours apart cannot give the same R to the last decimal if the prices were real fills.

# solve for R from each leg and compare within the trade
r_multiple distinct values: 4  →  -0.7  -0.42  +1.2  +2.0
comparable pairs: 293   max discrepancy: 0.0000%

Consequence. The degradation from slippage, rounding and fees is not small: it is unobservable with this record. The manager cannot measure what costs him most, and does not know that he cannot. Any break-even computed from these figures is understated by construction.

H-08

Zero dispersion inside every exit cluster

Proven on disk

Measuring dispersion inside the dominant cluster instead of over a fixed window that mixed two design levels: 5 of 5 clusters with 0.0000 % dispersion across 393 trades, in both files. Eleven independent clusters, each with a single distinct value.

# observed clusters and their cardinality
2021-22:  -0.7(88)  -0.42(5)  +1.2(30)  +1.6(8)  +2.0(12)
2023-25:  -0.7(152) -0.42(11) +1.2(55) +1.6(9) +2.0(22)
# a real execution record produces dispersion: tick, rounding, fees
The detail that settles it: nominal loss −0.700R against an observed −0.685R. The observed loss is better than the nominal stop, which is impossible with real slippage. H-07 and H-08 say the same thing by independent routes: that is corroboration, not duplication.
H-09

It loses before paying fees

Proven on disk

The mean gross effect is −0.4258 against a cost floor of 0.5842 per trade. The observed ratio is 0.73: fees take 137.2 % of the gross. There is no effect from which to deduct costs.

# gross measured from prices and size, not reconstructed
mean gross  -0.425841    cost floor  0.584161
ratio  0.73
Terminal. The verdict depends on no other finding: this one alone invalidates what is claimed.
H-10

The published configuration does not govern the exits

Proven on disk

Comparing config_4_0.yaml against the levels the record produces: 65.0 % of trades (93 of 143) end at a level the configuration neither declares nor allows to be derived. The targets match exactly; the entire loss geometry sits outside the config.

# declared config against observed record
declares  part_a_target_r +1.2   part_b_target_r +2.0
          part_b_stop_loss_r -0.5   part_b_be_buffer_r +0.3
observes  +1.2(30)  +2.0(12)   declared
          -0.7(88)  -0.42(5)   orphans: neither declared nor derivable
Two more findings from the same comparison: part_b_stop_loss_r and part_b_be_buffer_r are declared and never executed; and the assumed cost went from 0.002 to 0.0005 between config_3_0 and config_4_0 — divided by four. That is not a change of strategy: it is a change to what the strategy has to clear in order to look viable.
H-06

ETH time misalignment

Reported — not verified here

The manager documents a six-hour offset in the ETH series relative to the rest of the panel. This audit has not checked it. What does appear on disk is four scripts dedicated to the problem — check_eth_align.py, diag_eth.py, fix_eth_data.py, refix_eth.py — all dated 31 July, which is consistent with the account but does not prove it. Verifying it requires running the cross-correlation over the original panel.

Outstanding. Same status for the other two reported artefacts: the 1H→15m merge carrying the future bar forward, and fees applied from the wrong venue.

14 pair-window combinations · result with H-01 corrected

Counterfactual

WindowPairReal tradesProfit factorSharpeResult USD
2021–2022AVAX210.649−1.178−20.92
2021–2022BNB181.008+0.044+0.34
2021–2022BTC150.415−1.990−29.40
2021–2022ETH300.552−1.928−39.67
2021–2022LINK230.573−1.590−27.37
2021–2022SOL20.000−1.979−8.02
2021–2022XRP210.631−1.199−21.42
2023–2025AVAX340.356−2.740−69.12
2023–2025BNB320.366−2.587−66.54
2023–2025BTC520.489−2.548−86.72
2023–2025ETH410.689−1.210−38.38
2023–2025LINK240.644−1.094−24.49
2023–2025SOL91.326+0.471+6.38
2023–2025XRP310.369−2.574−64.26
14 combinations35312 of 14 < 112 of 14 < 0−489.59

Three engine failures, each with its commit

What ASSAY got wrong

The seven hypotheses in the opening section are the auditor's errors while reasoning. These three are the engine's errors while measuring, and they are published for the same reason: a method that only shows its hits cannot be checked. Each has the commit that corrects it.

R-1

A false terminal finding, already published in a report

Retracted

The engine accused WILL 4.0, at terminal severity, of not reaching its own break-even. It counted each leg as an independent trade, and splitting every winner across two different levels while both losing legs exit at the same one sinks the hit rate. All of the bias ran in the same direction.

# the same sample, two units of count
legs        (2021-22)  n=258  hit rate 28.3%  break-even 32.8%  FIRES
R per trade          n=143  hit rate 35.0%  break-even 32.0%  does not fire
legs        (2023-25)  n=443  hit rate 27.3%  break-even 32.9%  FIRES
R per trade          n=250  hit rate 34.8%  break-even 32.2%  does not fire
Corrected in 63aedc1. Rule derived: currency is extensive and adds up; the risk multiple is intensive and must be weighted by leg size. Adding R gave −1.4R on a −0.7R stop, a level the design does not contemplate.
R-2

The configuration attack accused every honestly executed record

Retracted

100 % of trades were flagged by the noise of execution itself, not by the configuration: the attack could not tell a dishonest record from a merely executed one. We checked whether adjusting the criterion resolved it, and no adjustment separated the defect from the noise.

Corrected in e942303: the attack abstains and says so on records it cannot judge fairly, instead of scoring them. The criterion that does separate the two cases is not published: a published threshold tells a dishonest seller exactly how far to move a record to clear it.
R-3

The tail was measured in currency: it sorted by position size

Retracted

The distribution analysis took the 90th percentile in money while the rest of the attack measured in risk multiples. In money, the tails are the biggest bets, not the best trades.

# tails identified by unit
in currency  15 tails   in risk multiples  20 tails   overlap  8
# and in the right unit the 90th percentile falls on +2.0R, a design level
# the "tails" would be every trade that reached the larger target
Corrected in 501696c. The code already had the guard written for this case and it could never fire, because in currency no continuous value repeats. With the unit corrected the attack abstains: an intended outcome is not a tail.

Investment committee

Fail

What this report does not say

It does not say there is no strategy there. It says that the results the code itself produces, once the exit defect is removed, are negative in 12 of 14 cases, and that the trial count cannot be reconstructed from the available information — so no significance statistic on this strategy can be rigorously corrected for multiple testing.

Three of the four artefacts the manager documents have not been verified in this audit and are reported as claims, not findings. Verifying them requires running the pipeline over the original panel, work that has not been done.

ASSAY finds problems; it does not certify that a strategy works and it issues no return forecasts. A report that finds nothing is an honest result and is delivered all the same.

Verifiable appendices

How to check this

All ten findings rest on files that exist and commands that regenerate them. The last four — H-07 to H-10 — are produced by the ASSAY engine, and their full output lives in a generated report.

The three reports that used to accompany this document — A-0041, A-0042 and A-0041-EN — were withdrawn from circulation on 20 August 2026. The current WILL 4.0 report is informe_A-0047-EN.html, generated with the engine of that date: same verdict and the same nine karats, 120 commits later.

Every report states the engine commit it was produced with. A report that does not state which version generated it is not reproducible, and reproducibility is exactly what ASSAY sells. This document is written by hand — the engine cannot produce the seven dead hypotheses or the three retractions — and its figures were verified against that same commit.