Level 3 — ProductionWhat to Trade

What to Trade

45 minutes60 marksprintable — key stays hidden on paper

Chapter: 4.2 What to Trade Level: 3 — Production (from-scratch derivations, code-from-memory, explain-out-loud) Time Limit: 45 minutes Total Marks: 60

Instructions: Show all working. Derive formulas from first principles where asked. Code answers may be pseudocode but must be logically complete. Use ...... for math.


Question 1 — Liquidity & Instrument Choice (10 marks)

(a) From first principles, derive an expression for the round-trip transaction cost (as a fraction of trade value) for a market order in a stock, in terms of the bid–ask spread ss, mid-price MM, and brokerage rate bb (per side). Explain each term out loud. (4)

(b) Stock A has bid/ask of 198/202198/202; Stock B has bid/ask of 199.5/200.5199.5/200.5. Both trade at mid M=200M=200, brokerage b=0.03%b=0.03\% per side. Compute round-trip cost fraction for each. (4)

(c) State the decision rule you would use to choose between the two for a scalping strategy, and justify. (2)


Question 2 — Index Trading & Weighting (12 marks)

(a) Derive the formula for a free-float market-cap weighted index value from scratch, defining the divisor DD and explaining why a divisor is needed. (4)

(b) An index has 3 constituents:

Stock Price Free-float shares
X 500 100
Y 300 200
Z 800 50

If the base free-float market cap corresponds to index value 1000 with divisor DD, compute DD (take base = current). Then compute the new index value if X rises to 550. (5)

(c) Explain out loud why Bank Nifty is more volatile than Nifty 50, referencing concentration. (3)


Question 3 — F&O Payoff Derivation (12 marks)

(a) Derive from scratch the payoff at expiry of a long call and a short put on the same strike KK and premium notation. Sketch/describe the payoff profiles. (5)

(b) A trader is long a Nifty future at 22,00022{,}000 and long a 22,00022{,}000 put at premium 150150. Derive the combined payoff expression and identify the maximum loss. (5)

(c) Name this combined position and explain out loud what market view it expresses. (2)


Question 4 — Correlation From Scratch (12 marks)

(a) Write the Pearson correlation coefficient formula and explain each component. (3)

(b) Given daily returns: Instrument P: {+2,1,+3,0}\{+2, -1, +3, 0\} (%), Instrument Q: {+1,2,+2,1}\{+1, -2, +2, -1\} (%). Compute the correlation coefficient ρPQ\rho_{PQ} from scratch (means, deviations, covariance, std devs). (6)

(c) Explain out loud how a trader uses a high positive correlation between two watchlist stocks to avoid over-exposure. (3)


Question 5 — Screening Code From Memory (8 marks)

Write pseudocode (from memory) for a stock screener function that takes a list of stock dicts (each with avg_volume, atr_pct, rel_strength, price) and returns tradable candidates satisfying: liquidity (avg_volume > 1,000,000), sufficient volatility (atr_pct > 1.5), leadership (rel_strength > 1.0), and affordability (price < 3000). Sort output by rel_strength descending. (8)


Question 6 — Relative Strength & Sector Leaders (6 marks)

(a) Derive the relative strength ratio of a stock vs its benchmark and state what RS>1RS>1 and a rising RSRS line mean. (3)

(b) Stock closes at 120120 (was 100100); benchmark at 110110 (was 100100). Compute the RS ratio of returns and interpret. (3)

Answer keyMark scheme & solutions

Question 1 (10)

(a) Buy at ask M+s2M+\tfrac{s}{2}, sell at bid Ms2M-\tfrac{s}{2}. Spread cost per round trip =s=s on a value of MM. Brokerage charged both sides =2bM=2bM. Round-trip cost fraction: C=sM+2bC=\frac{s}{M}+2b

  • s/Ms/M = spread as fraction of mid (implicit cost). (2)
  • 2b2b = explicit brokerage both legs. (2)

(b) Stock A: s=4s=4, CA=4200+2(0.0003)=0.02+0.0006=0.0206=2.06%C_A=\frac{4}{200}+2(0.0003)=0.02+0.0006=0.0206=2.06\%. (2) Stock B: s=1s=1, CB=1200+0.0006=0.005+0.0006=0.0056=0.56%C_B=\frac{1}{200}+0.0006=0.005+0.0006=0.0056=0.56\%. (2)

(c) Choose the lower-cost, tighter-spread stock (B) for scalping since frequent trades make spread the dominant cost; edge per trade is small so cost must be minimized. (2)

Question 2 (12)

(a) Total free-float mcap =piqi=\sum p_i q_i. Raw sum changes with corporate actions, so we normalise by divisor DD: Index=ipiqiD\text{Index}=\frac{\sum_i p_i q_i}{D} DD is set so the index equals a chosen base value at the base date; adjusting DD on splits/additions keeps the index continuous. (4)

(b) Current mcap =500(100)+300(200)+800(50)=50000+60000+40000=150000=500(100)+300(200)+800(50)=50000+60000+40000=150000. Index base 10001000: D=1500001000=150D=\frac{150000}{1000}=150. (2) New mcap with X=550: 550(100)+60000+40000=55000+100000=155000550(100)+60000+40000=55000+100000=155000. New index =155000/150=1033.33=155000/150=1033.33. (3)

