Entry, Exit & Trade Management
Level: 5 (Mastery — cross-domain: probability, calculus, and algorithmic reasoning) Time limit: 90 minutes Total marks: 60
Notation: denotes one unit of initial risk (entry price minus stop distance, in currency per share). All "R-multiples" are trade outcomes expressed in units of . RR denotes reward-to-risk ratio.
Question 1 — Expectancy, Sizing & the Ruin Boundary (24 marks)
A systematic swing trader defines a setup with the following rules:
- Enter long only when price closes above the 20-day high (breakout) AND the ATR(14) is above its 50-day median (volatility filter).
- Initial stop = entry (an ATR-based stop).
- Backtest over 200 signals gives: win rate ; average winner ; average loser (losers hit the full stop).
(a) Derive the general formula for per-trade expectancy in R-multiples given win rate , average win (in ) and average loss (in , entered as a positive magnitude). Compute for this system. (4)
(b) The trader risks a fixed fraction of equity per trade (i.e. a loss of costs of current equity). Show that the expected logarithmic growth per trade is Derive the first-order condition and solve for the growth-optimal fraction (Kelly). Compute numerically for this system. (8)
(c) Using the system's numbers, compute the expected equity multiple after independent trades if the trader risks the full each trade, versus half-Kelly (). Use . State which you would deploy live and give one risk-management reason. (6)
(d) Prove that if then , and interpret what this means for taking any positive position size. (6)
Question 2 — Structure Stops, Trailing Logic & Break-even (20 marks)
A trade is entered at \100$96=$2.00$.
(a) Compute the initial risk in dollars. If the profit target is set at a minimum RR of , give the target price. (3)
(b) The trader uses a chandelier trailing stop: . Over 5 days the intraday highs are (ATR constant at ). Tabulate the trailing stop each day and state the day the stop first moves to break-even or better. (6)
(c) Write pseudocode (any clear syntax) for a function manage_trade(prices, entry, atr, R) that returns the exit price and the realized R-multiple, applying: (i) a break-even stop after price reaches unrealised, then (ii) the chandelier trail thereafter. State your assumptions about intrabar fills. (7)
(d) Explain, referencing "cut losers quickly," why moving to a break-even stop too early can reduce expectancy even though it feels safer. Support with one sentence linking to the win-rate/average-win trade-off. (4)
Question 3 — Scaling Out: Optimising a Two-Target Exit (16 marks)
A trade risks . The trader will scale out: sell fraction of the position at (a "profit-book"), and let the remaining ride to either (probability , conditional on reaching ) or back to break-even (i.e. , probability ). Assume the level is always reached before resolution.
(a) Write the expected R-multiple of the whole trade as a function . (4)
(b) Show is linear in ; determine its slope and hence whether the optimal (to maximise expectancy) is or . Interpret this result against the psychological appeal of scaling out. (6)
(c) Now suppose scaling out reduces the variance of the outcome. Compute and the outcome variance at and , and argue in terms of the ratio (expectancy/standard deviation) — a per-trade "Sharpe" — which a risk-averse trader might prefer. (6)
End of paper.
Answer keyMark scheme & solutions
Question 1
(a) Expectancy is the probability-weighted sum of outcomes: (2 — correct construction) With : (2 — value) The system has a positive edge of per trade.
(b) Each trade multiplies equity by with prob and with prob . Log-growth per trade is the expected log-return: (2 — setup) Differentiate: (2) Cross-multiplying: Expand: . So (2 — derivation) Numerically: , i.e. risk 16% of equity per trade. (2)
(c) Compute at each fraction. A loss of costs fraction ; note means a winner returns of equity.
At : ; . Multiple over 100 trades: . (3)
At half-Kelly : ; . Multiple: . (3)
Deploy half-Kelly: full Kelly has extreme drawdowns (Kelly maximises growth but the equity path is very volatile; a run of losses at 16%/trade produces a punishing drawdown and, with estimation error in , can overbet into ruin). Half-Kelly keeps ~75% of the growth with far lower variance — consistent with "cut losers / preserve capital." (1 mark choice + 1 mark reason within the 6)
(d) . At : (3) If then : log-growth is non-increasing as you leave zero position size, so any positive gives (equity erodes in the long run). Interpretation: with no positive expectancy, no position size — however clever the sizing — creates a compounding edge; the only optimal size is zero. This is the mathematical statement of "don't trade a negative-expectancy setup." (3)
Question 2
(a) R = 100-96 = \4.001{:}2+2R = +$8\Rightarrow=$108$**. (2)
(b) Chandelier stop (highest high since entry) . Track running max of highs:
| Day | High | Running HH | Stop = HH−6 | Notes |
|---|---|---|---|---|
| 1 | 102 | 102 | 96 | = initial stop |
| 2 | 105 | 105 | 99 | below break-even |
| 3 | 104 | 105 | 99 | HH unchanged |
| 4 | 109 | 109 | 103 | ≥ 100: first at/above break-even |
| 5 | 108 | 109 | 103 | HH unchanged (trailing never lowers) |
(4 for table) Break-even () is first reached on Day 4 (stop ). (2)
(c) Pseudocode (assume stops fill at the stop price; check stop against each bar's low; unrealised profit measured off the bar high):
function manage_trade(prices, entry, atr, R):
stop = entry - R # initial structure/ATR stop
hh = entry
be_armed = false
for bar in prices: # bar has .high, .low, .close
# 1) update highest high
hh = max(hh, bar.high)
# 2) arm break-even once +1R touched
if not be_armed and bar.high >= entry + R:
be_armed = true
stop = max(stop, entry) # move to break-even
# 3) chandelier trail (only tightens upward)
if be_armed:
stop = max(stop, hh - 3*atr)
# 4) check for stop hit this bar
if bar.low <= stop:
exit = stop
return exit, (exit - entry)/R # realized R-multiple
exit = prices.last.close # exit at end if never stopped
return exit, (exit - entry)/R
(5 for correct logic: BE arming, upward-only trail, stop-hit check; 2 for stated assumption on intrabar fill.)
(d) Moving to break-even too early converts many trades that would have retraced then continued into scratch (0R) exits and truncates would-be winners at the low end, cutting the average win . Because expectancy , shrinking (and only slightly raising effective of non-losses) can lower even though loss frequency feels reduced — the "safety" is paid for by giving up right-tail R-multiples that the whole edge depends on. "Cut losers quickly" applies to real adverse structure breaks, not to normal noise near entry. (4)
Question 3
(a) Portion books . Portion resolves to (prob ) or (prob ): (4) With : , so .
(b) is linear; slope . (3) Hence expectancy is maximised at the lower endpoint (hold the full position for the runner), giving ; scaling everything at gives . (2) Interpretation: scaling out feels good (locks profit, boosts hit rate) but here it reduces expectancy because the runner has a positive edge worth more than the booked ; the psychological comfort costs return. (1)
(c) Outcomes of the whole trade as a function of the runner's resolution:
- With prob : .
- With prob : .
Mean (from (a)). Variance: (2 — derivation) With :
- : mean , Var , sd ; ratio .
- : mean , Var , sd ; ratio undefined/ (a certain ). (2)
Argument: the full-runner () has higher expectancy but lower per-trade Sharpe (0.734) and real downside dispersion. Scaling fully out () yields a certain — zero variance — so a strongly risk-averse trader (minimising ruin/drawdown, or with poor edge estimates) may prefer larger despite lower mean, trading ~0.4R of expectancy for elimination of variance. The rational choice is an interior compromise if a smoothness/drawdown constraint is added; on pure expectancy alone, wins. (2)
[
{"claim":"Expectancy E = 0.40R for Q1a","code":"p=Rational(4,10);W=Rational(5,2);L=1;E=p*W-(1-p)*L;result=(E==Rational(4,10))"},
{"claim":"Kelly fraction f* = 0.16","code":"p=Rational(4,10);W=Rational(5,2);L=1;E=p*W-(1-p)*L;f=E/(W*L);result=(f==Rational(16,100))"},
{"claim":"100-trade full-Kelly multiple ~20.0","code":"import sympy as sp;g=sp.Float('0.4')*sp.log(sp.Float('1.40'))+sp.Float('0.6')*sp.log(sp.Float('0.84'));m=sp.exp(100*g);result=(abs(m-20.0)<0.5)"},
{"claim":"Half-Kelly multiple ~9.87","code":"import sympy as sp;g=sp.Float('0.4')*sp.log(sp.Float('1.20'))+sp.Float('0.6')*sp.log(sp.Float('0.92'));m=sp.exp(100*g);result=(abs(m-9.87)<0.3)"},
{"claim":"Chandelier stop reaches break-even (>=100) on Day4","code":"highs=[102,105,104,109,108];hh=100;days=[];\nfor i,h in enumerate(highs,1):\n hh=max(hh,h);days.append((i,hh-6))\nfirst=[d for d,s in days if s>=100][0];result=(first==4)"},
{"claim":"Scaling expectancy R-bar(0)=1.4 and R-bar(1)=1.0","code":"q=Rational(35,100);f=lambda x:x+(1-x)*4*q;result=(f(0)==Rational(14,10) and f(1)==1)"},
{"claim":"Variance at x=0 is 3.64","code":"q=Rational(35,100);V=16*q*(1-q)*(1-0)**2;result=(V==Rational(364,100))"}
]