SPECIMEN
Sample memo and method
Method
How the figures are computed: the scripts and data, the glossary, the export guide for a firm’s own records, and the client script, partner_disposition.py.
Specimen memo, computed on public data
- Question
- In this panel, what share of traders realised gains more readily than losses, counting every day a position was held?
- Figure
- 76.1% (3,547 of 4,659 traders; Chinese A-share social-trading portfolios, 2016–18)
- 95% interval
- 74.9–77.3%, treating traders as independent; the study explains why they are not quite
- Denominator
- Traders with at least one winner and at least one loser on some day, so that both halves of the measure are defined: 4,659 of the 4,731 in the panel
- Supporting figures
- Per trader then averaged: PGR 0.1925, PLR 0.1200, ratio 1.61. Pooled across every observation: PGR 0.0785, PLR 0.0535, ratio 1.47
- Period
- 24 Jun 2016 to 27 Mar 2018
- Observations
- 2,780,879 trader-stock-lot-days across 3,501 stocks; every day a position was held counts
- Data
- Jin, Li & Zhu, replication files for PLoS ONE (2021), CC0, Harvard Dataverse
- Script
reproduce.pyin the public repository. Client engagements usepartner_disposition.py, which computes pooled PGR and PLR from a five-column extract, counting only days on which an account sold something, as Odean did; since 17 Oct 2026 it also makes the same comparison with holding age held fixed. It does not produce a share of traders or a per-trader ratio. The like-for-like public figure is the pooled ratio, 1.47, and even that is only approximately comparable, because the two count days differently- What this does not show
- It measures the problem, not a fix. Nothing here says whether anything corrects the disposition effect.
- Chinese A-shares, mid-2016 to early 2018, one social-trading platform. Whether it holds for North American retail today is an assumption, not a result.
- Social-trading users are a selected population. Xueqiu cube operators chose to run public portfolios.
- I did not collect this data. It is someone else’s replication file, released CC0. The contribution is the computation and publishing it.
- The pooled and per-trader ratios differ, 1.47x against 1.61x, because the denominators differ. Both are above. Quoting one without the other is picking.
- Significance is not effect size. The t-statistics are enormous because n is enormous. Cohen’s d of 0.49 is the honest magnitude: moderate, not overwhelming.
- No minimum activity was required. A trader with one winning and one losing held day counts the same as one with thousands; how sensitive the share is to a minimum-activity rule has not been computed.
- Traders whose two rates are exactly equal are counted as not showing the effect; reproduce.py does not report how many there are.
- The source data’s gain flag is 1 only when a position was in profit, so a break-even day counts on the loss side. The client script, partner_disposition.py, drops break-even rows instead.
- Holding age: positions are sold less often the longer they are held. A robustness update to the study (17 Oct 2026) finds the direction survives when holding age is held fixed, but the size depends on how “gain” is timed, and a V-shaped selling pattern is not ruled out.
- Reliance
- A client memo is for the client’s use only; no other party may rely on it.
Client-format specimen, synthetic file
This is the complete output of the published client script, partner_disposition.py, run when this page was built on the synthetic file that the published make_fixture.py writes. It is what a client’s staff send back, and the figures a client memo is built from.
$ python3 make_fixture.py --out fixture.csv --seed 7
$ python3 partner_disposition.py fixture.csv --pnl-basis price
pnl basis: price (funding excluded)
accounts: 30
qualifying sale days: 256
data rows parsed: 14400
blank records skipped: 0
rows in qualifying pairs: 2048
rows discarded (no close that day): 12352
same-day marks superseded by close: 0
orphan closes (no mark row): 14 of 335 (4.2%)
identifier spelling collisions: 0
unicode data version: 14.0.0
PGR 0.2178
PLR 0.1119
ratio (PGR/PLR) 1.9470
t statistic 6.51
n gains (RG+PG) 1001
n losses (RL+PL) 1046
realised gains RG 218
paper gains PG 783
realised losses RL 117
paper losses PL 929
zero-pnl rows excluded 1
AGE-CONTROLLED FIGURES (holding age = calendar days since the
position's first row in this file)
positions with a known open date: 329
positions open on the first date (left out): 240
rows used (qualifying pairs, pnl not 0): 975
ratio, ages pooled, same rows: 2.0325
within-age ratio (Mantel-Haenszel): 1.9273
95% interval 1.3825 to 2.6867, by account
holding age gain rows loss rows PGR PLR ratio within-age
<=1 day 43 32 0.2093 0.0938 2.233 2.232
2-5 days 73 75 0.2055 0.1333 1.541 1.618
6-20 days 192 224 0.2240 0.0804 2.787 2.595
21-60 days 168 168 0.1667 0.1071 1.556 1.441
61-250 days 0 0 - - - -
251+ days 0 0 - - - -
fixed effects (account + holding day), linear probability model:
gain coefficient: 0.103986
standard error (account and date): 0.021478
ratio implied for gain rows (ATT): 2.0878
95% interval 1.4495 to 3.7307
gain timing (rows that have a previous row for the same position):
rows: 933
ratio, ages pooled: same day / previous row: 2.0604 / 1.8627
within-age ratio: same day / previous row: 1.9488 / 1.7481
fixed-effects ATT: same day / previous row: 2.0993 / 1.8586
sign changed since previous row, sold rows: 10 of 138
sign changed since previous row, unsold rows: 60 of 795
HOW TO READ THE AGE-CONTROLLED FIGURES
- Positions are sold less often the longer they are held. If losing
positions are on average older than winning ones, the pooled ratio at
the top can show an effect that is only an age pattern. The within-age
ratio compares winners and losers of the same holding age; use it, not
the pooled ratio, for the size of the effect.
- Holding age is counted from each position's first row in this file.
Positions already open on the file's first date are left out of these
figures because their age is unknown; the pooled figures still use them.
- The fixed-effects line compares each account with itself, at the same
holding day. It is a different average from the pooled ratio, so the two
are not expected to match.
- Gain timing: a position's gain or loss on the day it is sold may partly
reflect the sale itself (the fill or the closing mark). The lines that
take the gain or loss from the position's previous row avoid that. If
they are much smaller, the effect depends on same-day timing.
- Not ruled out: traders may sell large moves in either direction more
often (a V-shaped pattern, Ben-David and Hirshleifer 2012). Separating
that from a preference for selling winners needs the size of each gain
or loss relative to the position, which these five columns do not carry.
- The intervals here are clustered by account (the within-age ratio) and
by account and date (fixed effects). The t statistic at the top treats
every row as independent and is not.
- NOT MEASURED means the data cannot support the figure, never zero.
How to read the age-controlled figure
The headline ratio compares the share of winning positions you sold with the share of losing positions you sold, pooled over every position however long it had been held. Positions are usually sold less often the older they get, so if losers tend to be older, part of the headline is an age pattern, not a habit. The within-age ratio makes the same comparison only between positions of the same age (same number of days since opened), then combines the days. That is the figure to use for the size of the effect. The table by holding age shows where the effect sits: often mostly in positions held a day or less. The fixed-effects ratio compares each account with itself at the same holding age; it is a different average and is not expected to equal the pooled one. If the within-age interval includes 1, the data do not show an effect once age is held fixed. NOT MEASURED means the data cannot support that figure; it never means zero.
Scripts: partner_disposition.py · make_fixture.py
Get the next study by email. One email per finished study; free, no advice.
Or follow the Atom feed of new studies and corrections.