Level 5 — MasteryTrading Strategies

Trading Strategies

90 minutes60 marksprintable — key stays hidden on paper

Chapter: 4.6 Trading Strategies Difficulty: Level 5 — Mastery (cross-domain: math + probability + coding) Time limit: 90 minutes Total marks: 60

Instructions: Answer ALL questions. Show full working. Round monetary values to 2 decimals and probabilities to 4 decimals unless stated. Pseudocode or Python accepted for coding parts.


Question 1 — Opening Range Breakout, VWAP filter, and expectancy (24 marks)

A trader runs an Opening Range Breakout (ORB) system on a single stock with a VWAP confirmation filter.

Market data (first candles of the session):

Time Volume (shares) Typical Price (H+L+C3)\left(\frac{H+L+C}{3}\right)
09:15–09:20 4,000 100.00
09:20–09:25 6,000 100.50
09:25–09:30 10,000 101.00

The opening range (OR) is defined over 09:15–09:30 with high HOR=101.20H_{OR}=101.20 and low LOR=99.80L_{OR}=99.80.

(a) Compute the session VWAP at 09:30 from the table above. (4)

(b) A long breakout entry is triggered at 09:31 when price closes at 101.35101.35 (above HORH_{OR}). State whether the VWAP filter (price must be above VWAP) confirms the trade, and justify numerically. (3)

(c) The stop is placed at the OR midpoint. The target uses a fixed reward:risk ratio of R=2.5R=2.5. Compute the stop price, the risk per share, the target price, and the reward per share. (5)

(d) Backtesting gives a win rate p=0.42p=0.42. Using the reward:risk of 2.52.5 (winners = +2.5+2.5 units of risk, losers = 1-1 unit), derive the expectancy per trade in units of risk and state whether the system is profitable. (4)

(e) Prove algebraically the break-even win rate p\*p^\* as a function of the reward:risk ratio RR, then evaluate p\*p^\* for R=2.5R=2.5. Comment on the margin of safety of the p=0.42p=0.42 system. (5)

(f) Position sizing: account equity is \50{,}000,risking, risking 1%$ per trade. Compute the number of shares (round down to nearest whole share) using the risk-per-share from (c). (3)


Question 2 — Moving-average crossover: cross-domain derivation + code (22 marks)

Consider a price series and two simple moving averages, the fast SMAn\text{SMA}_n (period nn) and slow SMAm\text{SMA}_m (period mm), with m>nm>n.

(a) A golden cross occurs when the fast SMA crosses above the slow SMA. For a price series that is a pure linear uptrend Pt=a+btP_t = a + bt (b>0b>0), prove that SMAn(t)SMAm(t)\text{SMA}_n(t) - \text{SMA}_m(t) is a constant (independent of tt), and derive that constant in terms of a,b,n,ma,b,n,m. Explain what this proves about crossover signals in a perfectly linear trend. (8)

(b) Given the closing prices: [10,11,13,12,14,16,15,17,19,18][10, 11, 13, 12, 14, 16, 15, 17, 19, 18] Compute SMA3\text{SMA}_3 and SMA5\text{SMA}_5 at the final bar (index 9, last value 1818). State whether the fast SMA is above or below the slow SMA at that bar. (6)

(c) Write a function (Python or clear pseudocode) crossover_signals(prices, n, m) that returns a list of signals: +1 on the bar where a golden cross first occurs, -1 on a death cross, 0 otherwise. Handle the warm-up period (bars before both SMAs exist) as 0. (8)


Question 3 — RSI reversal system: math + probabilistic edge (14 marks)

The RSI over period N=14N=14 is: RSI=1001001+RS,RS=avg gainavg lossRSI = 100 - \frac{100}{1+RS}, \qquad RS = \frac{\text{avg gain}}{\text{avg loss}}

(a) Over the last 14 bars the average gain is 1.201.20 and the average loss is 0.800.80. Compute RSRS and RSIRSI. Is this an overbought (>70>70), oversold (<30<30), or neutral reading? (5)

(b) Derive the general condition on the ratio g=avg gainavg lossg = \frac{\text{avg gain}}{\text{avg loss}} for which RSI=70RSI = 70, and hence state the threshold value of gg that marks the overbought line. (4)

(c) A mean-reversion trader only takes long trades when RSI<30RSI<30. Historically such signals win 60%60\% of the time with reward:risk 1.51.5. Compute the expectancy in units of risk and state whether combining this with the RSI oversold filter is a positive-edge system. (5)

