1. Projects Portfolio
Daniel Fei Wang
Master in Financial Markets
Trading Strategies & Financial Engineering
Illinois Institute of Technology
Chicago, IL 60661
312-927-2431
Fwang17@stuart.iit.edu
2. Trading Projects List
Page 2 – Page 25
Project I:
Pair Trading Model with Equities, ETFS and Options
Page 26 – Page 28
Project II:
Fixed Income Trading Portfolio Modeling with Ted
Spreads, Yield Curve Trade, and Basis Trade
Project III: Page 29 – Page 41
Algorithmic Equity Trading System with Moving
Averages and Oscillators in MATLAB
Project IV: Page 42 – Page 54
Portfolio Optimization Model by VBA
Project V: Page 55 – Page 69
Market Risk Management Report By VAR Analysis
Project VI: Page 70 – Page 77
Summary of Financial Modeling by MATLAB
2
3. Statistical Arbitrage Trading Model
------With Stocks & ETFs
For Short Term Intra-Day Trading and Long Term Back Testing
1). Equity Searching & Pairs Research
Stock Pair One:
ABX / NEM
Sector: Gold Mines for Both
Average Volume: 13168417 / 7819029
Float: 968M / 478.9625M
Short Interest: 8.695M / 7.141M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression Data:
Regression Statistics
0.682
Multiple R 6
0.466
R Square 0
Adjusted R 0.465
Square 4
2.173
Standard Error 8
945.000
Observations 0
3
4. ANOVA
Significanc
df SS MS F eF
1.000 3,888.397 3,888.397 822.835
Regression 0 6 6 9 0.0000
943.000 4,456.245
Residual 0 5 4.7256
944.000 8,344.643
Total 0 1
Stock Pair Two:
APA / APC
Sector: Energy Company / oil Gas Exploration
Average Volume: 4870352 / 7724989
Float: 333.81M / 488.27M
Short Interest: 4.228M / 10.573M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression Data:
Regression Statistics
0.93
Multiple R 96
0.88
R Square 28
Adjusted R 0.88
Square 27
3.28
Standard Error 03
954.00
Observations 00
ANOVA
Significanc
df SS MS F eF
4
5. 1.00 77,170.432 77,170.432 7,171.827
Regression 00 2 2 3 -
952.00 10,243.728 10.760
Residual 00 4 2
953.00 87,414.160
Total 00 6
Stock Pair Three:
APA / MUR
Sector: Energy Company / oil Gas Exploration
Average Volume: 4870352 / 2269944
Float: 333.81M / 178.51M
Short Interest: 4.228M / 5.636M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression Data:
Regression Statistics
Multiple R 0.943594
R Square 0.890369
Adjusted R
Square 0.890254
Standard Error 3.172775
Observations 954
ANOVA
Significanc
df SS MS F eF
Regression 1 77830.85 77830.85 7731.668 0
Residual 952 9583.31 10.0665
Total 953 87414.16
Stock Pair Four:
ALTR / LSCC
Sector: Both Programmable logic Devices
5
6. Average Volume: 9065785 / 745356
Float: 293.63M / 114.89M
Short Interest: 18.629M / 2.006M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression Data:
Regression Statistics
Multiple R 0.666213
R Square 0.44384
Adjusted R
Square 0.443251
Standard Error 0.996277
Observations 946
ANOVA
Significanc
df SS MS F eF
Regression 1 747.7548 747.7548 753.3531 2.1E-122
Residual 944 936.985 0.992569
Total 945 1684.74
Stock Pair Five:
BNI / CSX
Sector: Both Transportation
Average Volume: 3842821 / 7092411
Float: 338.55M / 389.52M
Short Interest: 4.560M / 22.710M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
6
7. Regression Data:
Regression Statistics
Multiple R 0.959484
R Square 0.92061
Adjusted R
Square 0.920527
Standard Error 2.451596
Observations 954
ANOVA
Significanc
df SS MS F eF
Regression 1 66351.03 66351.03 11039.51 0
Residual 952 5721.83 6.010325
Total 953 72072.86
Stock Pair Six:
BNI / UNP
Sector: Transportation / Electricity Transmission
Average Volume: 3842821 / 6288171
Float: 338.55M / 502.07M
Short Interest: 4.560M / 5.487M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
7
8. Regression Data:
Regression Statistics
Multiple R 0.98440392
R Square 0.969051078
Adjusted R Square 0.969018328
Standard Error 1.53524198
Observations 947
ANOVA
Significance
df SS MS F F
Regression 1 69740.75153 69740.75153 29589.18128 0
Residual 945 2227.3347 2.356967936
Total 946 71968.08623
2) Model Building, Back-testing & Results
Algorithm & Model Building:
The Algorithm of this pair trading model based on several straight-forward equation and definitions:
Step 1) Calculate Pair Price Ratio
Step 2) Determine Moving Average of Price Ratio by put an input parameter in VBA Program
Step 3) Calculate the Spread called Sigma by using the following formula:
Sigma = Price A - Moving Average ( A/B ) * Price B
Step 4) Compute the moving average of Sigma by put an input parameter in VBA Program again
8
9. Step 5) Calculate the moving standard deviation of Sigma
Step 6) Calculate the Z- Volatility Score Value by comparing Sigma with its moving average and standard deviation.
The formula is Z- Volatility Score = (Sigma – moving average) / moving standard deviation
Step 7) Based on the Z-Volatility Score, we determine the buy and sell signal, and we set up an benchmark in VBA
program input field.
Important Notes: the price I used to generate buy and sell signal, long/short share amount is the average of bid and
ask for each time. Based on these signal and long/short amount, I take bid and ask price and cost for each trade to
calculate the Market-to-Market P&L for the spread.
Back testing by change the parameters
---Built Model in VBA to back-testing the pairs
---Initial Portfolio 100,000 for each Pairs
---Determine which moving average length, trade signal, and position sizing makes you the most money.
Back Testing Result & Market to Market Account Chart
------Results:
ABX / NEM APA / APC
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 946 Percentage Price Data 955 Percentage
Net P&L $237.88 0.24% Net P&L $9,383.71 9.38%
Winning trades 39 63.93% Winning trades 17 60.71%
losing trades 22 36.07% losing trades 11 39.29%
Total Trades 61 Total Trades 28
Max Down -2.5156% Max Down -2.3627%
Max up 2.3174% Max up 2.7464%
9
10. APA / MUR ALTR / LSCC
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 955 Percentage Price Data 947 Percentage
Net P&L $2,299.50 2.30% Net P&L $1,236.54 1.24%
Winning trades 11 61.11% Winning trades 18 62.07%
losing trades 7 38.89% losing trades 11 37.93%
Total Trades 18 Total Trades 29
Max Down -2.4807% Max Down -37.7425%
Max up 4.3969% Max up 61.1562%
BNI / CSX BNI / UNP
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 955 Percentage Price Data 948 Percentage
Net P&L $2,304.74 2.30% Net P&L $2,776.72 2.78%
Winning trades 17 68.00% Winning trades 16 59.26%
losing trades 8 32.00% losing trades 11 40.74%
Total Trades 25 Total Trades 27
Max Percentage
Max Down -2.0028% Down -2.5592%
Max Percentage
Max up 2.2569% up 3.5574%
ABX / NEM
APA / APC
10
12. 2. ETF Pairs With Intraday Trading:
1). ETFS Searching & Pairs Research
ETFs Pair One:
IYR / URE
Sector: Real Estate Industry
Average Volume: 34195215 / 22932178
Float: 59.4M / 103.125M
Short Interest: 67.3M / 12.28M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression:
Regression Statistics
Multiple R 0.987473407
R Square 0.97510373
Adjusted R Square 0.975076006
Standard Error 0.690181083
Observations 900
ANOVA
Significance
df SS MS F F
Regression 1 16754.01773 16754.01773 35171.66013 0
Residual 898 427.7622344 0.476349927
12
13. Total 899 17181.77996
ETFs Pair Two:
XLF / FAS
Sector: Financial Select Sector
Average Volume: 191MLN / 32200597
Float: 510M/ 13.2489M
Short Interest: 111M / 4,488,052
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression:
Regression Statistics
Multiple R 0.965554314
R Square 0.932295134
Adjusted R Square 0.932219486
Standard Error 0.465995702
Observations 897
ANOVA
Significanc
df SS MS F eF
Regression 1 2676.211 2676.211 12324.14 0
Residual 895 194.351 0.217152
Total 896 2870.562
ETFs Pair Three:
XLF / UYG
Sector: Financial Select Sector / Dow Jones U.S. Financials Index
Average Volume: 191MLN / 108MLN
13
14. Float: 510M/ 405.75M
Short Interest: 111M / 26.33M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
Regression:
Regression Statistics
Multiple R 0.988323105
R Square 0.976782561
Adjusted R Square 0.97675662
Standard Error 0.272884664
Observations 897
ANOVA
Significance
df SS MS F F
Regression 1 2803.915193 2803.915193 37653.60964 0
Residual 895 66.64710558 0.07446604
Total 896 2870.562298
ETFs Pair Four:
VWO / FXI
Sector: emerging markets around the world / largest companies in the China equity market
Average Volume: 5404127 / 34709548
Float: 332.5M/ 221.4M
Short Interest: 8,448,043 / 30.75M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
14
15. Regression:
Regression Statistics
Multiple R 0.984253613
R Square 0.968755175
Adjusted R Square 0.968720574
Standard Error 0.753412507
Observations 905
ANOVA
Significance
df SS MS F F
Regression 1 15892.39456 15892.39456 27997.7859 0
Residual 903 512.5702562 0.567630405
Total 904 16404.96482
ETFs Pair Five:
IWM / SMH
Sector: 2000 Index Fund Growth-Small Cap / Fund-Technology
Average Volume: 73536673 / 14302000
Float: 200M/ 31.4M
Short Interest: 139M / 27.8M
Historical Chart from 3/2/2009 to 9/14/2009, Data Time Interval : 1 hour
15
16. Regression:
Regression Statistics
Multiple R 0.93493514
R Square 0.874103716
Adjusted R Square 0.873963831
Standard Error 1.869407541
Observations 902
ANOVA
Significance
df SS MS F F
Regression 1 21837.38064 21837.38064 6248.741567 0
Residual 900 3145.216098 3.494684554
Total 901 24982.59673
2) Model Building, Back-testing & Results
Algorithm & Model Building:
The Algorithm of this pair trading model based on several straight-forward equation and definitions:
Step 1) Calculate Pair Price Ratio
Step 2) Determine Moving Average of Price Ratio by put an input parameter in VBA Program
Step 3) Calculate the Spread called Sigma by using the following formula:
Sigma = Price A - Moving Average ( A/B ) * Price B
Step 4) Compute the moving average of Sigma by put an input parameter in VBA Program again
Step 5) Calculate the moving standard deviation of Sigma
Step 6) Calculate the Z- Volatility Score Value by comparing Sigma with its moving average and standard deviation.
The formula is Z- Volatility Score = (Sigma – moving average) / moving standard deviation
Step 7) Based on the Z-Volatility Score, we determine the buy and sell signal, and we set up an benchmark in VBA
16
17. program input field.
Important Notes: the price I used to generate buy and sell signal, long/short share amount is the average of bid and
ask for each time. Based on these signal and long/short amount, I take bid and ask price and cost for each trade to
calculate the Market-to-Market P&L for the spread.
Back testing by change the parameters
(Same as Equity)
---Built Model in VBA to back-testing the pairs
---Initial Portfolio 100,000 for each Pairs
---Determine which moving average length, trade signal, and position sizing makes you the most money.
Back Testing Result & Market to Market Account Chart
------Results:
Mid-Term 6 month
XLF / UYG IYR / URE
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 898 Percentage Price Data 901 Percentage
Net P&L $6,139.17 6.14% Net P&L $46,294.40 46.29%
Winning trades 19 55.88% Winning trades 38 73.08%
losing trades 15 44.12% losing trades 14 26.92%
Total Trades 34 Total Trades 52
Max Down -2.3808% Max Down -2.7293%
Max up 2.8235% Max up 2.7012%
XLF / FAS IWM / SMH
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 898 Percentage Price Data 903 Percentage
Net P&L $9,639.91 9.64% Net P&L $18,187.02 18.19%
Winning trades 17 54.84% Winning trades 34 82.93%
losing trades 14 45.16% losing trades 7 17.07%
Total Trades 31 Total Trades 41
Max Down -4.5232% Max Down -1.6654%
Max up 6.3077% Max up 1.9746%
17
18. VWO / FXI
Intial Portfolio $100,000.00
Price Data 906 Percentage
Net P&L $2,869.84 2.87%
Winning trades 25 64.10%
losing trades 14 35.90%
Total Trades 39
Max Down -2.8794%
Max up 2.9260%
Long Term 3 years
XLF UYG IYR URE
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 650 Percentage Price Data 656 Percentage
Net P&L $1,815,248.87 1815.25% Net P&L $15,483.82 15.48%
Winning trades 42 89.36% Winning trades 20 64.52%
losing trades 5 10.64% losing trades 11 35.48%
Total Trades 47 Total Trades 31
IWR IWP IWM SMH
Intial Portfolio $100,000.00 Intial Portfolio $100,000.00
Price Data 758 Percentage Price Data 758 Percentage
Net P&L $13,622.27 13.62% Net P&L $3,032.82 3.03%
Winning trades 82 77.36% Winning trades 13 46.43%
losing trades 24 22.64% losing trades 15 53.57%
Total Trades 106 Total Trades 28
Total Portfolio
Short Term 6 month
Intial 500000
End $583,130.34
Net P&L $83,130.34
Return 16.63%
Long Term 3 year
intial 400000
End $1,847,387.78
Net P&L $1,447,387.78
Return 361.85%
18
19. Daily Data Time
Short Term Market-to-Market Chart 6 month Interval
XLF / UYG
IYR / URE
XLF / FAS
IWM / SMH
19
20. VWO / FXI
Some Long Term Market-to-Market Chart to Compare make money during Market
Crsis 3 years
XLF / UYG
XLF / UYG
20
22. 3 Real Time Signal Generation
By pulling real time data from Bloomberg, I use the program keep doing the algorithm moving forward with the moving
average and standard deviation to generate the buy and sell signal, and then to calculate the P&L for each time step.
VBA Code:
' The program use the C++ inline function call itself in the subroutine
Public Sub Cal()
Worksheets("data").Range("ai2", "ai32773").Cells(Worksheets("data").Range("d2"), 1) =
Worksheets("data").Range("h8")
Worksheets("data").Range("aj2", "aj32773").Cells(Worksheets("data").Range("d2"), 1) =
Worksheets("data").Range("h5")
Worksheets("data").Range("ak2", "ak32773").Cells(Worksheets("data").Range("d2"), 1) =
Worksheets("data").Range("h9")
Worksheets("data").Range("al2", "al32773").Cells(Worksheets("data").Range("d2"), 1) =
Worksheets("data").Range("h6")
Worksheets("data").Range("a2", "a32773").Cells(Worksheets("data").Range("d2"), 1) = 0.5 *
(Worksheets("data").Range("ai2", "ai32773").Cells(Worksheets("data").Range("d2"), 1) +
Worksheets("data").Range("aj2", "aj32773").Cells(Worksheets("data").Range("d2"), 1))
Worksheets("data").Range("b2", "b32773").Cells(Worksheets("data").Range("d2"), 1) = 0.5 *
(Worksheets("data").Range("ak2", "ak32773").Cells(Worksheets("data").Range("d2"), 1) +
Worksheets("data").Range("al2", "al32773").Cells(Worksheets("data").Range("d2"), 1))
Worksheets("data").Range("c2", "c32773").Cells(Worksheets("data").Range("d2"), 1) = Now()
If Worksheets("data").Range("d2") > 52 Then
Call Clearputs
Call MainProgram
End If
Worksheets("data").Range("d2") = Worksheets("data").Range("d2") + 1
Application.OnTime Now + TimeValue(Worksheets("data").Range("d1").Value), "cal"
End Sub
22
23. 4. Long Term Statistic Hedging & Portfolio Management
1.) Equity Pairs with Daily Data
A. Pairs Historical Technique Research
Data Time Range: 97.01.02-----04.01.06
Equity Pairs:
WMT/COST (Wholesale) (Large Cap)
Close Correlation 0.29 COST
Change Correlation 0.98 WMT
Differential Ratio Closing
Spread
Mean -15.52 0.71 -0.01
Median -15.94 0.70 0.06
Mode -16.52 0.69 0.28
Average Deviation 4.89 0.09 1.06
Standard Deviation 6.25 0.11 1.57
Population Standard Deviation 6.25 0.11 1.57
Differential Moving Averages 90-Days 160-Days 250-Day
4.0000
3.0000
2.0000
1.0000
2002/11/25
2003/11/25
2002/1/25
2002/3/25
2002/7/25
2002/9/25
2003/3/25
2003/7/25
2002/5/25
2003/1/25
2003/5/25
2003/9/25
0.0000
-1.0000
-2.0000
-3.0000
-4.0000
-5.0000
WERN/YELL
Close Correlation 0.71 WERN 18.11
Change Correlation 0.93 YELL 14.25
23
24. Differential Ratio Closing
Spread
Mean -7.91 0.63 0.02
Median -7.32 0.63 0.01
Mode -7.54 0.55 0.00
Average Deviation 2.08 0.06 1.11
Standard Deviation 2.79 0.07 5.69
Population Standard Deviation 2.79 0.07 5.69
Differential Moving Averages 90-Days 160-Days 250-Day
4.0000
3.0000
2.0000
1997/11/2
1998/11/2
1997/9/2
1998/9/2
1997/1/2
1997/3/2
1997/5/2
1997/7/2
1998/1/2
1998/3/2
1998/5/2
1998/7/2
1.0000
0.0000
-1.0000
-2.0000
-3.0000
-4.0000
-5.0000
IP/BCC
Close Correlation 0.65 IP 43.6
Change Correlation 0.99 BCC 34.11
Differential Ratio Closing
Spread
Mean 7.36 1.27 0.00
Median 6.88 1.22 0.00
Mode 10.97 1.12 0.00
Average Deviation 3.10 0.13 0.37
Standard Deviation 3.58 0.16 0.52
Population Standard Deviation 3.57 0.16 0.52
24
25. Differential Moving Averages 90-Days 160-Days 250-Day
4.0000
3.0000
2002/11/25
2003/11/25
2.0000
2002/9/25
2003/1/25
2002/1/25
2002/3/25
2002/5/25
2002/7/25
2003/3/25
2003/5/25
2003/7/25
2003/9/25
1.0000
0.0000
-1.0000
-2.0000
-3.0000
-4.0000
-5.0000
EOG/BR
Close Correlation 0.18 EOG 24.62
Change Correlation 0.91 BR 47.39
Differential Ratio Closing
Spread
Mean -15.56 0.59 -0.03
Median -17.83 0.51 -0.03
Mode -21.03 0.48 0.24
Average Deviation 5.46 0.14 1.07
Standard Deviation 7.49 0.24 2.58
Population Standard Deviation 7.48 0.24 2.58
Differential Moving Averages 90-Days 160-Days 250-Day
14.0000
12.0000
10.0000
8.0000
6.0000
4.0000
1997/11/2
1998/11/2
1998/5/2
1998/9/2
1997/1/2
1997/3/2
1997/5/2
1997/7/2
1997/9/2
1998/1/2
1998/3/2
1998/7/2
2.0000
0.0000
-2.0000
-4.0000
B Model Building and Back-testing
Four Pairs I choose are (COST /WMT), (WERN/YELL), (IP/BCC ), (EOG/BR)
25
26. Basically, I choose the pairs who have high change correlation, and whose volatility ratio is
normal.
Also I choose the pair from lower P/E ratio and same industry.
Intial Portfolio for each Pair 1,000,000
By keeping changing the parameter, I get the P&L as follow:
P&L
singal 2 and -2 1.5 and -1.5 1 and -1
PL 1 Pair COST /WMT $1,545,782.67 $3,905,349.17 $8,728,578.15
Profits times 31.00
Loss times 18.00
Profit Factor 2.14
WERN/YELL $519,067.56 $38,854.94 $1,037,323.32
Profits times 28
Loss times 18
Profit Factor 2.136673883
IP/BCC $541,652.63 $1,577,210.95 $1,354,645.33
Profits times 28.00
Loss times 14.00
Profit Factor 2.00
EOG/BR $4,948,500.34 $43,238,730.73 $75,275,510.23
Profits times 33
Loss times 6
Profit Factor 6.109747295
C. Option Pairs with Daily Data
Based on the four pairs of equities in the first portfolio, I build the model the option pair trading in VBA,
The algorithm is hedging pairs by Delta to generate the buy or sell at the money call or put at different signal
point, which is generated by undervalued or overvalued spread price and undervalued or overvalued Volatility.
Finally, the result for the option pair trading is as follow
singal 2 and -2 1.5 and -1.5 1 and -1
PL 1 Pair $ $ $
COST /WMT $79,123,812.98 $195,563,930.76 $1,052,834,845.18
PL 1 Pair $ $
WERN/YELL $8,837,609.97 $22,812,164.42 $37,358,989.52
PL 1 Pair $ $
IP/BCC $311,899,424.76 $3,881,076,833.44 $5,738,904,258.93
PL 1 Pair
EOG/BR $88,426,672.09 $48,590,921,277.17 $16,269,381,046.76
26
27. Fixed Income Trading Strategies Portfolio
Notes: All VBA Codes for this projects are attached at the back of the project portfolio
For this project, I build the Macro in Excel by using VBA.
The process I did this as follow:
First, I calculate the Duration, Convexity and Yield for all 35 bonds, and I can also calculate more bonds if I
input more bonds. And I calculate the Net Duration, Convexity and Yield for project 1. And this is called
USTDurationCovex and Port1 in my VBA Code.
Portfolio at the last Day
Par Amount Duration Covexity Yield Date
1 $100,000,000 0.8405094 0.0044779 2009/4/2
3 $100,000,000 1.8750005 4.4611338 0.0086958 2009/4/2
5 $100,000,000 2.7898725 9.2461094 0.0128316 2009/4/2
7 $100,000,000 4.6631282 24.591889 0.0204651 2009/4/2
9 $100,000,000 8.0146283 74.796798 0.0308571 2009/4/2
11 $100,000,000 16.620428 386.4433 0.0403963 2009/4/2
Portfolio
1 $600,000,000 5.80 83.26 0.01962 2009/4/2
Second, I calculate all the carries and reverse carries per dollar trade in VBA and outputs in different excel
spreadsheets. And then obtain the short and long P&L for 1 dollar for all 35 bonds by adding Carry and Capital
gain. This Subroutine is called Carry.
The Trades I have done are as follow:
Curve Steepener, Curve Flattner, Butterfly, Basis, and Ted Spread.
Moreover, I begin to do the different trades, and get the P&L by picking the right P&L from what I have done
for all 35 bonds, and then multiply by the right par amount for each trade to get the P&L for all the trades at
each day. This Subroutine in VBA is called Trade.
Then, I change the par amount to 1 million for the 1st instrument of each trade and acquire another P&L for each
day, and calculate 2 standard deviation of 10 days P&L for each trade.
Finally, I start my money management approach as follow: I use the smallest Standard deviation one as a
benchmark to relocate my capital for each trade to get the P&L for the 10 days and I also obtain the P&L for the
last day which is 11th day on 5/8/2009.
The Result are:
With 1 million invested:
P&L for the last day on 5/8/2009
27
28. Curve
steepener $6,137.85
Curve
steepener $13,805.90
Curve
flattener ($6,684.14)
Curve
flattener ($6,848.30)
Butterfly $2,774.55
Butterfly ($3,982.31)
Butterfly $1,638.56
basis $714.78
basis $1,407.79
basis ($2,531.37)
basis $344.76
Ted 5253.70
Ted 30331.00
2 standard deviation is as follow:
Obviously, the first basis trade is the smallest one with same amount of capital invested.
curve steepener $7,106.72
curve steepener $3,520.22
curve flattener $3,962.01
curve flattener $16,100.59
Butterfly $7,019.99
Butterfly $16,004.25
Butterfly $3,964.93
basis $2,903.40
basis $3,521.72
basis $3,189.99
basis $4,632.61
Ted $4,174.64
Ted $69,036.64
After the 2 standard deviation adjustment, the P&L for the last day on 5/8/2009 is
curve
steepener $2,507.57
curve
steepener $11,386.80
curve
flattener ($4,898.20)
curve
flattener ($1,234.94)
Butterfly $1,147.53
Butterfly ($722.45)
Butterfly $1,199.86
28
32. Close
150
100
50
0
0 500 1000 1500 2000 2500
RSI
100
RSI
30
70
50
0
0 500 1000 1500 2000 2500
200
Close
Price
100 5-day Moving Average
20-day Moving Average
0
0 500 1000 1500 2000 2500
Stochastic %K%D
100
%K
50 %D
0
0 500 1000 1500 2000 2500
RSI
100
RSI
50 30
70
0
0 500 1000 1500 2000 2500
MATLAB CODE:
By Daniel (Fei) Wang
%We save the qqqq data as "data" in our folder and run the program.
32
33. clear all, clc
load data
open=data(:,1);
high=data(:,2);
low=data(:,3);
close=data(:,4);
s=size(data);
m=s(1,1);
nuMA=1;
nuKD=1;
nuRSI=1;
%I. Signal Generation
%1. By Moving Average: 5-day nd 20-day
%1.1 find moving average
%1.1.1 5-day moving average
close5=zeros(m,1);
for i=5:m
close5(i,1)=mean(close(i-4:i,1));
end
close5MX=[close,close5];
%1.1.2 20-day moving average
close20=zeros(m,1);
d=20;
d1=d+1;
d2=d-1;
for i=d:m
close20(i,1)=mean(close(i-d2:i,1));
end
MAMX=[close,close5,close20];
%1.2 Plot 5-day and 20-day Moving Average with close
%***since the first 19 periods are not applicable
MAplot=MAMX(d:end,:);
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
plot(MAplot)
ylabel('Price')
legend('Close','5-day Moving Average','20-day Moving Average')
%&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
%1.3 Generate signals by moving average
MAsig(1,1)=0;
for i=d1:m
if (close5(i)> close20(i))&&(close5(i-1)<= close20(i-1))
MAsig(i)=1;
elseif (close5(i)< close20(i))&&(close5(i-1)>= close20(i-1))
MAsig(i)=-1;
33
34. else
MAsig(i)=0;
end
end
MAsig=MAsig';
MAsig=nuMA*MAsig;
MAsigMX=[[1:m]',MAMX,MAsig];
%1.4 Number of MA signals
aMAsig=abs(MAsig);
numMAsig=sum(aMAsig);
%2. By Stochastic %K and %D
%*** we assume the time period is 14
p=14;
p1=p+1;%just helps to match matrixes
p2=p-1;%just helps to match matrixes
%2.1 Find the highest high and lowest low prices in each 14 periods
L14=zeros(m,1);
H14=zeros(m,1);
for i=p:m
L14(i,1)=min(low(i-13:i,1));
H14(i,1)=max(high(i-13:i,1));
end
%2.2 Calc %K
K=zeros(m,1);
for i=p:m
K(i,1)=100*(close(i,1)-L14(i,1))/(H14(i,1)-L14(i,1));
end
KMX=[high,low,close,L14,H14,K];
%2.3 Find %D, 3-period moving average
D=zeros(m,1);
p3=p+2;
for i=p3:m
D(i,1)=mean(K(i-2:i,1));
end
KDMX=[high,low,close,L14,H14,K,D];
%2.4 Plot %K and %D with close
KD=[K,D];
%*** since the first 14 periods are not applicable
KDplot=KD(p1:m,:);
KDclose=close(p1:m,:);
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
figure
subplot(2,1,1); plot(KDclose)
title('Close')
subplot(2,1,2); plot(KDplot)
title('Stochastic %K%D')
legend('%K','%D')
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
% 2.5 KD Signal Generation
34
35. KDsig=zeros(m,1);
p4=p+3;
for i=p4:m
if (K(i,1)>D(i,1))&&(K(i-1,1)<=D(i-1,1))
KDsig(i,1)=1;
elseif (K(i,1)<D(i,1))&&(K(i-1,1)>=D(i-1,1))
KDsig(i,1)=-1;
end
end
KDsig=nuKD*KDsig;
KDsigMX=[KDMX,KDsig];
%2.6 Numbers of KD signal
aKD=abs(KDsig);
numKDsig=sum(aKD);
%3. BY RSI,Relative Strength Index,
%technical momentum indicator that compares the magnitude of recent gains
%to recent losses in an attempt to determine overbought
%and oversold conditions of an asset.
%3.1 Calc the changes of the close prices
chg=zeros(m,1);
for i=2:m
chg(i,1)= close(i,1)-close(i-1,1);
end
chgMX=[close,chg];
%3.2 Seperate the advances and declines from the changes
adva=zeros(m,1);
decl=zeros(m,1);
for i=1:m
if chg(i,1)>0
adva(i,1)=chg(i,1);
elseif chg(i,1)<0
decl(i,1)=-chg(i,1);
end
end
adMX=[chgMX,adva,decl];
%3.3 Calc the average gains and average losses for 14 periods
p=14;
p1=p+1;%just helps to match matrixes
p2=p-1;%just helps to match matrixes
avggain=zeros(m,1);
avgloss=zeros(m,1);
avggain(p1,1)=mean(adva(2:p1,1));
avgloss(p1,1)=mean(decl(2:p1,1));
for i=16:m
avggain(i,1)= (avggain(i-1,1)*p2+adva(i,1))/p;
avgloss(i,1)=(avgloss(i-1,1)*p2+decl(i,1))/p;
end
avgMX=[adMX,avggain,avgloss];
%3.4 Calc RS
RS=zeros(m,1);
for i=p1:m
RS(i,1)=avggain(i,1)/avgloss(i,1);
end
%3.5 Calc RSI
35
36. RSI=zeros(m,1);
for i=p1:m
if avgloss==0
RSI(i,1)=100;
else
RSI(i,1)=100-(100/(1+RS(i,1)));
end
end
RSIMX=[close,chg,adva,decl,avggain,avgloss,RS,RSI];
%3.6 Plot the RSI with close
l30=30*ones(m,1);
l70=70*ones(m,1);
RSIband=[RSI,l30,l70];
%since the first 14 periods are not applicable
RSIclose=close(p1:m,1);
RSIplot=RSIband(p1:m,:);
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
figure
subplot(2,1,1); plot(RSIclose)
title('Close')
subplot(2,1,2); plot(RSIband)
title('RSI')
legend('RSI','30','70')
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
%3.7 RSI Signal Generation
RSIsig=zeros(m,1);
p3=p+2;
for i=p3:m
if (RSI(i,1)<70)&&(RSI(i-1,1)>70)
RSIsig(i,1)=-1;
elseif (RSI(i,1)>30)&&(RSI(i-1,1)<30)
RSIsig(i,1)=1;
end
end
RSIsig=nuRSI*RSIsig;
RSIsigMX=[RSIMX,RSIsig];
%3.8 numbers of RSI signal
aRSI=abs(RSIsig);
numRSIsig=sum(aRSI);
%4. Signal Combination
%4.1 Plot the three parameters in the same figure
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
figure
subplot(3,1,1);plot(MAplot)
ylabel('Price')
36
37. legend('Close','5-day Moving Average','20-day Moving Average')
subplot(3,1,2); plot(KDplot)
title('Stochastic %K%D')
legend('%K','%D')
subplot(3,1,3); plot(RSIband)
title('RSI')
legend('RSI','30','70')
%&&&&&&&PLOT&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&777777
%4.2 Combine sigals into one matrix
Allsig=[MAsig,KDsig,RSIsig];
AllsigMX=[close,Allsig];
for i=1:m
Tsig(i,1)=sum(Allsig(i,:));
end
TsigMX=[AllsigMX, Tsig];
%4.3 Only transition situations
sigMX=[[1:m]',close,Tsig];
sz=size(sigMX);
sz=sz(1,2);
trans=zeros(1,sz) ;
for i=2:m
if (Tsig(i)==1)||(Tsig(i)==-1)||(Tsig(i)==-2)||(Tsig(i)==2)||(Tsig(i)==3)||
(Tsig(i)==-3)
trans=[trans;sigMX(i,1:end)];
end
end
trans=trans(2:end,:);
%4.4 numbers of total trade signals
[numsig c]=size(trans);
clear c;
numsig;
%4.5 Considering that if the system provides more than one consecutive buy or
%sell signals, we need to modify our "trans" matrix to reflect this fact.
trsigOld=trans(:,end);
trsig=zeros(numsig,1);
trsig(1,1)=trsigOld(1,1);
for i=2:numsig
if trsigOld(i,1)*trsigOld(i-1,1)>0
trsig(i,1)=trsig(i-1,1)+trsigOld(i-1,1);
else
trsig(i,1)=trsigOld(i,1);
end
end
trsigMX=[trans,trsig];
%4.5 Therefore, we can create a new total signal list
newTsig=Tsig;
for i=1:numsig
j=trsigMX(i);
newTsig(j,1)=trsig(i);
end
newTsigMX=[sigMX,newTsig];
37
38. %5. P&L Calculation
%5.1 To find the P&L we need to find the profit of each trade
for i=1:numsig
mktvalue(i,1)=trsigMX(i,2)*trsigMX(i,4);
end
mktvalueMX=[trsigMX,mktvalue];
%5.2 to find the net profit of each trade
netprofit(1,1)=0;
for i=2:numsig
netprofit(i,1)=-(mktvalue(i,1)+mktvalue(i-1,1));
end
%for the position of 100
netprofit=netprofit*100;
netprofitMX=[trans,mktvalue,netprofit];
%6. to find the largest winning trade and largest losing trade
LargestWin=max(netprofit); %(1)
LargestLoss=min(netprofit); %(2)
%7. to find the number of wintrade and losstrade
numwin=0;
numloss=0;
for i=1:numsig
if netprofit(i,1)>0
numwin=numwin+1;
elseif netprofit(i,1)<0
numloss=numloss+1;
end
end
numwin; %(3)
numloss ;%(4)
%8. Find the GrossProfit and GrossLoss to calculate the Profit Factor
GrossProfit=0;
GrossLoss=0;
for i=1:numsig
if netprofit(i,1)>0
GrossProfit=GrossProfit+netprofit(i,1);
elseif netprofit(i,1)<0
GrossLoss=GrossLoss+netprofit(i,1);
end
end
GrossProfit;
GrossLoss;
CumuProfit=GrossProfit+GrossLoss;
ProfitFactor=GrossProfit/(-GrossLoss); %(5)
%9.Daily Mark-to-Market P&L and return
%to find the daily return, we first calculate the actual daily market value
%9.1 We make find our daily market position
actposi=zeros(m,1);
for i=2:m
if newTsig(i,1)==0
38
39. actposi(i,1)=actposi(i-1,1);
elseif ((newTsig(i,1)<-0.1)||(newTsig(i,1)>0.1))
actposi(i,1)=newTsig(i,1);
end
end
actposiMX=[newTsig,close,actposi];
%9.2 We make find our actual market values
%for 100 positions
acctvalue=close*100;
acctMX=[actposiMX,acctvalue];
%9.3 we calculate daily changes in our portfolio.
shortV=zeros(m,1);
longV=zeros(m,1);
for i=2:m
if acctMX(i-1,3)<0
shortV(i,1)=(acctMX(i,4)-acctMX(i-1,4))*acctMX(i-1,2);
elseif acctMX(i-1,3)>0
longV(i,1)=(acctMX(i,4)-acctMX(i-1,4))*acctMX(i-1,2);
end
end
acctMXX=[acctMX,longV,shortV];
%9.4 Daily Mark-to-Market P&L. Suppose our base is $1000000.
M2MPL=zeros(m,1);
M2MPL(1,1)=1000000;
for i=2:m
M2MPL(i,1)=longV(i,1)+shortV(i,1)+M2MPL(i-1,1);
end
M2MPLMX=[acctMXX,M2MPL];
%9.5 we calculate the daily returns based on the daily M2M P&L.
dayreturn=zeros(m,1);
for i=2:m
dayreturn(i,1)=(M2MPL(i,1)-M2MPL(i-1,1))/M2MPL(i-1,1);
end
dayreturnMX=[M2MPLMX,dayreturn];
% 10. Sharpe Ratio (6)
%
%We assume that the risk-free rate is 0.
stdday=std(dayreturn);
stdannual=sqrt(stdday^2*256);
ER=mean(dayreturn);
ERannual=ER*256;
%SharpeRatioDaily=ER/std
SharpeRatioAnnual=ERannual/stdannual;
%11.Sortino Ratio (7)
%
%We assume that the risk-free rate is 0.
%
%11.1 Annulized Downside Standard Deviation
downreturn=0;
39
40. for i=1:m
if dayreturn(i,1)<0
downreturn=[downreturn;dayreturn(i,1)];
end
end
downreturn=downreturn(2:end,:);
stddown=std(downreturn);
stddownannual=sqrt(stddown^2*256);
%11.2 Calculation of Sortino Ratio
SortinoRatioAnnual=ERannual/stddownannual;
%12.Expected Profit (8)
%(Average Profit*Probability of Profit-Average Loss*Probability of Loss) (8)
Gain=0;
Loss=0;
for i=1:numsig
if netprofit(i,1)>0
Gain=[Gain;netprofit(i,1)];
elseif netprofit(i,1)<0
Loss=[Loss;netprofit(i,1)];
end
end
Gain=Gain(2:end,:);
Loss=Loss(2:end,:);
AverageProfit=mean(Gain);
ProbabilityofProfit=numwin/(numwin+numloss);
AverageLoss=mean(Loss);
ProbabilityofLoss=numloss/(numwin+numloss);
ExpectedProfit=(AverageProfit*ProbabilityofProfit-AverageLoss*ProbabilityofLoss); %(8)
%13.Return Retracement Ratio(9)
%
%13.1 We first find R, average annual compounded return
S=M2MPL(1,1);%starting equity
E=M2MPL(end,1);%ending equity
N=m/256;
R=exp((1/N)*(log(E)-log(S)))-1;
%
%13.2 We calculate AMR
%
% We assume that each months has 22 trading days
%
%13.2.1 We find the equity at the end of each month.
monthend=[22:22:m]';
[monthnum w]=size(monthend);
clear w
Ei=zeros(monthnum,1);
for i=1:monthnum
j=monthend(i,1);
Ei(i,1)=M2MPL(j,1);
end
EiMX=[monthend, Ei];
%13.2.2 PEi and MEi
40
41. PEi=zeros(monthnum,1);
PEi(1,1)=Ei(1,1);
MEi=zeros(monthnum,1);
MEi(1,1)=min(Ei);
for i=2:monthnum
PEi(i,1)=max(Ei(1:i,1));
MEi(i,1)=min(Ei(i:end,1));
end
PEMEMX=[Ei, PEi,MEi];
%13.2.2 MRPP,MRSL and MR
MRPP=zeros(monthnum,1);
MRSL=zeros(monthnum,1);
MR=zeros(monthnum,1);
for i=1:monthnum
MRPP(i,1)=(PEi(i,1)-Ei(i,1))/PEi(i,1);
MRSL(i,1)=(Ei(i,1)-MEi(i,1))/Ei(i,1);
MR(i,1)=max(MRPP(i,1),MRSL(i,1));
end
MRMX=[MRPP,MRSL,MR];
%13.2.3 AMR
AMR=1/monthnum*(sum(MR));
%13.3 RRR
RRR=R/AMR;
%14. Calculate account mark-to-market P&L for each new price level
%(row in excel) (10)
AcctM2M=[M2MPLMX(:,1),M2MPLMX(:,3),M2MPLMX(:,2),M2MPLMX(:,5:end)];
%Result Summary
disp('Final Project II: Result Summary')
LargestLoss
LargestWin
numloss
numwin
ProfitFactor
SortinoRatioAnnual
ExpectedProfit
RRR
disp('Important Note:')
disp(' ')
disp('The account mark-to-market P&L is saved in the variable names ACCTM2M')
disp('Since it is really big,please type"AcctM2M" in MATLAB to see the matrix')
disp(' ')
disp('AcctM2M Column Labels:')
disp('TradeSignal, AccountPostion, Close, M2MValueChangeOfLong, M2MValueChangeOfShort,
M2MPL, M2MAccountValue')
41
42. Portfolio Optimization Model
---Efficiency Frontier by VBA
Results for Equity Portfolio:
Example Results:
Notes: Inputs can be changed to get different portfolio allocation results
Inputs:
ABT C GE IBM MSFT
Data: 05/02/97 to 05/01/07 Daily Close Price
30 points of Frontier
Add constraints
stock # min wt. max. wt.
1 -1 1
2 -1 1
42
43. 3 -1 1
4 -1 1
5 -1 1
Outputs:
Historical stock return data
Expected returns & volatility
stock # ticker E[r] σ
1 ABT 0.93% 6.36%
2 C 1.51% 8.48%
3 GE 0.91% 6.72%
4 IBM 1.20% 9.21%
5 MSFT 1.29% 10.93%
Variance-covariance matrix
ABT C GE IBM MSFT
ABT 0.40% 0.07% 0.10% 0.01% 0.06%
C 0.07% 0.72% 0.28% 0.42% 0.30%
GE 0.10% 0.28% 0.45% 0.26% 0.36%
IBM 0.01% 0.42% 0.26% 0.85% 0.53%
MSFT 0.06% 0.30% 0.36% 0.53% 1.20%
Efficiency Portfolio
14.00%
12.00%
10.00%
8.00%
Volatilities
6.00%
4.00%
2.00%
0.00%
0.00% 5.00% 10.00% 15.00% 20.00% 25.00%
Expected Returns
Minimum variance portfolio
weights
σp rp ABT C GE IBM MSFT Σw
4.83% 1.02% 0.4943 0.0873 0.2743 0.1424 0.0016 1
Frontier points
σp rp ABT C GE IBM MSFT Σw
1 4.83% 1.02% 0.4943 0.0873 0.2743 0.1424 0.0016
43
46. 13 122.57% 5.46% -9.9830 1.5000 -1.0000 1.0000 9.4830 1.0000
-11.024
14 135.12% 5.83% 7 1.5000 -1.0000 1.0000 10.5247 1.0000
-12.066
15 147.68% 6.20% 4 1.5000 -1.0000 1.0000 11.5664 1.0000
-13.108
16 160.25% 6.57% 1 1.5000 -1.0000 1.0000 12.6081 1.0000
-14.149
17 172.83% 6.94% 8 1.5000 -1.0000 1.0000 13.6498 1.0000
-15.191
18 185.42% 7.31% 5 1.5000 -1.0000 1.0000 14.6915 1.0000
-16.233
19 198.02% 7.68% 2 1.5000 -1.0000 1.0000 15.7332 1.0000
-17.274
20 210.62% 8.05% 9 1.5000 -1.0000 1.0000 16.7749 1.0000
-18.316
21 223.23% 8.42% 6 1.5000 -1.0000 1.0000 17.8166 1.0000
-19.358
22 235.84% 8.79% 3 1.5000 -1.0000 1.0000 18.8583 1.0000
-20.400
23 248.45% 9.16% 0 1.5000 -1.0000 1.0000 19.9000 1.0000
-21.441
24 261.07% 9.53% 9 1.5000 -1.0000 1.0000 20.9419 1.0000
-22.483
25 273.68% 9.90% 6 1.5000 -1.0000 1.0000 21.9836 1.0000
-23.525
26 286.30% 10.27% 0 1.5000 -1.0000 1.0000 23.0250 1.0000
-24.566
27 298.92% 10.64% 7 1.5000 -1.0000 1.0000 24.0667 1.0000
-25.608
28 311.55% 11.01% 7 1.5000 -1.0000 1.0000 25.1087 1.0000
-26.650
29 324.17% 11.38% 1 1.5000 -1.0000 1.0000 26.1501 1.0000
-27.692
30 336.80% 11.75% 1 1.5000 -1.0000 1.0000 27.1921 1.0000
Code:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''
'' Portfolio Effeciency Frontier VBA Code
'' Daniel (Fei) Wang
'' Financial Modeling Project
''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit
Dim j As Long, k As Integer
Dim NumReturns As Long, Numstocks As Integer
Dim rng_data As Range, rng_returns As Range, rng_returnticker As Range, rng_tickerlist As
Range, rng_tickerchoice As Range
Private Sub MakeAllVisible()
Dim wks As Worksheet, chrt As Chart
For Each wks In Worksheets
wks.Visible = xlSheetVisible
Next wks
For Each chrt In Charts
chrt.Visible = xlSheetVisible
Next chrt
End Sub
46
47. Public Sub MainProgram()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Call CalcStockReturns
Call CalcMeanReturns
Call CalcVolatilities
Call CalcCovarianceMatrix
Call MinVariance
Call ChoosePoints
End Sub
Public Sub CalcStockReturns()
Dim wks_wel As Worksheet, wks_data As Worksheet, wks_o As Worksheet, wks_returns As
Worksheet
Set wks_wel = Worksheets("Welcome")
Set wks_data = Worksheets("Stock Price Data")
Set wks_o = Worksheets("Optimization")
'Count how many Returns and Match the Date
Dim Date_1 As Double, Date_2 As Double, Rng_date As Range
Set wks_data = Worksheets("Stock Price Data")
Set Rng_date = wks_data.Range("A7", "A32773")
Set wks_returns = Worksheets("Returns")
Set rng_data = wks_data.Range("A6")
Set rng_returns = wks_returns.Range("A6")
Date_1 = Worksheets("Optimization").Range("D7").Value
Date_2 = Worksheets("Optimization").Range("D8").Value
Dim Sdate As Integer, Edate As Integer
Sdate = Application.WorksheetFunction.Match(Date_1, Rng_date, 0)
Edate = Application.WorksheetFunction.Match(Date_2, Rng_date, 0)
NumReturns = Edate - Sdate + 1
wks_returns.Range("A5").Value = NumReturns
'input selected dates
For j = 0 To NumReturns - 1
rng_returns.Offset(j + 1, 0).Value = rng_data.Offset(j + Sdate, 0).Value
Next j
'input date and ticker title
For k = 0 To 5
rng_returns.Offset(0, k) = rng_data.Offset(0, k)
Next k
For j = 1 To NumReturns - 1
'calculate first column of expected return
For k = 1 To 5
rng_returns.Offset(j + 1, k) = ((rng_data.Offset(j + 1 + (Sdate - 1), k) -
rng_data.Offset(j + (Sdate - 1), k)) / rng_data.Offset(j + (Sdate - 1), k))
Next k
Next j
End Sub
47
48. Public Sub CalcMeanReturns()
Dim wks_wel As Worksheet, wks_data As Worksheet, wks_o As Worksheet, wks_returns As
Worksheet
Set wks_wel = Worksheets("Welcome")
Set wks_data = Worksheets("Stock Price Data")
Set wks_o = Worksheets("Optimization")
Set wks_returns = Worksheets("Returns")
Dim i As Integer, j As Integer, k As Integer, rng_in As Range, rng_out As Range,
rng_returnticker As Range, rng_tickerlist As Range, rng_tickerchoice As Range
Set rng_in = wks_returns.Range("A8")
Set rng_out = wks_returns.Range("H7")
Set rng_returnticker = wks_returns.Range("H6")
Set rng_tickerlist = Worksheets("Optimization").Range("C32")
Set rng_tickerchoice = Worksheets("Optimization").Range("D12")
For i = 1 To 5
'Calculate annual mean on the "Return" worksheet ( paste the result of the calculation of
the Average return to 5 right columns)
With Worksheets("returns")
rng_out.Cells(1, i) = Application.WorksheetFunction.Average(Range(rng_in.Offset(0,
i), rng_in.Offset(0, i).End(xlDown)))
rng_returnticker.Cells(1, i) = wks_returns.Range("A6").Offset(0, i) '
Worksheets("Returns").Range("G7").Value = "Mean"
End With
'Display and Pasta the ticker list base on the user's choice
With Worksheets("Optimization")
rng_tickerlist.Cells(i, 1).Value = rng_tickerchoice.Cells(i, 1).Value
End With
Next i
'Paste return base on the tickerlist, match the tickerlist("optimization") with the
tickers from the ("returns")
'if value is the same, so paste the expected return to the right column
With Worksheets("Optimization")
For j = 1 To 5
For k = 1 To 5
If rng_tickerlist.Cells(k, 1).Value = rng_returnticker.Cells(1, j).Value Then
''Macth the ticker name on the optimization sheet From the return sheet
rng_tickerlist.Cells(k, 2).Value = rng_returnticker.Cells(2, j).Value
ElseIf rng_tickerlist.Cells(k, 1).Value = 0 Then
'Leave the cell to be blank
rng_tickerlist.Cells(k, 2).Value = 0
End If
Next k
Next j
End With
End Sub
Public Sub CalcVolatilities()
Dim i As Integer, j As Integer, k As Integer, rng_in As Range, rng_out As Range,
rng_returnticker As Range, rng_tickerlist As Range
Dim wks_optimization As Worksheet, wks_returns As Worksheet
Set wks_returns = Worksheets("returns")
Set wks_optimization = Worksheets("Optimization")
Set rng_in = wks_returns.Range("A8")
Set rng_out = wks_returns.Range("H8")
48
49. Set rng_tickerlist = wks_optimization.Range("C32")
Set rng_returnticker = wks_returns.Range("H6")
'on the return worksheet to caculate the Volatilities and paste to the 5 right Columns
With wks_returns
.Range("G8").Value = "Volatilities"
For i = 1 To 5
rng_out.Cells(1, i) = Application.WorksheetFunction.StDevP(Range(rng_in.Offset(0,
i), rng_in.Offset(0, i).End(xlDown)))
'rng_out.Cells(1, i) = Application.WorksheetFunction.StDevP(rng_in.Offset(0, i),
rng_in.Offset(0, i).End(xlDown))
Next i
End With
'Paste volatilities base on the tickerlist, match the tickerlist("optimization") with the
tickers from the ("returns")
'if value is the same, so paste the Volatilities to the second right column
With Worksheets("Optimization")
For j = 1 To 5
For k = 1 To 5
If rng_tickerlist.Cells(k, 1).Value = rng_returnticker.Cells(1, j).Value Then
rng_tickerlist.Cells(k, 3).Value = rng_returnticker.Cells(3, j).Value
ElseIf rng_tickerlist.Cells(k, 1).Value = 0 Then
rng_tickerlist.Cells(k, 3).Value = 0
End If
Next k
Next j
End With
End Sub
Private Sub CalcCovarianceMatrix()
Dim i As Integer, j As Integer, k As Integer, p As Integer, m As Integer, n As Integer, o
As Integer, Numstocks As Integer
Dim rng_in As Range, rng_out As Range, rng_tickerlist As Range, rng_ticker As Range,
rng_matrix As Range
Dim wks_optimization As Worksheet, wks_returns As Worksheet
Dim rng1 As Range, rng2 As Range, rng_Stickerlist As Range, rng_Htickerlist As Range
Dim tickers As Range
Set wks_optimization = Worksheets("Optimization")
Set wks_returns = Worksheets("returns")
Set rng_in = wks_returns.Range("A8")
Set rng_out = wks_returns.Range("H10")
Set rng_ticker = wks_returns.Range("G10", "G14")
Set rng_tickerlist = wks_optimization.Range("C32")
Set rng_matrix = wks_optimization.Range("H32")
'get the row and column name for the return matrix on the optimization Sheet
For o = 1 To 5
Set rng_Stickerlist = wks_optimization.Range("G32")
Set rng_Htickerlist = wks_optimization.Range("H31")
rng_Stickerlist.Cells(o, 1).Value = rng_tickerlist.Cells(o, 1).Value
rng_Htickerlist.Cells(1, o).Value = rng_tickerlist.Cells(o, 1).Value
Next o
'Caculate the return matrix for five Stocks on the return sheet
For j = 1 To 5
Set rng1 = Range(rng_in.Offset(0, j), rng_in.Offset(0, j).End(xlDown))
For i = 1 To 5
Set rng2 = Range(rng_in.Offset(0, i), rng_in.Offset(0, i).End(xlDown))
49
50. rng_out.Cells(j, i) = Application.WorksheetFunction.Covar(rng1, rng2)
Next i
rng_out.Offset(j - 1, -1) = rng_in.Offset(-2, j)
rng_out.Offset(-1, j - 1) = rng_in.Offset(-2, j)
Next j
'paste the return Matrix based on the users' choice
Dim a As Integer, b As Integer
For n = 1 To 5
For m = 1 To 5
If rng_matrix.Offset(-1, n - 1).Value = rng_out.Offset(-1, m - 1).Value Then
For a = 1 To 5
For b = 1 To 5
If rng_matrix.Offset(a - 1, -1).Value = rng_out.Offset(b - 1, -1).Value Then
rng_matrix.Cells(a, n).Value = rng_out.Cells(b, m).Value
End If
Next b
Next a
End If
Next m
Next n
End Sub
Sub ClearOutputs()
Worksheets("Optimization").Activate
Range(Range("C32"), Range("E36")).ClearContents
Range(Range("G31"), Range("L36")).ClearContents
Range(Range("E40"), Range("I40")).ClearContents
Range(Range("E43"), Range("I43")).ClearContents
Dim rng_WholeMatrix As Range, i As Integer
Set rng_WholeMatrix = Range("H32")
For i = 1 To 5
For j = 1 To 5
rng_WholeMatrix.Cells(j, i).Value = 0
Next j
Next i
Range(Range("C41"), Range("J41")).ClearContents
Range(Range("C44").Offset(0, 0),
Range("C44").End(xlDown).End(xlToRight)).ClearContents
Worksheets("Returns").Activate
Worksheets("Returns").Cells.Clear
Charts("Frontier Chart").Visible = False
End Sub
Sub ClearInputs()
Range(Range("D7"), Range("D8")).ClearContents
Range(Range("D12"), Range("D16")).ClearContents
Range(Range("H12"), Range("I16")).ClearContents
Range("C19").ClearContents
Charts("Frontier Chart").Visible = False
End Sub
Sub ClearAll()
Call ClearInputs
Call ClearOutputs
End Sub
50
51. Private Sub MinVariance()
Dim i As Integer, j As Integer, n As Integer, Numstocks As Integer, index As Integer
Dim MinVarWts As Range, rng_tickerlist As Range, ExpReturns As Range, CovarMatrix As
Range, MinVarRet As Range, MinVar As Range
Dim WName As Range ' rng_Dataticker As Range
'Set rng_Dataticker = Worksheets("stock price data").Range("B6", "F6")
Set rng_tickerlist = Worksheets("Optimization").Range("C32", "C36")
'Count stocks available, use worksheet countBlank Function
n = Application.WorksheetFunction.CountBlank(rng_tickerlist)
Numstocks = 5 - n
Set WName = Worksheets("Optimization").Range("E40")
Set MinVarWts = Worksheets("Optimization").Range(Range("E41"), Range("E41").Cells(1,
Numstocks))
Set ExpReturns = Worksheets("Optimization").Range(Range("D32"),
Range("D32").Cells(Numstocks, 1))
Set CovarMatrix = Worksheets("Optimization").Range(Range("H32"),
Range("H32").Cells(Numstocks, Numstocks))
Set MinVarRet = Worksheets("Optimization").Range("D41")
Set MinVar = Worksheets("Optimization").Range("C41")
'Paste Stock Names based on the user's selection
Dim m As Integer
For m = 1 To 5
WName.Cells(1, m) = rng_tickerlist.Cells(m, 1)
WName.Cells(4, m) = rng_tickerlist.Cells(m, 1)
Next m
'Dim a As Integer
'For a = 1 To 5
'If WName.Cells(1, a) = 0 Then
'WName.Cells(1, a).Select
'Selection.Delete Shift:=xlToLeft
'End If
'Next a
With Worksheets("Optimization")
'Input initial weights equally
With rng_tickerlist
For i = 1 To 5
If .Cells(i, 1) <> 0 Then
MinVarWts.Cells(1, i) = 1 / Numstocks
Else
MinVarWts.Cells(1, i) = 0
End If
Next i
End With
'Find the first selected stock's index
' With Range("MinVarWts")
' For j = 1 To 5
' If .Cells(1, j) <> 0 Then
' index = j
' Exit For
' End If
'
' Next j
'
' End With
MinVarRet.FormulaArray = "=sumproduct(Transpose(MinVarWts), ExpReturns)"
51
52. MinVar.FormulaArray = "=(MMult(MinVarWts ,MMult(CovarMatrix, Transpose(MinVarWts))))^0.5"
Range("J41").FormulaR1C1 = "=SUM(MinVarWts)"
Range(Range("E41").Cells(1, 1), Range("E41").Cells(1, 1 + Numstocks - 1)).Name = "MinWts"
'Range("J41").Value = Application.WorksheetFunction.Sum(Range("E41"), Range("F41"),
Range("G42"), Range("H42"), Range("I42"))
SolverReset
SolverOk SetCell:=Range("MinVar"), MaxMinVal:=2, ByChange:=("MinVarWts")
solveradd cellref:=Range("J41"), Relation:=2, FormulaText:=1.00000000001
SolverOptions AssumeNonNeg:=False
SolverSolve UserFinish:=True
End With
End Sub
Private Sub ChoosePoints()
Dim Wts2 As Range, Exp2 As Range, Stdev2 As Range, rng_tickerlist As Range, ExpReturns As
Range
Dim h As Integer, i As Integer, j As Integer, k As Integer, Point As Integer, n As
Integer, Numstocks As Integer, index As Integer
Set Wts2 = Worksheets("Optimization").Range("E45")
Set Exp2 = Worksheets("Optimization").Range("D45")
Set rng_tickerlist = Worksheets("Optimization").Range("C32", "C36")
Set ExpReturns = Worksheets("Optimization").Range("D32", "D36")
'use the count Blank Founction to get the number of the stocks the user's choice
n = Application.WorksheetFunction.CountBlank(rng_tickerlist)
Numstocks = 5 - n
'Choose points on frontier
Point = Worksheets("Optimization").Range("NumPoints").Value
With Worksheets("Optimization")
'Copy the min variance row result first
For i = 1 To 7
.Range("C44").Cells(1, i) = .Range("C41").Cells(1, i)
Next i
For i = 1 To Point - 1
'Setting initial weights for every point
For k = 1 To 5
If Range("C32").Cells(k, 1) <> 0 Then
Range("MinVarWts").Cells(i + 4, k) = 1 / Numstocks
Else
Range("MinVarWts").Cells(i + 4, k) = 0
End If
Next k
'Range("J41").Cells(3 + i, 1).Value =
Application.WorksheetFunction.Sum(Range("E44").Cells(i, 1), Range("E44").Cells(i, 5))
'Find the first selected stock's index
' With Range("MinVarWts")
' For j = 1 To 5
' If .Cells(1, j) <> 0 Then
' index = j
' Exit For
52
53. ' End If
' Next j
' End With
Dim SumW As Range
Set SumW = Worksheets("Optimization").Range("J45")
Set Stdev2 = Worksheets("Optimization").Range("C45")
'Name every row of weights
Range(Stdev2.Cells(i, 3), Stdev2.Cells(i, 7)).Name = "Weight" & (i + 1)
'Input formula for Stdev cell
Stdev2.Cells(i, 1).FormulaArray = "= MMult(Weight" & (i + 1) & ", MMult(CovarMatrix,
Transpose(Weight" & (i + 1) & ")))^0.5 "
'Adding Expected Returns by Ascending sequence as Target
Range("D45").Offset(i - 1, 0) = Range("D45").Offset(i - 2, 0) + 0.0037
'For expected returns which should be adjusted
Range("K41").Offset(i + 3, 0).FormulaArray = "=sumproduct(transpose(Weight" & (i + 1)
& "), ExpReturns)"
'Name every row of weights with non-zero value (for solver adjusting)
Range(Range("E45").Cells(i, 1), Range("E45").Cells(i, 1 + Numstocks - 1)).Name =
"Wts" & (i + 1)
'Input formula for sum of the weights
SumW.Cells(i, 1).Formula = "=Sum(Weight" & (i + 1) & ")"
'solver efficient frontier
SolverReset
SolverOk SetCell:=Range("MinVar").Offset(i + 3, 0), MaxMinVal:=2, ByChange:=("Wts" & (i +
1) & "")
solveradd cellref:=Range("J41").Offset(i + 3, 0), Relation:=2, FormulaText:=1.00000000001
solveradd cellref:=Range("K41").Offset(i + 3, 0), Relation:=2,
FormulaText:=Range("MinVarRet").Offset(i + 3, 0)
Dim c As Integer
For c = 1 To Numstocks
If Range("H12").Cells(c, 1) <> "" Then
solveradd cellref:=Range("E45").Cells(i, c), Relation:=3,
FormulaText:=Range("H12").Cells(c, 1).Address
End If
If Range("H12").Cells(c, 2) <> "" Then
solveradd cellref:=Range("E45").Cells(i, c), Relation:=1,
FormulaText:=Range("H12").Cells(c, 2).Address
End If
Next c
'Add constraints
' For h = 1 To Numstocks
' If Range("H12").Cells(h, 1) <> "" And Range("H12").Cells(h, 2) <> "" Then
' SolverAdd CellRef:=Range("E41").Offset(i + 3, h - 1), Relation:=3,
FormulaText:=Range("H12").Cells(h, 1).Address
' SolverAdd CellRef:=Range("E41").Offset(i + 3, h - 1), Relation:=1,
FormulaText:=Range("H12").Cells(h, 2).Address
'
' ElseIf Range("H12").Cells(h, 1) = "" And Range("H12").Cells(h, 2) <> "" Then
' SolverAdd CellRef:=Range("E41").Offset(i + 3, h - 1), Relation:=1,
FormulaText:=Range("H12").Cells(h, 2).Address
' ElseIf Range("H12").Cells(h, 1) = "" And Range("H12").Cells(h, 2) <> "" Then
' SolverAdd CellRef:=Range("E41").Offset(i + 3, h - 1), Relation:=1,
FormulaText:=Range("H12").Cells(h, 1).Address
53
54. ' Else
' Exit For
' End If
' Next h
SolverOptions AssumeNonNeg:=False
SolverSolve UserFinish:=True
Range("K41").Offset(i + 3, 0).ClearContents
Next i
End With
Charts("Frontier Chart").Visible = True
Charts("Frontier Chart").Activate
End Sub
54
55. Final Report For Market Risk Management
Problem (1) Very Simple Portfolio VaR:
First, we begin to manage our data:
From the raw data, we found the TSE 3000 is in CAD currency, so we change the TSE 3000 into the US Dollar by
applying the CAD/USD exchange rate. ( TSE 3000 in USD = TSE in CAD / exchange rate CAD/USD )
Chart 1 -----Percentage Movement of the Data
250
200
S&P500
150 T-Bill
$/Yen
100 Oil Price
TSE300(USD)
50
0
1 97 193 289 385 481 577 673 769 865 961 1057 1153 1249
From the chart 1, we plot the percentage term of the data to check there is no serious jump in the data. Then for each
instrument, we calculate the log return for the time series data and access five columns of log returns for these assets.
Moreover, I plot these returns data separately as follow to find the trend of the data:
55