♬ 國立臺灣大學管理學院資訊管理學系 程式設計期末報告♪
國立臺灣大學管理學院資訊管理學系
程式設計期末報告
Department of Information Management
College of Management
National Taiwan University
Program Design
Final Report
选择权定价与交易策略
Option evaluation and trading strategy
Chris Zhichao Chi
國際企業系三年級T99704283
指導教授:洪瑞文 博士
Advisor: Hong, Ph.D.
中華民國100年6月
June, 2011
目 錄
中文摘要: 2
Abstract: 2
1. Introduction 2
2. Assumptions 3
3. Trading strategy 3
4. Data & Results 4
1) A list of all available strikes for each day 4
2) A list of all available expirations for each day 5
3) A list of all trades each day and profit from each trade 5
4) Total Profit at the end of each day, Total Profit for the entire trading period 6
5) Percentage profit for each trade 6
6) Profitability Analysis 7
5. APPEN DIX1: Optionclass.H source code : 7
6. APPENDIX 2: Main Project Source Code: 11
7. Reference 21
中文摘要:
本篇报告主要研究如何通过C++的语言来进行选择权的定价,并且在一定的假设条件下,通过程式交易计算选择权交易的最优策略。
关键词:选择权 C++程式 定价 交易 最优 策略
Abstract:
in this report, we try to evaluate the option price using the Black-Scholes Option Pricing Model ,and discuss the optimal trading strategy under some given assumptions.
Key words: option C++language pricing trading optimal strategy
1. Introduction
In this project, we try to write the Black-Scholes Model function and use it in the option price evaluation and trading strategy. We use a crowd of specific option trading data to serve the materials, and create an “optionclass. H” profile to handle all the material data and prepare to be used by the main project. We discuss our optimal trading strategy in the main project, which achieve under some given conditions.
2. Assumptions
We can only trade one type of option one time in the day.
We only buy options (short index) to get the maximum return since selling option requires buying index, which is too costly.
We can keep buying options as long as we have available funds.
We cannot invest the money we get from shorting the index.
We only hold one type of option at a time. This is a natural result of our previous assumption in addition to our trading strategy ensuring that the option we pick (we invest all our money in it) is the most profitable one.
3. Trading strategy
Firstly, we assume we buy the option at time t and we calculate the return for each available selling point (transactions with the same strike) after t. Secondly we compare the return of those selling points and pick the maximum payoff as the maximal return for the option. Thirdly, we buy the option with the highest return and proceed to find the next most profitable options.
Suppose we buy the optimal option at s and sell it at t, according to our assumptions, we only hold that option during time s and t. Then our first transaction divided the overall time 0 to T into two parts: 0 to s and t to T. At each sub-interval we apply the same strategy we used in the first transaction to find the next most profitable options in each sub-interval with an additional requirement that we cannot buy the option that we already bought previously. We keep executing this strategy until we buy all the available options (with different strikes) which actually form a binomial tree of scenarios. We also follow the same strategy on each individual day.
We achieve our trading strategy by using recursive functions. And we find we can have an average daily return of 1000% if we know the future. The result is actually consistent with the data since we always have transactions which can produce return over 100%.
The following flow chart illustrates our strategy function in the code. Strategy () is a function that gives us the best buy and sell point within a certain period of time. We first calculated the best buy and sell point for the whole day that will give us the most return. Then, strategy() function calls itself twice in the function to further calculate the best buy and sell point from time 0 to time buy-1 and from time sell+1 to the end of the day. The trading strategy forms a binomial tree which is shown as follows.
Figure 1 Trading Strategy
4. Data & Results
1) A list of all available strikes for each day
Table 1 Available Strikes for Each Day
Available Strikes
12-Jun 13-Jun 14-Jun 15-Jun 16-Jun
470 470 470 475 470
475 475 475 480 475
485 480 480 485 480
490 485 485 490 490
495 490 490 495 495
500 495 495 500 500
505 500 500 505 505
510 505 505 510 510
515 510 510 515 515
520 515 515 520 520
525 520 520 525
525 525
2) A list of all available expirations for each day
We will only trade the nearest date of expiration on each of our trading days
Table 2 Available Expirations for Each Day
Date 12-Jun 13-Jun 14-Jun 15-Jun 16-Jun
Days to Maturity 5 4 3 2 1
Expiration Date 17-Jun 17-Jun 17-Jun 17-Jun 17-Jun
3) A list of all trades each day and profit from each trade
Table 3 All Trades Each Day and Profit from Each Trade
12-Jun 13-Jun
New Position Clear Position Profit New Position Clear Position Profit
9:42:49 9:53:28 36336.8 9:34:40 15:15:08 1116840
9:53:41 10:01:45 19195.6 15:15:27 15:15:49 33876.9
10:20:50 10:45:12 20189.4 15:17:32 15:18:56 41576.2
11:13:46 11:22:35 91375.3
11:43:16 14:59:18 459215
15:02:18 15:10:55 28543.5
14-Jun 15-Jun
New Position Clear Position Profit New Position Clear Position Profit
8:34:32 8:45:17 69591.2 8:39:39 13:04:45 33055100
8:52:25 8:53:38 5564.08 13:20:00 13:27:47 512843
8:56:15 8:57:52 237189 13:31:31 13:47:58 3005110
8:58:29 8:59:06 78438.4 13:49:45 13:50:01 11794300
9:03:11 10:24:52 559599 13:51:42 13:51:51 2770620
10:29:02 10:31:18 34182.9 14:01:36 14:34:24 33572200
10:31:33 11:58:49 2379760 14:39:36 14:56:31 5408340
12:10:06 13:50:48 10089400 14:59:24 15:12:29 1.61E+08
16-Jun
New Position Clear Position Profit
9:04:56 9:05:32 19468700
9:12:04 14:42:12 89273200
14:47:55 14:50:04 6.28E+08
4) Total Profit at the end of each day, Total Profit for the entire trading period
Figure 2 Percentage Profit for Each Day and Percentage Profit the Entire Trading Period
5) Percentage profit for each trade
Table 4 Percentage Profit for Each Trade
12-Jun 13-Jun
New Position Clear Position Percent New Position Clear Position Percent
9:42:49 9:53:28 36.33% 9:34:40 15:15:08 147.95%
9:53:41 10:01:45 14.08% 15:15:27 15:15:49 1.81%
10:20:50 10:45:12 12.98% 15:17:32 15:18:56 2.18%
11:13:46 11:22:35 52.00%
11:43:16 14:59:18 171.93%
15:02:18 15:10:55 3.93%
14-Jun 15-Jun
New Position Clear Position Percent New Position Clear Position Percent
8:34:32 8:45:17 3.57% 8:39:39 13:04:45 214.63%
8:52:25 8:53:38 0.28% 13:20:00 13:27:47 1.06%
8:56:15 8:57:52 11.73% 13:31:31 13:47:58 6.14%
8:58:29 8:59:06 3.47% 13:49:45 13:50:01 22.69%
9:03:11 10:24:52 23.94% 13:51:42 13:51:51 4.34%
10:29:02 10:31:18 1.18% 14:01:36 14:34:24 50.45%
10:31:33 11:58:49 81.17% 14:39:36 14:56:31 5.40%
12:10:06 13:50:48 189.95% 14:59:24 15:12:29 152.50%
16-Jun
New Position Clear Position Percent
9:04:56 9:05:32 7.31%
9:12:04 14:42:12 31.23%
14:47:55 14:50:04 167.34%
6) Profitability Analysis
In this project, we realized $1,002,800,000 payoff. During the first day, we earned 654,856 dollars; during the second day, we earned 1,192,300 dollars; during the third day, we earned 13,453,700 dollars; during the fourth day, we earned 251,023,000 dollars; and during the fifth day, we earned 736,548,000 dollars.
5. APPEN DIX1: Optionclass.H source code :
________________________________________________________________
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <ostream>
#include <istream>
#include <string>
#include <iomanip>
#include<boost/math/tools/roots.hpp>
#include<boost/math/special_functions/erf.hpp>
using namespace std;
using namespace boost::math;
using namespace boost::math::tools;
class Option
{
friend ostream & operator<<(ostream & out, Option option);
friend istream & operator>>(istream & in, Option & option);
public:
Option(string sym="asd", string d="1900-01-01", string tm="00:00:00",
string xD ="1900-01-01", int dif=0, double strk=0, string typ="CALL",
double trP = 0, int vol=0, double stckP=0., double intrst=0.0547)
{
symbol=sym;
date=d;
time=tm;
xdate=xD;
diff=dif;
strike=strk;
type=typ;
tradep=trP;
volume=vol;
stockp=stckP;
interest=intrst;
impliedvol=0.1;
delta=0.0;
gamma=0.0;
theta=0.0;
profit=0.0;
indicator=0;
imax=0;
maxrtn=0;
}
string getSymbol(){return symbol;}
string getDate() {return date;}
string getTime() {return time;}
string getXdate() {return xdate;}
int getDiff() {return diff;}
double getStrike() {return strike;}
string getType() {return type;}
double getTradep() {return tradep;}
int getVolume() {return volume;}
double getStockp() {return stockp;}
double getInterest() {return interest;}
double getVol(){return impliedvol;}
double getDelta(){return delta;}
double getGamma(){return gamma;}
double getTheta(){return theta;}
double getProfit(){return profit;}
void setVol(double imp){impliedvol=imp;}
void setDelta(double del){delta=del;}
void setGamma(double gam){gamma=gam;}
void setTheta(double the){theta=the;}
int imax;
double rtn;
double profit;
double maxrtn;
bool indicator;
private:
string symbol;
string date;
string time;
string xdate;
int diff;
double strike;
string type;
double tradep;
int volume;
double stockp;
double interest;
double impliedvol;
double delta;
double gamma;
double theta;
};
ostream & operator<<(ostream & out, Option opt)
{
out<<"Symbol :"<<opt.getSymbol()<<endl
<<"Date :"<<opt.getDate()<<endl
<<"Time :"<<opt.getTime()<<endl
<<"xDate :"<<opt.getXdate()<<endl
<<"Diff :"<<opt.getDiff()<<endl
<<"Strike :"<<opt.getStrike()<<endl
<<"Type :"<<opt.getType()<<endl
<<"TradeP :"<<opt.getTradep()<<endl
<<"Volume :"<<opt.getVolume()<<endl
<<"StockP :"<<opt.getStockp()<<endl
<<"Interst:"<<opt.getInterest()<<endl
<<"ImpliedVol:"<<opt.getVol()<<endl
<<"Delta:"<<opt.getDelta()<<endl
<<"Gamma:"<<opt.getGamma()<<endl
<<"Theta:"<<opt.getTheta()<<endl
<<"Profit:"<<opt.getProfit()<<endl
<<"Actual Return:"<<opt.rtn<<endl
<<"Sell Index:"<<opt.imax<<endl
<<"Payoff: "<<opt.profit<<endl;
return out;
};
istream & operator>>(istream & in, Option & opt)
{
in>>opt.symbol
>>opt.date
>>opt.time
>>opt.xdate
>>opt.diff
>>opt.strike
>>opt.type
>>opt.tradep
>>opt.volume
>>opt.stockp
>>opt.interest;
return in;
};
6. APPENDIX 2: Main Project Source Code:
______________________________________________________________
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <ostream>
#include <istream>
#include <string>
#include <iomanip>
#include <optionclass.h>
using namespace std;
//some universal virables
double gdiff, gstrike, gstockp, ginterest, gtradep, gimpliedVol;
double invest=100000;
vector <double> strike;
//functions statement: for calculating
double findVol();
double findDelta();
double findGamma();
double findTheta();
double blackscholes(int diff, double strike, double stockp, double interest,double impliedVol);
double f(double x);
bool tol(double low, double high);
//functions statement: for trading strategy
int findnext(int index,vector <Option> &data);
double findReturn(vector <Option> &data);
bool findMaxReturn(vector <Option> &data,int start, int end);
void strategy(vector <Option> &data,int m, int n);
void main()
{
//INPUTING DATA:
vector <Option> data1, data2, data3, data4, data5;
ifstream fin;
Option call;
fin.open("tradeCallBig.txt");
while(fin>>call)
{
if( call.getStockp()/call.getStrike()>=0.9 && call.getStockp()/call.getStrike()<=1.1 )//screen the data
{
if (call.getDate()=="1995-06-12"&&call.getDiff()==5) { //firt date and closest expiration
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data1.push_back(call);
}
else if (call.getDate()=="1995-06-13"&&call.getDiff()==4) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data2.push_back(call);
}
else if (call.getDate()=="1995-06-14"&&call.getDiff()==3) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data3.push_back(call);
}
else if (call.getDate()=="1995-06-15"&&call.getDiff()==2) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data4.push_back(call);
}
else if(call.getDate()=="1995-06-16"&&call.getDiff()==1) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data5.push_back(call);
}
}
}
fin.close();
//TRADING:
double data0_end_cash = 100000, data1_end_cash = 0, data2_end_cash = 0, data3_end_cash = 0, data4_end_cash = 0, data5_end_cash = 0;
//1st day
strike.clear();
strategy(data1,0,data1.size()-1);
data1_end_cash = findReturn(data1);
cout<<"Profit of 1995-06-12: "<< data1_end_cash - data0_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-12: "<< (data1_end_cash - data0_end_cash)/data0_end_cash * 100 <<"%" <<endl<<endl;
//2nd day
strike.clear();
strategy(data2,0,data2.size()-1);
data2_end_cash = findReturn(data2);
cout<<"Profit of 1995-06-13: "<< data2_end_cash - data1_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-13: "<< (data2_end_cash - data1_end_cash)/data1_end_cash * 100 <<"%" <<endl<<endl;
//3rd day
strike.clear();
strategy(data3,0,data3.size()-1);
data3_end_cash = findReturn(data3);
cout<<"Profit of 1995-06-14: "<< data3_end_cash - data2_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-14: "<< (data3_end_cash - data2_end_cash)/data2_end_cash * 100 <<"%" <<endl<<endl;
//4th day
strike.clear();
strategy(data4,0,data4.size()-1);
data4_end_cash = findReturn(data4);
cout<<"Profit of 1995-06-15: "<< data4_end_cash - data3_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-15: "<< (data4_end_cash - data3_end_cash)/data3_end_cash * 100 <<"%" <<endl<<endl;
//5th day
strike.clear();
strategy(data5,0,data5.size()-1);
data5_end_cash = findReturn(data5);
cout<<"Profit of 1995-06-16: "<< data5_end_cash - data4_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-16: "<< (data5_end_cash - data4_end_cash)/data4_end_cash * 100 <<"%" <<endl<<endl;
//total
cout<<"Total profit is: "<< data5_end_cash - data0_end_cash << endl;
cout<<"Total Percentage Profit: "<< (data5_end_cash - data0_end_cash)/data0_end_cash * 100 <<"%" <<endl<<endl;
//OUTPUT:
ofstream fout;
fout.open("output.txt");
fout.clear();
//Generating the list of our trades:
for(int j=0;j<data1.size();j++)
{
if(data1[j].indicator==1) {
fout<<data1[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data1[data1[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data2.size();j++)
{
if(data2[j].indicator==1) {
fout<<data2[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data2[data2[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data3.size();j++)
{
if(data3[j].indicator==1) {
fout<<data3[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data3[data3[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data4.size();j++)
{
if(data4[j].indicator==1) {
fout<<data4[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data4[data4[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data5.size();j++)
{
if(data5[j].indicator==1) {
fout<<data5[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data5[data5[j].imax] <<endl<<endl;
}
}
fout.close();
system("PAUSE");
}
//=====================================================================================//
// Trading Strategy Functions
//=====================================================================================//
bool findMaxReturn(vector <Option> &data, int start, int end)
//Look for the theoretical max return of current option.
//If find, return 1; otherwise, return 0.
{
double delC=0, delS=0, volume=0, tmpreturn=0, maxreturn=0;
int k=0;
for(int i=start; i<end; i++) {
data[i].imax = 0;
}
for(int i=start; i<end-1; i++)
{
tmpreturn=0;
maxreturn=0;
for(int j=i+1; j<end; j++)
{
if(data[i].getStrike()==data[j].getStrike())
{
k++;
delC = data[j].getTradep() - data[i].getTradep();
delS = ( data[i].getStockp() - data[j].getStockp() ) * data[i].getDelta();
tmpreturn = ( delC + delS ) / data[i].getTradep();
if( tmpreturn > maxreturn ) {
maxreturn = tmpreturn;
data[i].imax=j;
}
}
}
data[i].maxrtn = maxreturn;
}
return k;
}
int findnext(int index,vector <Option> &data)
//Check if there still exist option whose strke has not been processed.
//If find, return 1; otherwise, return 0
{
bool existstrike=0;
for(int j=0;j<strike.size();j++)
{
if( data[index].getStrike() == strike[j] )
existstrike = 1;
}
return existstrike;
}
void strategy(vector <Option> &data,int m, int n)
//Main trading strategy. Input buy index m and sell index n.
//Given interval (m,n), look for the subinterval recursely
{
int i,index,buy,sell;
double temp;
if(m<n)
{
if(findMaxReturn(data,m, n))
{
temp=0;index=0;
for(i=m;i<n;i++)
{
if( data[i].maxrtn>temp && findnext(i,data)==0 ) {
temp = data[i].maxrtn;
index = i;
}
}
if( index!=0 && data[index].imax!=0 ) {
buy=index;
sell=data[index].imax;
data[index].indicator=1;
strike.push_back( data[index].getStrike() );
strategy(data, m, buy-1);//recurse call
strategy(data, sell+1, n);//recurse call
}
}
}
}
double findReturn(vector <Option> &data)
//Compute the actual total cash after one day trading
{
double delC=0, delS=0, volume=0;
for(int i=0; i<data.size(); i++)
{
if(data[i].indicator){
delC = data[data[i].imax].getTradep() - data[i].getTradep();
delS = (data[i].getStockp() - data[data[i].imax].getStockp())*data[i].getDelta();
data[i].rtn = (delC+delS)/data[i].getTradep();
data[i].profit = (data[i].rtn+1)*invest;
invest=data[i].profit;
}
}
return invest;
}
//=====================================================================================//
/Parameters Calculation Functions
BLACK-SCHOLES MODEL
//=====================================================================================//
double blackscholes(int diff, double strike, double stockp, double interest,double impliedVol)
{
double d1,d2,N_d1,N_d2, T;
T=diff/365.0;
d1=(log(stockp/strike) + (interest+.5*impliedVol*impliedVol)*T)/(impliedVol*sqrt(T));
d2 = d1 - impliedVol * sqrt(T);
N_d1 = .5*(1 + erf(d1/sqrt(2.)));
N_d2 = .5*(1 + erf(d2/sqrt(2.)));
return stockp* N_d1 - strike * exp(-interest * T)* N_d2;
}
bool tol(double low, double high)
{
return fabs(high - low) < .00001;
}
double f(double x)
{
return (blackscholes(gdiff,gstrike,gstockp,ginterest,x) - gtradep);
}
double findVol()
{
std::pair<double, double> range;
range = bisect(f, -1.0, 1.1, tol);
gimpliedVol=0.5*range.first+0.5*range.second;
return gimpliedVol;
}
double findDelta()
{
double d1,N_d1,T;
T=gdiff/365.0;
d1=(log(gstockp/gstrike) + (ginterest+.5*gimpliedVol*gimpliedVol)*T)/(gimpliedVol*sqrt(T));
N_d1 = .5*(1 + erf(d1/sqrt(2.)));
return N_d1;
}
double findGamma()
{
double d1,gam,T;
T=gdiff/365.0;
d1=(log(gstockp/gstrike) + (ginterest+.5*gimpliedVol*gimpliedVol)*T)/(gimpliedVol*sqrt(T));
gam=1.0/sqrt(2.0*3.1415926)*exp(-d1*d1/2.0)/(gstockp*gimpliedVol*sqrt(T));
return gam;
}
double findTheta()
{
double d1,d2,n_d1,n_d2,T,the;
T=gdiff/365.0;
d1=(log(gstockp/gstrike) + (ginterest+.5*gimpliedVol*gimpliedVol)*T)/(gimpliedVol*sqrt(T));
d2=d1-gimpliedVol*sqrt(T);
n_d1=-gstockp*gimpliedVol/sqrt(2.0*3.1415926)*exp(-d1*d1/2.0)/(2*sqrt(T));
n_d2=ginterest*gstrike*exp(-ginterest*T)*0.5*(1 + erf(d2/sqrt(2.)));
the=n_d1-n_d2;
return the;
}
7. Reference
(1) Black-Schole Model, Black ,Scholes, Merton ,1970s
(2) Fundamentals of Futures and Options Markets: Global Edition 7/e, John C. Hull\
(3) Financial engineering , John,Marshall
程式設計期末報告
Department of Information Management
College of Management
National Taiwan University
Program Design
Final Report
选择权定价与交易策略
Option evaluation and trading strategy
Chris Zhichao Chi
國際企業系三年級T99704283
指導教授:洪瑞文 博士
Advisor: Hong, Ph.D.
中華民國100年6月
June, 2011
目 錄
中文摘要: 2
Abstract: 2
1. Introduction 2
2. Assumptions 3
3. Trading strategy 3
4. Data & Results 4
1) A list of all available strikes for each day 4
2) A list of all available expirations for each day 5
3) A list of all trades each day and profit from each trade 5
4) Total Profit at the end of each day, Total Profit for the entire trading period 6
5) Percentage profit for each trade 6
6) Profitability Analysis 7
5. APPEN DIX1: Optionclass.H source code : 7
6. APPENDIX 2: Main Project Source Code: 11
7. Reference 21
中文摘要:
本篇报告主要研究如何通过C++的语言来进行选择权的定价,并且在一定的假设条件下,通过程式交易计算选择权交易的最优策略。
关键词:选择权 C++程式 定价 交易 最优 策略
Abstract:
in this report, we try to evaluate the option price using the Black-Scholes Option Pricing Model ,and discuss the optimal trading strategy under some given assumptions.
Key words: option C++language pricing trading optimal strategy
1. Introduction
In this project, we try to write the Black-Scholes Model function and use it in the option price evaluation and trading strategy. We use a crowd of specific option trading data to serve the materials, and create an “optionclass. H” profile to handle all the material data and prepare to be used by the main project. We discuss our optimal trading strategy in the main project, which achieve under some given conditions.
2. Assumptions
We can only trade one type of option one time in the day.
We only buy options (short index) to get the maximum return since selling option requires buying index, which is too costly.
We can keep buying options as long as we have available funds.
We cannot invest the money we get from shorting the index.
We only hold one type of option at a time. This is a natural result of our previous assumption in addition to our trading strategy ensuring that the option we pick (we invest all our money in it) is the most profitable one.
3. Trading strategy
Firstly, we assume we buy the option at time t and we calculate the return for each available selling point (transactions with the same strike) after t. Secondly we compare the return of those selling points and pick the maximum payoff as the maximal return for the option. Thirdly, we buy the option with the highest return and proceed to find the next most profitable options.
Suppose we buy the optimal option at s and sell it at t, according to our assumptions, we only hold that option during time s and t. Then our first transaction divided the overall time 0 to T into two parts: 0 to s and t to T. At each sub-interval we apply the same strategy we used in the first transaction to find the next most profitable options in each sub-interval with an additional requirement that we cannot buy the option that we already bought previously. We keep executing this strategy until we buy all the available options (with different strikes) which actually form a binomial tree of scenarios. We also follow the same strategy on each individual day.
We achieve our trading strategy by using recursive functions. And we find we can have an average daily return of 1000% if we know the future. The result is actually consistent with the data since we always have transactions which can produce return over 100%.
The following flow chart illustrates our strategy function in the code. Strategy () is a function that gives us the best buy and sell point within a certain period of time. We first calculated the best buy and sell point for the whole day that will give us the most return. Then, strategy() function calls itself twice in the function to further calculate the best buy and sell point from time 0 to time buy-1 and from time sell+1 to the end of the day. The trading strategy forms a binomial tree which is shown as follows.
Figure 1 Trading Strategy
4. Data & Results
1) A list of all available strikes for each day
Table 1 Available Strikes for Each Day
Available Strikes
12-Jun 13-Jun 14-Jun 15-Jun 16-Jun
470 470 470 475 470
475 475 475 480 475
485 480 480 485 480
490 485 485 490 490
495 490 490 495 495
500 495 495 500 500
505 500 500 505 505
510 505 505 510 510
515 510 510 515 515
520 515 515 520 520
525 520 520 525
525 525
2) A list of all available expirations for each day
We will only trade the nearest date of expiration on each of our trading days
Table 2 Available Expirations for Each Day
Date 12-Jun 13-Jun 14-Jun 15-Jun 16-Jun
Days to Maturity 5 4 3 2 1
Expiration Date 17-Jun 17-Jun 17-Jun 17-Jun 17-Jun
3) A list of all trades each day and profit from each trade
Table 3 All Trades Each Day and Profit from Each Trade
12-Jun 13-Jun
New Position Clear Position Profit New Position Clear Position Profit
9:42:49 9:53:28 36336.8 9:34:40 15:15:08 1116840
9:53:41 10:01:45 19195.6 15:15:27 15:15:49 33876.9
10:20:50 10:45:12 20189.4 15:17:32 15:18:56 41576.2
11:13:46 11:22:35 91375.3
11:43:16 14:59:18 459215
15:02:18 15:10:55 28543.5
14-Jun 15-Jun
New Position Clear Position Profit New Position Clear Position Profit
8:34:32 8:45:17 69591.2 8:39:39 13:04:45 33055100
8:52:25 8:53:38 5564.08 13:20:00 13:27:47 512843
8:56:15 8:57:52 237189 13:31:31 13:47:58 3005110
8:58:29 8:59:06 78438.4 13:49:45 13:50:01 11794300
9:03:11 10:24:52 559599 13:51:42 13:51:51 2770620
10:29:02 10:31:18 34182.9 14:01:36 14:34:24 33572200
10:31:33 11:58:49 2379760 14:39:36 14:56:31 5408340
12:10:06 13:50:48 10089400 14:59:24 15:12:29 1.61E+08
16-Jun
New Position Clear Position Profit
9:04:56 9:05:32 19468700
9:12:04 14:42:12 89273200
14:47:55 14:50:04 6.28E+08
4) Total Profit at the end of each day, Total Profit for the entire trading period
Figure 2 Percentage Profit for Each Day and Percentage Profit the Entire Trading Period
5) Percentage profit for each trade
Table 4 Percentage Profit for Each Trade
12-Jun 13-Jun
New Position Clear Position Percent New Position Clear Position Percent
9:42:49 9:53:28 36.33% 9:34:40 15:15:08 147.95%
9:53:41 10:01:45 14.08% 15:15:27 15:15:49 1.81%
10:20:50 10:45:12 12.98% 15:17:32 15:18:56 2.18%
11:13:46 11:22:35 52.00%
11:43:16 14:59:18 171.93%
15:02:18 15:10:55 3.93%
14-Jun 15-Jun
New Position Clear Position Percent New Position Clear Position Percent
8:34:32 8:45:17 3.57% 8:39:39 13:04:45 214.63%
8:52:25 8:53:38 0.28% 13:20:00 13:27:47 1.06%
8:56:15 8:57:52 11.73% 13:31:31 13:47:58 6.14%
8:58:29 8:59:06 3.47% 13:49:45 13:50:01 22.69%
9:03:11 10:24:52 23.94% 13:51:42 13:51:51 4.34%
10:29:02 10:31:18 1.18% 14:01:36 14:34:24 50.45%
10:31:33 11:58:49 81.17% 14:39:36 14:56:31 5.40%
12:10:06 13:50:48 189.95% 14:59:24 15:12:29 152.50%
16-Jun
New Position Clear Position Percent
9:04:56 9:05:32 7.31%
9:12:04 14:42:12 31.23%
14:47:55 14:50:04 167.34%
6) Profitability Analysis
In this project, we realized $1,002,800,000 payoff. During the first day, we earned 654,856 dollars; during the second day, we earned 1,192,300 dollars; during the third day, we earned 13,453,700 dollars; during the fourth day, we earned 251,023,000 dollars; and during the fifth day, we earned 736,548,000 dollars.
5. APPEN DIX1: Optionclass.H source code :
________________________________________________________________
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <ostream>
#include <istream>
#include <string>
#include <iomanip>
#include<boost/math/tools/roots.hpp>
#include<boost/math/special_functions/erf.hpp>
using namespace std;
using namespace boost::math;
using namespace boost::math::tools;
class Option
{
friend ostream & operator<<(ostream & out, Option option);
friend istream & operator>>(istream & in, Option & option);
public:
Option(string sym="asd", string d="1900-01-01", string tm="00:00:00",
string xD ="1900-01-01", int dif=0, double strk=0, string typ="CALL",
double trP = 0, int vol=0, double stckP=0., double intrst=0.0547)
{
symbol=sym;
date=d;
time=tm;
xdate=xD;
diff=dif;
strike=strk;
type=typ;
tradep=trP;
volume=vol;
stockp=stckP;
interest=intrst;
impliedvol=0.1;
delta=0.0;
gamma=0.0;
theta=0.0;
profit=0.0;
indicator=0;
imax=0;
maxrtn=0;
}
string getSymbol(){return symbol;}
string getDate() {return date;}
string getTime() {return time;}
string getXdate() {return xdate;}
int getDiff() {return diff;}
double getStrike() {return strike;}
string getType() {return type;}
double getTradep() {return tradep;}
int getVolume() {return volume;}
double getStockp() {return stockp;}
double getInterest() {return interest;}
double getVol(){return impliedvol;}
double getDelta(){return delta;}
double getGamma(){return gamma;}
double getTheta(){return theta;}
double getProfit(){return profit;}
void setVol(double imp){impliedvol=imp;}
void setDelta(double del){delta=del;}
void setGamma(double gam){gamma=gam;}
void setTheta(double the){theta=the;}
int imax;
double rtn;
double profit;
double maxrtn;
bool indicator;
private:
string symbol;
string date;
string time;
string xdate;
int diff;
double strike;
string type;
double tradep;
int volume;
double stockp;
double interest;
double impliedvol;
double delta;
double gamma;
double theta;
};
ostream & operator<<(ostream & out, Option opt)
{
out<<"Symbol :"<<opt.getSymbol()<<endl
<<"Date :"<<opt.getDate()<<endl
<<"Time :"<<opt.getTime()<<endl
<<"xDate :"<<opt.getXdate()<<endl
<<"Diff :"<<opt.getDiff()<<endl
<<"Strike :"<<opt.getStrike()<<endl
<<"Type :"<<opt.getType()<<endl
<<"TradeP :"<<opt.getTradep()<<endl
<<"Volume :"<<opt.getVolume()<<endl
<<"StockP :"<<opt.getStockp()<<endl
<<"Interst:"<<opt.getInterest()<<endl
<<"ImpliedVol:"<<opt.getVol()<<endl
<<"Delta:"<<opt.getDelta()<<endl
<<"Gamma:"<<opt.getGamma()<<endl
<<"Theta:"<<opt.getTheta()<<endl
<<"Profit:"<<opt.getProfit()<<endl
<<"Actual Return:"<<opt.rtn<<endl
<<"Sell Index:"<<opt.imax<<endl
<<"Payoff: "<<opt.profit<<endl;
return out;
};
istream & operator>>(istream & in, Option & opt)
{
in>>opt.symbol
>>opt.date
>>opt.time
>>opt.xdate
>>opt.diff
>>opt.strike
>>opt.type
>>opt.tradep
>>opt.volume
>>opt.stockp
>>opt.interest;
return in;
};
6. APPENDIX 2: Main Project Source Code:
______________________________________________________________
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <ostream>
#include <istream>
#include <string>
#include <iomanip>
#include <optionclass.h>
using namespace std;
//some universal virables
double gdiff, gstrike, gstockp, ginterest, gtradep, gimpliedVol;
double invest=100000;
vector <double> strike;
//functions statement: for calculating
double findVol();
double findDelta();
double findGamma();
double findTheta();
double blackscholes(int diff, double strike, double stockp, double interest,double impliedVol);
double f(double x);
bool tol(double low, double high);
//functions statement: for trading strategy
int findnext(int index,vector <Option> &data);
double findReturn(vector <Option> &data);
bool findMaxReturn(vector <Option> &data,int start, int end);
void strategy(vector <Option> &data,int m, int n);
void main()
{
//INPUTING DATA:
vector <Option> data1, data2, data3, data4, data5;
ifstream fin;
Option call;
fin.open("tradeCallBig.txt");
while(fin>>call)
{
if( call.getStockp()/call.getStrike()>=0.9 && call.getStockp()/call.getStrike()<=1.1 )//screen the data
{
if (call.getDate()=="1995-06-12"&&call.getDiff()==5) { //firt date and closest expiration
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data1.push_back(call);
}
else if (call.getDate()=="1995-06-13"&&call.getDiff()==4) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data2.push_back(call);
}
else if (call.getDate()=="1995-06-14"&&call.getDiff()==3) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data3.push_back(call);
}
else if (call.getDate()=="1995-06-15"&&call.getDiff()==2) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data4.push_back(call);
}
else if(call.getDate()=="1995-06-16"&&call.getDiff()==1) {
gdiff=call.getDiff();gstrike=call.getStrike();gstockp=call.getStockp();ginterest=call.getInterest();gtradep=call.getTradep();
call.setVol(findVol());call.setDelta(findDelta());call.setGamma(findGamma());call.setTheta(findTheta());data5.push_back(call);
}
}
}
fin.close();
//TRADING:
double data0_end_cash = 100000, data1_end_cash = 0, data2_end_cash = 0, data3_end_cash = 0, data4_end_cash = 0, data5_end_cash = 0;
//1st day
strike.clear();
strategy(data1,0,data1.size()-1);
data1_end_cash = findReturn(data1);
cout<<"Profit of 1995-06-12: "<< data1_end_cash - data0_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-12: "<< (data1_end_cash - data0_end_cash)/data0_end_cash * 100 <<"%" <<endl<<endl;
//2nd day
strike.clear();
strategy(data2,0,data2.size()-1);
data2_end_cash = findReturn(data2);
cout<<"Profit of 1995-06-13: "<< data2_end_cash - data1_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-13: "<< (data2_end_cash - data1_end_cash)/data1_end_cash * 100 <<"%" <<endl<<endl;
//3rd day
strike.clear();
strategy(data3,0,data3.size()-1);
data3_end_cash = findReturn(data3);
cout<<"Profit of 1995-06-14: "<< data3_end_cash - data2_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-14: "<< (data3_end_cash - data2_end_cash)/data2_end_cash * 100 <<"%" <<endl<<endl;
//4th day
strike.clear();
strategy(data4,0,data4.size()-1);
data4_end_cash = findReturn(data4);
cout<<"Profit of 1995-06-15: "<< data4_end_cash - data3_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-15: "<< (data4_end_cash - data3_end_cash)/data3_end_cash * 100 <<"%" <<endl<<endl;
//5th day
strike.clear();
strategy(data5,0,data5.size()-1);
data5_end_cash = findReturn(data5);
cout<<"Profit of 1995-06-16: "<< data5_end_cash - data4_end_cash <<endl;
cout<<"Percentage Profit of 1995-06-16: "<< (data5_end_cash - data4_end_cash)/data4_end_cash * 100 <<"%" <<endl<<endl;
//total
cout<<"Total profit is: "<< data5_end_cash - data0_end_cash << endl;
cout<<"Total Percentage Profit: "<< (data5_end_cash - data0_end_cash)/data0_end_cash * 100 <<"%" <<endl<<endl;
//OUTPUT:
ofstream fout;
fout.open("output.txt");
fout.clear();
//Generating the list of our trades:
for(int j=0;j<data1.size();j++)
{
if(data1[j].indicator==1) {
fout<<data1[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data1[data1[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data2.size();j++)
{
if(data2[j].indicator==1) {
fout<<data2[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data2[data2[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data3.size();j++)
{
if(data3[j].indicator==1) {
fout<<data3[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data3[data3[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data4.size();j++)
{
if(data4[j].indicator==1) {
fout<<data4[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data4[data4[j].imax] <<endl<<endl;
}
}
for(int j=0;j<data5.size();j++)
{
if(data5[j].indicator==1) {
fout<<data5[j]<<endl;
fout<<"The corresponding selling option is: " << endl << data5[data5[j].imax] <<endl<<endl;
}
}
fout.close();
system("PAUSE");
}
//=====================================================================================//
// Trading Strategy Functions
//=====================================================================================//
bool findMaxReturn(vector <Option> &data, int start, int end)
//Look for the theoretical max return of current option.
//If find, return 1; otherwise, return 0.
{
double delC=0, delS=0, volume=0, tmpreturn=0, maxreturn=0;
int k=0;
for(int i=start; i<end; i++) {
data[i].imax = 0;
}
for(int i=start; i<end-1; i++)
{
tmpreturn=0;
maxreturn=0;
for(int j=i+1; j<end; j++)
{
if(data[i].getStrike()==data[j].getStrike())
{
k++;
delC = data[j].getTradep() - data[i].getTradep();
delS = ( data[i].getStockp() - data[j].getStockp() ) * data[i].getDelta();
tmpreturn = ( delC + delS ) / data[i].getTradep();
if( tmpreturn > maxreturn ) {
maxreturn = tmpreturn;
data[i].imax=j;
}
}
}
data[i].maxrtn = maxreturn;
}
return k;
}
int findnext(int index,vector <Option> &data)
//Check if there still exist option whose strke has not been processed.
//If find, return 1; otherwise, return 0
{
bool existstrike=0;
for(int j=0;j<strike.size();j++)
{
if( data[index].getStrike() == strike[j] )
existstrike = 1;
}
return existstrike;
}
void strategy(vector <Option> &data,int m, int n)
//Main trading strategy. Input buy index m and sell index n.
//Given interval (m,n), look for the subinterval recursely
{
int i,index,buy,sell;
double temp;
if(m<n)
{
if(findMaxReturn(data,m, n))
{
temp=0;index=0;
for(i=m;i<n;i++)
{
if( data[i].maxrtn>temp && findnext(i,data)==0 ) {
temp = data[i].maxrtn;
index = i;
}
}
if( index!=0 && data[index].imax!=0 ) {
buy=index;
sell=data[index].imax;
data[index].indicator=1;
strike.push_back( data[index].getStrike() );
strategy(data, m, buy-1);//recurse call
strategy(data, sell+1, n);//recurse call
}
}
}
}
double findReturn(vector <Option> &data)
//Compute the actual total cash after one day trading
{
double delC=0, delS=0, volume=0;
for(int i=0; i<data.size(); i++)
{
if(data[i].indicator){
delC = data[data[i].imax].getTradep() - data[i].getTradep();
delS = (data[i].getStockp() - data[data[i].imax].getStockp())*data[i].getDelta();
data[i].rtn = (delC+delS)/data[i].getTradep();
data[i].profit = (data[i].rtn+1)*invest;
invest=data[i].profit;
}
}
return invest;
}
//=====================================================================================//
/Parameters Calculation Functions
BLACK-SCHOLES MODEL
//=====================================================================================//
double blackscholes(int diff, double strike, double stockp, double interest,double impliedVol)
{
double d1,d2,N_d1,N_d2, T;
T=diff/365.0;
d1=(log(stockp/strike) + (interest+.5*impliedVol*impliedVol)*T)/(impliedVol*sqrt(T));
d2 = d1 - impliedVol * sqrt(T);
N_d1 = .5*(1 + erf(d1/sqrt(2.)));
N_d2 = .5*(1 + erf(d2/sqrt(2.)));
return stockp* N_d1 - strike * exp(-interest * T)* N_d2;
}
bool tol(double low, double high)
{
return fabs(high - low) < .00001;
}
double f(double x)
{
return (blackscholes(gdiff,gstrike,gstockp,ginterest,x) - gtradep);
}
double findVol()
{
std::pair<double, double> range;
range = bisect(f, -1.0, 1.1, tol);
gimpliedVol=0.5*range.first+0.5*range.second;
return gimpliedVol;
}
double findDelta()
{
double d1,N_d1,T;
T=gdiff/365.0;
d1=(log(gstockp/gstrike) + (ginterest+.5*gimpliedVol*gimpliedVol)*T)/(gimpliedVol*sqrt(T));
N_d1 = .5*(1 + erf(d1/sqrt(2.)));
return N_d1;
}
double findGamma()
{
double d1,gam,T;
T=gdiff/365.0;
d1=(log(gstockp/gstrike) + (ginterest+.5*gimpliedVol*gimpliedVol)*T)/(gimpliedVol*sqrt(T));
gam=1.0/sqrt(2.0*3.1415926)*exp(-d1*d1/2.0)/(gstockp*gimpliedVol*sqrt(T));
return gam;
}
double findTheta()
{
double d1,d2,n_d1,n_d2,T,the;
T=gdiff/365.0;
d1=(log(gstockp/gstrike) + (ginterest+.5*gimpliedVol*gimpliedVol)*T)/(gimpliedVol*sqrt(T));
d2=d1-gimpliedVol*sqrt(T);
n_d1=-gstockp*gimpliedVol/sqrt(2.0*3.1415926)*exp(-d1*d1/2.0)/(2*sqrt(T));
n_d2=ginterest*gstrike*exp(-ginterest*T)*0.5*(1 + erf(d2/sqrt(2.)));
the=n_d1-n_d2;
return the;
}
7. Reference
(1) Black-Schole Model, Black ,Scholes, Merton ,1970s
(2) Fundamentals of Futures and Options Markets: Global Edition 7/e, John C. Hull\
(3) Financial engineering , John,Marshall
还没人转发这篇日记