Answer keyMark scheme & solutions

Question 1

(a) VWAP (4 marks) VWAP=(TypPrice×Vol)VolVWAP = \frac{\sum (\text{TypPrice}\times \text{Vol})}{\sum \text{Vol}} Numerator =100.00(4000)+100.50(6000)+101.00(10000)= 100.00(4000)+100.50(6000)+101.00(10000) =400,000+603,000+1,010,000=2,013,000= 400{,}000 + 603{,}000 + 1{,}010{,}000 = 2{,}013{,}000 (2 marks) Denominator =4000+6000+10000=20,000= 4000+6000+10000 = 20{,}000 VWAP=2,013,00020,000=100.65VWAP = \frac{2{,}013{,}000}{20{,}000} = 100.65 (2 marks)

(b) VWAP filter (3 marks) Entry price 101.35>VWAP 100.65101.35 > VWAP\ 100.65 ⇒ price is above VWAP, so the long filter confirms the trade. (3 marks: correct comparison + conclusion)

(c) Stop, risk, target, reward (5 marks) OR midpoint =HOR+LOR2=101.20+99.802=100.50= \frac{H_{OR}+L_{OR}}{2} = \frac{101.20+99.80}{2} = 100.50 (stop). (1) Risk per share =101.35100.50=0.85= 101.35 - 100.50 = 0.85. (1) Reward per share =R×risk=2.5×0.85=2.125= R\times\text{risk} = 2.5\times 0.85 = 2.125. (1) Target =101.35+2.125=103.475103.48= 101.35 + 2.125 = 103.475 \approx 103.48. (2)

(d) Expectancy (4 marks) E=p(2.5)+(1p)(1)E = p\cdot(2.5) + (1-p)(-1) =0.42(2.5)+0.58(1)=1.050.58=0.47= 0.42(2.5) + 0.58(-1) = 1.05 - 0.58 = 0.47 units of risk. (3) E>0E>0profitable system (expected +0.47R+0.47R per trade). (1)

(e) Break-even win rate (5 marks) Set expectancy to zero: p\*(R)+(1p\*)(1)=0p\*R1+p\*=0p^\*(R) + (1-p^\*)(-1) = 0 \Rightarrow p^\*R - 1 + p^\* = 0 p\*(R+1)=1p\*=1R+1p^\*(R+1) = 1 \Rightarrow \boxed{p^\* = \frac{1}{R+1}} (3) For R=2.5R=2.5: p\*=13.5=0.2857p^\* = \frac{1}{3.5} = 0.2857. (1) Actual p=0.42>0.2857p=0.42 > 0.2857, giving a comfortable margin of safety (~13 percentage points above break-even). (1)

(f) Position sizing (3 marks) Risk budget = 1\%\times 50{,}000 = \500.(1)Shares. *(1)* Shares = \dfrac{500}{0.85} = 588.24 \Rightarrow 588$ shares (round down). (2)


Question 2

(a) Constant SMA difference in linear trend (8 marks) For Pt=a+btP_t = a+bt, the SMA of period kk ending at tt (using bars tk+1,,tt-k+1,\dots,t): SMAk(t)=1ki=0k1Pti=1ki=0k1(a+b(ti))\text{SMA}_k(t) = \frac{1}{k}\sum_{i=0}^{k-1} P_{t-i} = \frac{1}{k}\sum_{i=0}^{k-1}\big(a + b(t-i)\big) =a+btbki=0k1i=a+btbk(k1)k2=a+btb(k1)2.= a + bt - \frac{b}{k}\sum_{i=0}^{k-1} i = a + bt - \frac{b}{k}\cdot\frac{(k-1)k}{2} = a + bt - \frac{b(k-1)}{2}. (4 marks) Therefore: SMAn(t)SMAm(t)=b(n1)2+b(m1)2=b(mn)2.\text{SMA}_n(t) - \text{SMA}_m(t) = -\frac{b(n-1)}{2} + \frac{b(m-1)}{2} = \frac{b(m-n)}{2}. (2 marks) This is constant (no tt). Since b>0b>0 and m>nm>n, the difference is positive: the fast SMA sits a fixed distance above the slow SMA. Interpretation: in a perfectly linear trend the SMAs never cross — crossover signals arise only from curvature / changes in slope, not from steady trends. (2 marks)

