clear all;
clc;
prompt_name = 'input code if you would like to search by the code \n or the name of the stock of interest: ';
name = input(prompt_name,'s');
code = name;
if strcmp(name,'code')==1
prompt_code = 'the code of the stock of interest: ';
code = input(prompt_code,'s');
end
filename = strcat('sh',code,'_D_ExDiv.mat');
foldername = 'D:\test\DataBase_\Stock\Day_ExDividend_mat';
file = fullfile(foldername, filename);
load(file);
tic
%fee=1.5/10000;%手续费
fee=0;%手续费,实际要用1.5/10000!!
Open=StockData(:,2);%开盘价
High=StockData(:,3);%最高价
Low=StockData(:,4);%最低价
Close=StockData(:,5);%收盘价
Vol=StockData(:,6);%成交量
% Openint=data(:,6);%持仓量
hhvc=hhigh(High,5); %近一周最低值
llvc=llow(Low,5); %近一周最高值
[lth,wth]=size(StockData);
% 计算MACD
%定义计算长度
shortPeriod=12;%定义收盘价短期(快速)平滑移动平均计算长度
longPeriod=26;%定义收盘价长期(慢速)平滑移动平均计算长度
DEAPeriod=9;%定义diff线平滑移动平均计算长度
%建立占位矩阵,提高程序运行效率
EMAshort=zeros(lth,1);
EMAlong=zeros(lth,1);
DIFF=zeros(lth,1);
DEA=zeros(lth,1);
MACD=zeros(lth,1);
%用循环语句计算各个指标
EMAshort(1)=Close(1);%初始化EMAshort第一值
EMAlong(1)=Close(1);%初始化EMAlong第一个值
DEA(1)=0;%初始化第一值
DIFF(1)=0;
MACD(1)=0;
for i=2:lth
%计算短期和长期EMA
EMAshort(i)=Close(i)*(2/(shortPeriod+1))+EMAshort(i-1)*((shortPeriod-1)/(shortPeriod+1));
EMAlong(i)=Close(i)*(2/(longPeriod+1))+EMAlong(i-1)*((longPeriod-1)/(longPeriod+1));
%计算DIFF
DIFF(i)=EMAshort(i)-EMAlong(i);
%计算DEA
DEA(i)=DIFF(i)*(2/(DEAPeriod+1))+DEA(i-1)*((DEAPeriod-1)/(DEAPeriod+1));
%计算MACD
MACD(i)=(DIFF(i)-DEA(i));
end
figure(1)
plot(Close);
hold on;
plot(EMAshort);
hold on;
plot(EMAlong);
hold on;
plot(DIFF);
hold on;
plot(DEA);
hold on;
plot(MACD)
hold off;
legend('show');
% 计算boll
boll_matrix = zeros(lth,3);
boll_time = 5;
for i=1:lth
if (boll_time>=i) %前面几个数据没有均线数据,用实际数据替代
boll_matrix(i,1)=sum(Close(1:i))/i; %头几天平均
boll_matrix(i,2)=boll_matrix(i,1)+1.5*std(Close(1:i)); %头几天boll上轨
boll_matrix(i,3)=boll_matrix(i,1)-1.5*std(Close(1:i)); %头几天boll下轨
else
boll_matrix(i,1)=sum(Close(i-boll_time+1:i))/boll_time; %第一天的平均
boll_matrix(i,2)=boll_matrix(i,1)+1.5*std(Close(i-boll_time:i)); %boll上轨
boll_matrix(i,3)=boll_matrix(i,1)-1.5*std(Close(i-boll_time:i)); %boll下轨
end
end
figure(2)
plot(Close);
hold on;
plot(boll_matrix(:,1));
hold on;
plot(boll_matrix(:,2));
hold on;
plot(boll_matrix(:,3));
hold off;
legend('show');
KDJ_Matrix = zeros(lth,4);
% 计算KDJ
Ma_Min=5;%参数1,Ma_Min表示测试用的Ma的最小值
Ma=9; %参数1,Ma表示均线的天数,初始值为Ma_Min
Ma_Max=60;%参数1,Ma_Max表示测试用的Ma的最大值
for i=2:lth
if (Ma>i) %前面几个数据没有均线数据,用实际数据替代
KDJ_Matrix(i,1)=0; %每天的RSV参数,等于0
KDJ_Matrix(i,2)=50; %每天的K值,因为前一天无K值,所以赋初值50
KDJ_Matrix(i,3)=50; %每天的D值,因为前一天无D值,所以赋初值50
KDJ_Matrix(i,4)=0; %每天的J值,因为当天无K值和J值,所以赋初值0
else
KDJ_Matrix(i,1)=(Close(i)-min((Low(i-Ma+1:i))))/(max((High(i-Ma+1:i)))-min((Low(i-Ma+1:i))))*100;%每日rsv
KDJ_Matrix(i,2)=2/3*KDJ_Matrix(i-1,2)+1/3* KDJ_Matrix(i,1); %每日K值,K值=2/3×前一日K值+1/3×当日RSV
KDJ_Matrix(i,3)=2/3* KDJ_Matrix(i-1,3)+1/3*KDJ_Matrix(i,2); %每日D值,D值=2/3×前一日D值+1/3×当日的K植
KDJ_Matrix(i,4)=3* KDJ_Matrix(i,2)-2*KDJ_Matrix(i,3); %每日J值,J值=3*当日K值-2*当日D值
end
end
minMACD = zeros(lth,1);
minMACD(1) = MACD(1);
%计算到i时刻MACD的最小值
for i=2:lth
if MACD(i)>MACD(i-1)||MACD(i)==MACD(i-1);
minMACD(i)=MACD(i-1);
elseif MACD(i)<MACD(i-1)
minMACD(i)=MACD(i);
end
end
maxMACD = zeros(lth,1);
maxMACD(1) = MACD(1);
%计算到i时刻MACD的最大值
for i=2:lth
if MACD(i)>MACD(i-1)||MACD(i)==MACD(i-1)
maxMACD(i)=MACD(i);
elseif MACD(i)<MACD(i-1)
maxMACD(i)=MACD(i-1);
end
end
cmi = zeros(lth,1);
%cmi指标
for i=2:lth
cmi(i)=(abs(Close(i)-Open(i)))*100/(hhvc(i)-llvc(i));
end
figure(3)
plot(cmi);
%%交易思想
% MACD负转正,买,MACD正转负,卖
% 当cmi大于或等于53时
% 开多:MACD底背离;
% 平多:MACD顶背离;
% 开空:当天MACD小于前一天MACD、收盘价碰到BOLL的上轨、当期J值小于前一期的J值,三个条件中满足2个或2个以上;
% 平空:当天MACD大于前一天MACD、收盘价碰到BOLL的下轨、当期J值大于前一期的J值,三个条件中满足2个或2个以上;
% 当cmi小于53时
% 开多:收盘价碰到BOLL的下轨;
% 平多:收盘价碰到BOLL的上轨;
% 开空:当天MACD小于前一天MACD、收盘价碰到BOLL的上轨、当期J值小于前一期的J值,三个条件中满足2个或2个以上;
% 平空:当天MACD大于前一天MACD、收盘价碰到BOLL的下轨、当期J值大于前一期的J值,三个条件中满足2个或2个以上;
account_balance = zeros(lth,1);
holding = zeros(lth,1);
value = zeros(lth,1);
entryprice = zeros(lth,1);
tradetimes=0;
cmi=zeros(lth,1);
time = [1:lth];
% 初始化账户参数
account_balance(1) = 10000;
holding(1) = 0;
entryprice(1) = 0;
investment = 1000;
for i=2:lth
if cmi(i)>= 53
buy=(llvc(i)<llvc(i-1))&&(minMACD(i)==minMACD(i-1)); %开多
sellshort=((MACD(i)<MACD(i-1))&&(Close(i)>boll_matrix(i,2)))||((MACD(i)<MACD(i-1))&&(KDJ_Matrix(i,4)<KDJ_Matrix(i-1,4)))||((Close(i)>boll_matrix(i,2))&&(KDJ_Matrix(i,4)<KDJ_Matrix(i-1,4)));%开空
sell=(hhvc(i)>hhvc(i-1))&&(maxMACD(i)==maxMACD(i-1));%平多
buytocover=((MACD(i)>MACD(i-1))&&(Close(i)<boll_matrix(i,3)))||((MACD(i)>MACD(i-1))&&(KDJ_Matrix(i,4)>KDJ_Matrix(i-1,4)))||((Close(i)<boll_matrix(i,3))&&(KDJ_Matrix(i,4)>KDJ_Matrix(i-1,4)));%平空
end
if cmi(i)<53
buy =Close(i)<boll_matrix(i,3);%开多
sellshort=((MACD(i)<MACD(i-1))&&(Close(i)>boll_matrix(i,2)))||((MACD(i)<MACD(i-1))&&(KDJ_Matrix(i,4)<KDJ_Matrix(i-1,4)))||((Close(i)>boll_matrix(i,2))&&(KDJ_Matrix(i,4)<KDJ_Matrix(i-1,4)));%开空
sell=Close(i)>boll_matrix(i,2);%平多
buytocover=((MACD(i)>MACD(i-1))&&(Close(i)<boll_matrix(i,3)))||((MACD(i)>MACD(i-1))&&(KDJ_Matrix(i,4)>KDJ_Matrix(i-1,4)))||((Close(i)<boll_matrix(i,3))&&(KDJ_Matrix(i,4)>KDJ_Matrix(i-1,4)));%平空
end
if sell == 1
account_balance(i+1) = account_balance(i+1)-investment;
holding(i+1) = holding(i)+investment/Open(i+1);
tradetimes = tradetimes +1;
end
if buy == 1
account_balance(i+1) = account_balance(i+1)+investment;
holding(i+1) = holding(i)-investment/Open(i+1);
tradetimes = tradetimes +1;
end
if buy ~=1 && sell ~=1
account_balance(i+1) = account_balance(i);
holding(i+1) = holding(i);
end
value(i) = account_balance(i)+holding(i)* Close(i);
end
figure(4)
plot(value);
hold on;
plot(holding);
hold off
toc;
% %%利润自动计算
% if(buytocover == 1 && holding(i)<-0.5) || (sell==1 && holding(i)>0.5 )
% profit(i)=profit(i)-Close(i)*fee;
% holding(i)=0;
% tradetimes=tradetimes+1;
% end
% if sellshort==1 && holding(i)>-0.5
% if holding(i)>0.5
% profit(i)=profit(i)-Close(i)*fee;
% tradetimes=tradetimes+1;
% end
% entryprice(i)=Close(i);
% profit(i)=profit(i)-Close(i)*fee;
% holding(i)=-1;
% end
%
% if buy == 1 && holding(i)<0.5
% if holding(i)<-0.5
% profit(i)=profit(i)-Close(i)*fee;
% tradetimes=tradetimes+1;
% end
% entryprice(i)=Close(i);
% profit(i)=profit(i)-Close(i)*fee;
% holding(i)=1;
% end
% if holding(i-1)>0.5
% profit(i)=profit(i)+Close(i)-Close(i-1);
% p(i)=pro