HSG-MCS-HS21_Julia/Problemsets/PS05_TradingStrategy_Solution.ipynb

316 lines
167 KiB
Plaintext
Raw Normal View History

2021-11-15 20:14:51 +00:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"printyellow (generic function with 1 method)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"using Printf, Dates, Statistics, DelimitedFiles, StatsBase\n",
"\n",
"include(\"jlFiles/printmat.jl\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"using Plots\n",
"\n",
"gr(size=(480,320))\n",
"default(fmt = :svg)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Load Data"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(10340, 25)"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = readdlm(\"Data/25_Portfolios_5x5_Daily.CSV\",',',skipstart=1) #daily return data\n",
"ym = round.(Int,x[:,1]) #yearmonthday, like 20071231\n",
"\n",
"dN = Date.(string.(ym),\"yyyymmdd\") #covert to Julia date, eg. 2001-12-31\n",
"\n",
"\n",
"vv = Date(1980,1,1) .<= dN .<= Date(2020,12,31) #pick out the correct sample\n",
"ym = ym[vv]\n",
"R = x[vv,2:end] #returns\n",
"\n",
"(T,n) = size(R) #number of data points, number of assets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Task 1: Two Simple Strategies\n",
"\n",
"`R_1`: go long each of asset 1-24 (each with the weight 1/24) and short asset 25\n",
"\n",
"`R_2`: go long asset 1 and short asset 25\n",
"\n",
"The returns of these portfolios are easy to calculate without having to explicitly construct the portfolio weights, but it still a good preparation for later to do the explicit calculations as follows:\n",
"\n",
"1. Construct the vector of portfolio weights `w`\n",
"2. The portfolio return in `t` is `w'*R[t,:]`.\n",
"\n",
"Also, do not be afraid of loops: they are quick.\n",
"\n",
"Show means and standard deviations of the two strategies. Annualize the mean by `*252` and the standard deviation by `*sqrt(252)`.\n",
"\n",
"Plot histograms with bins that are 0.25 wide. (Don't annualize anything in the histograms.)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"w1 = [ones(24)/24;-1] #static\n",
"w2 = [1;zeros(23);-1]\n",
"\n",
"(R_1,R_2) = (fill(NaN,T),fill(NaN,T))\n",
"for t = 1:T \n",
" R_1[t] = w1'*R[t,:]\n",
" R_2[t] = w2'*R[t,:]\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" R_1 R_2\n",
"mean -0.348 -8.665\n",
"std 13.860 18.996\n",
"SR -0.025 -0.456\n",
"\n"
]
}
],
"source": [
"R_all = [R_1 R_2]\n",
"\n",
"μ = mean(R_all,dims=1)*252\n",
"σ = std(R_all,dims=1)*sqrt(252)\n",
"SR = μ./σ\n",
"\n",
"printmat([μ;σ;SR],colNames=[\"R_1\",\"R_2\"],rowNames=[\"mean\",\"std\",\"SR\"])"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"480\" height=\"320\" viewBox=\"0 0 1920 1280\">\n<defs>\n <clipPath id=\"clip200\">\n <rect x=\"0\" y=\"0\" width=\"1920\" height=\"1280\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip200)\" d=\"\nM0 1280 L1920 1280 L1920 0 L0 0 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip201\">\n <rect x=\"384\" y=\"0\" width=\"1345\" height=\"1280\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip200)\" d=\"\nM151.798 1169.65 L1872.76 1169.65 L1872.76 123.472 L151.798 123.472 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip202\">\n <rect x=\"151\" y=\"123\" width=\"1722\" height=\"1047\"/>\n </clipPath>\n</defs>\n<polyline clip-path=\"url(#clip202)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 374.091,1169.65 374.091,123.472 \n \"/>\n<polyline clip-path=\"url(#clip202)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 693.184,1169.65 693.184,123.472 \n \"/>\n<polyline clip-path=\"url(#clip202)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 1012.28,1169.65 1012.28,123.472 \n \"/>\n<polyline clip-path=\"url(#clip202)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 1331.37,1169.65 1331.37,123.472 \n \"/>\n<polyline clip-path=\"url(#clip202)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 1650.46,1169.65 1650.46,123.472 \n \"/>\n<polyline clip-path=\"url(#clip200)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 151.798,1169.65 1872.76,1169.65 \n \"/>\n<polyline clip-path=\"url(#clip200)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 374.091,1169.65 374.091,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip200)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 693.184,1169.65 693.184,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip200)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1012.28,1169.65 1012.28,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip200)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1331.37,1169.65 1331.37,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip200)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1650.46,1169.65 1650.46,1150.75 \n \"/>\n<path clip-path=\"url(#clip200)\" d=\"M328.154 1209.65 L357.83 1209.65 L357.83 1213.59 L328.154 1213.59 L328.154 1209.65 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip200)\" d=\"M368.732 1222.54 L376.371 1222.54 L376.371 1196.18 L368.061 1197.85 L368.061 1193.59 L376.325 1191.92 L381.001 1191.92 L381.001 1222.54 L388.64 1222.54 L388.64 1226.48 L368.732 1226.48 L368.732 1222.54 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip200)\" d=\"M408.084 1195 Q404.473 1195 402.644 1198.56 Q400.839 1202.11 400.839 1209.23 Q400.839 1216.34 402.644 1219.91 Q404.473 1223.45 408.084 1223.45 Q411.718 1223.45 413.524 1219.91 Q415.353 1216.34 415.353 1209.23 Q415.353 1202.11 413.524 1198.56 Q411.718 1195 408.084 1195 M408.084 1191.29 Q413.894 1191.29 416.95 1195.9 Q420.028 1200.48 420.028 1209.23 Q420.028 1217.96 416.95 1222.5
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt = histogram( R_1,bins = -12:0.25:12,normalize=true,legend=false,title=\"strategy 1\" )\n",
"display(plt)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"480\" height=\"320\" viewBox=\"0 0 1920 1280\">\n<defs>\n <clipPath id=\"clip240\">\n <rect x=\"0\" y=\"0\" width=\"1920\" height=\"1280\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip240)\" d=\"\nM0 1280 L1920 1280 L1920 0 L0 0 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip241\">\n <rect x=\"384\" y=\"0\" width=\"1345\" height=\"1280\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip240)\" d=\"\nM151.798 1169.65 L1872.76 1169.65 L1872.76 123.472 L151.798 123.472 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip242\">\n <rect x=\"151\" y=\"123\" width=\"1722\" height=\"1047\"/>\n </clipPath>\n</defs>\n<polyline clip-path=\"url(#clip242)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 374.091,1169.65 374.091,123.472 \n \"/>\n<polyline clip-path=\"url(#clip242)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 693.184,1169.65 693.184,123.472 \n \"/>\n<polyline clip-path=\"url(#clip242)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 1012.28,1169.65 1012.28,123.472 \n \"/>\n<polyline clip-path=\"url(#clip242)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 1331.37,1169.65 1331.37,123.472 \n \"/>\n<polyline clip-path=\"url(#clip242)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:2; stroke-opacity:0.1; fill:none\" points=\"\n 1650.46,1169.65 1650.46,123.472 \n \"/>\n<polyline clip-path=\"url(#clip240)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 151.798,1169.65 1872.76,1169.65 \n \"/>\n<polyline clip-path=\"url(#clip240)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 374.091,1169.65 374.091,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip240)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 693.184,1169.65 693.184,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip240)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1012.28,1169.65 1012.28,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip240)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1331.37,1169.65 1331.37,1150.75 \n \"/>\n<polyline clip-path=\"url(#clip240)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1650.46,1169.65 1650.46,1150.75 \n \"/>\n<path clip-path=\"url(#clip240)\" d=\"M328.154 1209.65 L357.83 1209.65 L357.83 1213.59 L328.154 1213.59 L328.154 1209.65 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip240)\" d=\"M368.732 1222.54 L376.371 1222.54 L376.371 1196.18 L368.061 1197.85 L368.061 1193.59 L376.325 1191.92 L381.001 1191.92 L381.001 1222.54 L388.64 1222.54 L388.64 1226.48 L368.732 1226.48 L368.732 1222.54 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip240)\" d=\"M408.084 1195 Q404.473 1195 402.644 1198.56 Q400.839 1202.11 400.839 1209.23 Q400.839 1216.34 402.644 1219.91 Q404.473 1223.45 408.084 1223.45 Q411.718 1223.45 413.524 1219.91 Q415.353 1216.34 415.353 1209.23 Q415.353 1202.11 413.524 1198.56 Q411.718 1195 408.084 1195 M408.084 1191.29 Q413.894 1191.29 416.95 1195.9 Q420.028 1200.48 420.028 1209.23 Q420.028 1217.96 416.95 1222.5
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt = histogram( R_2,bins = -12:0.25:12,normalize=true,legend=false,title=\"strategy 2\" )\n",
"display(plt)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Task 2: Another Trading Strategy\n",
"\n",
"We now do simple volatility based trading strategy.\n",
"\n",
"1. Find the 3 least volatile assets over `t-22:t-1` and give each a portfolio weight `w[t,i]=1/3`. \n",
"\n",
"2. Find the 3 most volatile assets over `t-22:t-1` and give each a portfolio weight `w[t,i]=-1/3`. \n",
"\n",
"3. The portfolio return in `t` is `w[t,:]'*R[t,:]`.\n",
"\n",
"4. Compare the average and std (annualized) with the previous portfolios, over periods `23:T`\n",
"\n",
"Hint: `v = sortperm(x)` gives indices such that `v[1:2]` are the indices of the lowest 2 elements in x. Try `sortperm([12,11,13])` to see."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 2 \n",
" 1 \n",
" 3 \n",
"\n",
" 2 \n",
" 1 \n",
"\n"
]
}
],
"source": [
"v = sortperm([12,11,13])\n",
"printmat(v)\n",
"printmat(v[1:2])"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"σ_moving = fill(NaN,T,n)\n",
"for t = 22:T\n",
" σ_moving[t,:] = std(R[t-21:t,:],dims=1)\n",
"end "
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-0.36666666666666664"
]
}
],
"source": [
"m = 3 #number of long/short positions \n",
"\n",
"R_3 = fill(NaN,T)\n",
"for t = 23:T #loop over periods, save portfolio returns\n",
" #local s,w #local/global is needed in script\n",
" s = sortperm(σ_moving[t-1,:])\n",
" w = zeros(n)\n",
" w[s[1:m]] .= 1/m\n",
" w[s[end-m+1:end]] .= -1/m\n",
" R_3[t] = w'R[t,:]\n",
"end\n",
"\n",
"print(R_3[23])"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" R_1 R_2 Vol sort\n",
"avg return -0.281 -8.739 3.628\n",
"std 13.867 19.002 14.867\n",
"SR -0.020 -0.460 0.244\n",
"\n"
]
}
],
"source": [
"R_all = [R_1[23:end] R_2[23:end] R_3[23:end]]\n",
"\n",
"μ = mean(R_all,dims=1)*252\n",
"σ = std(R_all,dims=1)*sqrt(252)\n",
"SR = μ./σ\n",
"\n",
"printmat([μ;σ;SR],colNames=[\"R_1\",\"R_2\",\"Vol sort\"],rowNames=[\"avg return\",\"std\",\"SR\"])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"@webio": {
"lastCommId": null,
"lastKernelId": null
},
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Julia 1.7.0-rc1",
"language": "julia",
"name": "julia-1.7"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}