(b) SMA computation (6 marks) Last 3 prices (indices 7,8,9): 17,19,1817,19,18SMA3=17+19+183=543=18.00\text{SMA}_3 = \frac{17+19+18}{3} = \frac{54}{3} = 18.00. (3) Last 5 prices (indices 5–9): 16,15,17,19,1816,15,17,19,18SMA5=855=17.00\text{SMA}_5 = \frac{85}{5} = 17.00. (2) 18.00>17.0018.00 > 17.00 ⇒ fast SMA is above slow SMA (bullish). (1)

(c) Code (8 marks)

def crossover_signals(prices, n, m):
    def sma(seq, k, i):
        return sum(seq[i-k+1:i+1]) / k
    signals = [0] * len(prices)
    warmup = m - 1  # need m bars for slow SMA
    for i in range(len(prices)):
        if i < warmup:
            signals[i] = 0
            continue
        fast_now  = sma(prices, n, i)
        slow_now  = sma(prices, m, i)
        fast_prev = sma(prices, n, i-1)
        slow_prev = sma(prices, m, i-1)
        if fast_prev <= slow_prev and fast_now > slow_now:
            signals[i] = 1    # golden cross
        elif fast_prev >= slow_prev and fast_now < slow_now:
            signals[i] = -1   # death cross
        else:
            signals[i] = 0
    return signals

Marks: warm-up handling (2), correct prev-vs-now cross detection (4), golden/death labelling (2).


Question 3

(a) RSI computation (5 marks) RS=1.200.80=1.5RS = \frac{1.20}{0.80} = 1.5. (2) RSI=1001001+1.5=1001002.5=10040=60.RSI = 100 - \frac{100}{1+1.5} = 100 - \frac{100}{2.5} = 100 - 40 = 60. (2) 6060 is between 30 and 70 ⇒ neutral. (1)

(b) Threshold g for RSI=70 (4 marks) 70=1001001+g1001+g=301+g=10030=3.33370 = 100 - \frac{100}{1+g} \Rightarrow \frac{100}{1+g} = 30 \Rightarrow 1+g = \frac{100}{30} = 3.333\ldots g=100301=7030=2.3332.3333.g = \frac{100}{30} - 1 = \frac{70}{30} = 2.333\ldots \approx 2.3333. (3) So g=7/3g = 7/3 marks the overbought line (avg gain = 2.33×2.33\times avg loss). (1)

(c) Expectancy of RSI-oversold long (5 marks) E=0.60(1.5)+0.40(1)=0.900.40=0.50E = 0.60(1.5) + 0.40(-1) = 0.90 - 0.40 = 0.50 units of risk. (3) E=+0.50R>0E = +0.50R > 0positive-edge system; the RSI<30 filter produces a profitable expectancy. (2)

[
  {"claim":"VWAP equals 100.65","code":"num=100*4000+100.5*6000+101*10000; den=4000+6000+10000; result = (Rational(num,den)==Rational(20130,200)) and (num/den==100.65)"},
  {"claim":"ORB risk 0.85, reward 2.125, target 103.475","code":"stop=Rational('100.50'); entry=Rational('101.35'); risk=entry-stop; reward=Rational(5,2)*risk; target=entry+reward; result = (risk==Rational('0.85')) and (reward==Rational('2.125')) and (target==Rational('103.475'))"},
  {"claim":"Expectancy R=2.5 p=0.42 is 0.47","code":"p=Rational(42,100); E=p*Rational(5,2)+(1-p)*(-1); result = (E==Rational(47,100))"},
  {"claim":"Break-even win rate for R=2.5 is 2/7","code":"R=Rational(5,2); pstar=1/(R+1); result = (pstar==Rational(2,7))"},
  {"claim":"Shares = floor(500/0.85) = 588","code":"import math; result = (math.floor(500/Rational('0.85'))==588)"},
  {"claim":"SMA3=18 SMA5=17 at last bar","code":"p=[10,11,13,12,14,16,15,17,19,18]; s3=Rational(sum(p[7:10]),3); s5=Rational(sum(p[5:10]),5); result = (s3==18) and (s5==17)"},
  {"claim":"RSI with RS=1.5 equals 60","code":"RS=Rational(120,80); RSI=100-100/(1+RS); result = (RSI==60)"},
  {"claim":"g for RSI=70 equals 7/3","code":"g=symbols('g'); sol=solve(Eq(100-100/(1+g),70),g); result = (sol[0]==Rational(7,3))"},
  {"claim":"RSI-oversold expectancy = 0.5","code":"E=Rational(60,100)*Rational(3,2)+Rational(40,100)*(-1); result = (E==Rational(1,2))"}
]