(c) Bank Nifty has fewer constituents (~12) and heavy concentration in top private banks; large weighted names move it more, so idiosyncratic bank moves aren't diluted → higher volatility than the broader 50-stock Nifty. (3)

Question 3 (12)

(a) Long call payoff at expiry =max(STK,0)c=\max(S_T-K,0)-c. Below KK lose premium cc; above KK gains linearly. (2.5) Short put payoff =pmax(KST,0)=p-\max(K-S_T,0). Keep premium pp above KK; lose linearly below. (2.5)

(b) Long future payoff =ST22000=S_T-22000. Long put payoff =max(22000ST,0)150=\max(22000-S_T,0)-150. Combined: Π=(ST22000)+max(22000ST,0)150\Pi=(S_T-22000)+\max(22000-S_T,0)-150

  • If ST<22000S_T<22000: (ST22000)+(22000ST)150=150(S_T-22000)+(22000-S_T)-150=-150.
  • If ST22000S_T\ge22000: (ST22000)+0150=ST22150(S_T-22000)+0-150=S_T-22150. Max loss =150=150 (floor). (5)

(c) This is a protective put (synthetic long call). View: bullish but wanting downside protection. (2)

Question 4 (12)

(a) ρ=(xixˉ)(yiyˉ)(xixˉ)2(yiyˉ)2\rho=\dfrac{\sum(x_i-\bar x)(y_i-\bar y)}{\sqrt{\sum(x_i-\bar x)^2}\sqrt{\sum(y_i-\bar y)^2}}; numerator = covariance (co-movement), denominator = product of std devs (normalises to [1,1][-1,1]). (3)

(b) Pˉ=21+3+04=1\bar P=\frac{2-1+3+0}{4}=1, Qˉ=12+214=0\bar Q=\frac{1-2+2-1}{4}=0. Deviations P: 1,2,2,11,-2,2,-1; Q: 1,2,2,11,-2,2,-1. Products: 1,4,4,11,4,4,1=10\sum=10. (PPˉ)2=1+4+4+1=10\sum(P-\bar P)^2=1+4+4+1=10; (QQˉ)2=1+4+4+1=10\sum(Q-\bar Q)^2=1+4+4+1=10. ρ=101010=1010=1.0\rho=\frac{10}{\sqrt{10}\sqrt{10}}=\frac{10}{10}=1.0. (6)

(c) Two highly correlated stocks are effectively one bet; taking full positions in both doubles risk without diversifying. Trader sizes them as one exposure or picks the stronger only. (3)

Question 5 (8)

def screen(stocks):
    out = []
    for s in stocks:
        if (s['avg_volume'] > 1_000_000 and      # liquidity  (2)
            s['atr_pct'] > 1.5 and                # volatility (1)
            s['rel_strength'] > 1.0 and           # leadership (1)
            s['price'] < 3000):                   # affordability(1)
            out.append(s)
    out.sort(key=lambda s: s['rel_strength'], reverse=True)  # sort (2)
    return out                                    # return (1)

Correct filter logic (5) + sort desc (2) + return (1).

Question 6 (6)

(a) RS=PstockPbenchmarkRS=\dfrac{P_{stock}}{P_{benchmark}} (or ratio of normalised returns). RS>1RS>1 (or rising) means the stock outperforms the benchmark → leadership. A rising RS line = accumulating relative strength. (3)

(b) Stock return =20%=20\%, benchmark =10%=10\%. RS of returns =1.201.10=1.0909=\frac{1.20}{1.10}=1.0909; stock outperforms benchmark → relative leader. (3)

[
  {"claim":"Round-trip cost Stock A = 2.06%","code":"s=4; M=200; b=0.0003; C=s/M+2*b; result=abs(C-0.0206)<1e-9"},
  {"claim":"Round-trip cost Stock B = 0.56%","code":"s=1; M=200; b=0.0003; C=s/M+2*b; result=abs(C-0.0056)<1e-9"},
  {"claim":"Index divisor 150 and new value 1033.33","code":"D=150000/1000; newidx=155000/D; result=(D==150) and abs(newidx-1033.3333333)<1e-3"},
  {"claim":"Correlation PQ = 1.0","code":"P=[2,-1,3,0]; Q=[1,-2,2,-1]; mP=sum(P)/4; mQ=sum(Q)/4; cov=sum((p-mP)*(q-mQ) for p,q in zip(P,Q)); sp=sum((p-mP)**2 for p in P); sq=sum((q-mQ)**2 for q in Q); rho=cov/(sp*sq)**Rational(1,2); result=simplify(rho-1)==0"},
  {"claim":"RS ratio of returns = 1.0909","code":"rs=Rational(120,100)/Rational(110,100); result=abs(float(rs)-1.0909090909)<1e-6"},
  {"claim":"Protective put max loss = 150","code":"import numpy as np; loss=min((St-22000)+max(22000-St,0)-150 for St in range(20000,24001,50)); result=loss==-150"}
]