改编自http://www.matlabsky.com/thread-38451-1-3.html
非常感谢blake_libo和faruto的源码,在他们的基础上启发改编完成
源码或者Wind的复权算法如有错误请提醒我
还有,这个例子显示除权的信息感觉有很大的缺失。
量化板块支持分享重要代码、书籍资料(最好介绍详细) 、量化报告(最好介绍详细)、量化思想分享及提问(与量化或者编程软件、数理统计相关)、如果介绍详细或者有原创代码分享,有重大奖励!绝不手软!另外,发帖分享idea或者资料、转载代码,一般都会有奖励!但是不支持与量化无关的灌水帖!
源代码文件如下:
[hide][/hide]
[hide]
- %%一个基于股价复盘价的改编
- %%直接提取了blake_libo函数
- %%数据和读取数据来自blake_libo的方法
- %%Modified by fantuanxiaot
- clc
- clear all
- close all
- format compact
- %%byfantuanxiaot
- %只读形式进行打开(read)
- %这应该是通达信特有的数据处理格式
- file_fid=fopen('FT_SZ300100.day','r');
- %指向开头
- frewind(file_fid)
- %文件的属性
- dir_nature=dir('FT_SZ300100.day');
- %读取8行751列的数据进去
- %时间从20100806到20130923
- %dir_nature.bytes/32=751
- %数据总共有8*751个
- data=fread(file_fid,[8 dir_nature.bytes/32],'uint32');
- frewind(file_fid)
- %将文件的指针指向第20个字节
- fseek(file_fid,20,'bof');
- %成交量是float型数据,每隔28个数读取4个数
- data(6,:)=fread(file_fid,dir_nature.bytes/32,'float=>long',28);
- %开盘价,最高价,最低价,收盘价
- %成交额
- data(2:5,:)=data(2:5,:)/100;
- data(6,:)=round(data(6,:)/10);
- %这里做了变动,结果一样
- %对日期进行转换
- %data(1,:)=datenum(fix(data(1,:)/10000),fix(mod(data(1,:)/100,100)),mod(data(1,:),100));
- data(1,:)=datenum(num2str(data(1,:)'),'yyyymmdd')';
- fclose(file_fid);
- stockdata=fints(data(1,:)',data([2:7],:)',{'OPEN','HIGH','LOW','CLOSE',...
- 'AMOUNT','VOLUME'},'D','SZ300100');
- %%以上将数据进行了处理
- %提取一段时间的数据就像这样fetch(myFts,'01-Jan-2001',[],'03-Jan-2001',[],1,'d')
- %fetch(myFts,'01-Jan-2001','11:00','03-Jan-2001','12:00',1,'d')
- FromDate = '04-Jan-2011';
- ToDate = '20-Feb-2012';
- stock=fetch(stockdata,FromDate,[],ToDate,[],1,'d');
- %载入除权数据
- load('FT_Dividend_Data.mat')
- %一些数据处理
- txtRightout(2:end,3:8)=num2cell(numRightout);
- %寻找除权的股价时间
- index=strcmp('300100',txtRightout(:,2));
- %得到了除权的信息dividend_information
- dividend_information=txtRightout(index,:);
- dividend_information=[txtRightout(1,:);dividend_information];
- %%下面进行向前的复权处理
- %%方法是基于wind的涨跌幅法则
- Date=stockdata.dates;
- stock=fts2mat(stockdata);
- OPEN=stock(:,1);
- HIGH=stock(:,2);
- LOW=stock(:,3);
- CLOSE=stock(:,4);
- Date=datestr(Date,'yyyymmdd');
- %数据的处理方法来自blake_libo的贡献
- %再转化为数字
- Date=str2num(Date);
- %除权日期
- chuquanriqi=cell2mat(dividend_information(2:end,3));
- %派现金
- paixianjin=cell2mat(dividend_information(2:end,5));
- %配股价
- peigujia=cell2mat(dividend_information(2:end,6));
- %送股权
- songzhuangu=cell2mat(dividend_information(2:end,7));
- %配股数
- peigushu=cell2mat(dividend_information(2:end,8));
- %%向前的复权处理
- %除权位置
- location=ismember(Date,chuquanriqi);
- numlocation=1:length(Date);
- %将数据分开多少部分
- split_num=sum(location)+1;
- %得到了位置
- location_num=numlocation(location);
- %计算位置
- caculate_num=location_num-1;
- %得到计算复权分开的位置区间
- location_forward=[1 location_num;caculate_num length(Date)]';
- Close_yesterday=CLOSE(caculate_num);
- Close_T=Close_yesterday;
- %昨日收盘价的运算
- for i=1:length(Close_yesterday)
- %红利
- hongli=paixianjin(i)/10;
- %送股
- songgu=songzhuangu(i)/10;
- %配股数
- peigus=peigushu(i)/10;
- %配股价
- peiguj=peigujia(i)/10;
- %流通股份比例
- liutong=peigus+songgu;
- Close_yesterday(i)=(Close_yesterday(i)-hongli+peiguj*liutong)/(1+liutong);
- end
- %得到了比例
- close_ratio=Close_T./Close_yesterday;
- close_ratio_cum=cumprod(close_ratio);
- %向前的复权价格处理
- Foward_CLOSE=[];
- Foward_OPEN=[];
- Foward_LOW=[];
- Foward_HIGH=[];
- for i=1:length(location_forward)
- lo_num=location_forward(i,:);
- CLOSE_Forward=CLOSE(lo_num(1):lo_num(2));
- OPEN_Forward=OPEN(lo_num(1):lo_num(2));
- LOW_Forward=LOW(lo_num(1):lo_num(2));
- HIGH_Forward=HIGH(lo_num(1):lo_num(2));
- if i<length(location_forward)
- CLOSE_Forward=CLOSE_Forward/close_ratio_cum(end+1-i);
- Foward_CLOSE=[Foward_CLOSE;CLOSE_Forward];
- OPEN_Forward=OPEN_Forward/close_ratio_cum(end+1-i);
- Foward_OPEN=[Foward_OPEN;OPEN_Forward];
- LOW_Forward=LOW_Forward/close_ratio_cum(end+1-i);
- Foward_LOW=[Foward_LOW;LOW_Forward];
- HIGH_Forward=HIGH_Forward/close_ratio_cum(end+1-i);
- Foward_HIGH=[Foward_HIGH;HIGH_Forward];
- end
- if i==length(location_forward)
- Foward_CLOSE=[Foward_CLOSE;CLOSE_Forward];
- Foward_OPEN=[Foward_OPEN;OPEN_Forward];
- Foward_LOW=[Foward_LOW;LOW_Forward];
- Foward_HIGH=[Foward_HIGH;HIGH_Forward];
- end
- end
- %%作图
- FT_Candle(Foward_HIGH(1:200),Foward_LOW(1:200),Foward_CLOSE(1:200),...
- Foward_OPEN(1:200),'m',stockdata.dates(1:200),17)
- title('基于SZ300100的复权价格处理','fontname','华文楷体','fontsize',16)
- FT_MACD(Foward_CLOSE(1:200),9,26,12)
- title('基于SZ300100的MACD显示','fontname','华文楷体','fontsize',16)
- %%以上作图显示貌似还有一些除权的信息统计不全
复制代码- function FT_Candle(hi, lo, cl, op, color, dates, dateform)
- %%Modified by fantuanxiaot
- %%模仿faruto进行修改
- %%以下是一些例子
- % load disney
- % FT_Candle(dis_HIGH(end-20:end),dis_LOW(end-20:end),dis_CLOSE(end-20:end),dis_OPEN(end-20:end))
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end))
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end),'m')
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end),'m',dis_nv.dates(end-200:end))
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end),'m',datestr(dis_nv.dates(end-200:end))
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end),'m',dis_nv.dates(end-200:end),2)
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end),'m',datestr(dis_nv.dates(end-200:end)),2)
- % FT_Candle(dis_HIGH(end-200:end),dis_LOW(end-200:end),dis_CLOSE(end-200:end),dis_OPEN(end-200:end),'m',datestr(dis_nv.dates(end-200:end)),17)
- % FT_Candle(dis_HIGH,dis_LOW,dis_CLOSE,dis_OPEN,'m',datestr(dis_nv.dates),17)
- % FT_Candle(dis_HIGH(end-400:end),dis_LOW(end-400:end),dis_CLOSE(end-400:end),dis_OPEN(end-400:end),'m',datestr(dis_nv.dates(end-400:end)),17)
- %%以上是一些例子
- % CANDLE Candlestick chart.
- % CANDLE(HI, LO, CL, OP)
- % CANDLE(HI, LO, CL, OP, COLOR, DATES, DATEFORM)
- % Optional Inputs: COLOR, DATES, DATEFORM
- % Inputs:
- % HI - Column vector of high prices of a security.
- %
- % LO - Column vector of low prices of a security.
- %
- % CL - Column vector of closing prices of a security.
- %
- % OP - Column vector of opening prices of a security.
- % Optional Inputs:
- % COLOR - Three element color vector, [R G B], or a string specifying the
- % color name. MATLAB supplies a default color if none is specified
- % or if it is empty. The default color differs depending on the
- % background color of the figure window. See COLORSPEC in the
- % MATLAB Reference Guide for color names.
- % DATES - Column vector of dates for user specified X-axis tick
- % labels.
- %
- % DATEFORM - A scalar dictating the format of the date string tick labels.
- % See DATEAXIS for details on the date string formats.
- %
- % See also BOLLING, HIGHLOW, MOVAVG, POINTFIG.
- % Copyright 1995-2006 The MathWorks, Inc.
- % $Revision: 1.9.2.4 [ DISCUZ_CODE_4 ]nbsp;$Date: 2008/01/10 21:10:22 $
- if nargin < 5 || isempty(color)
- color ='k';
- end
- if nargin < 4
- error('finance:candle:missingInputs', ...
- 'Missing high, low, closing, or opening data.')
- end
- if size(hi, 2) > 1 || size(lo, 2) > 1 || size(cl, 2) > 1 || size(op, 2) > 1
- error('finance:candle:invalidInputs', ...
- 'Please specify input data as column vectors.')
- elseif size(hi, 1) ~= size(lo, 1) || size(lo, 1) ~= size(cl, 1) || size(cl, 1) ~= size(op, 1),
- error('finance:candle:mismatchInputData', ...
- 'Number of data must be consistent across inputs.');
- end
- if nargin == 6 || nargin == 7
- %补充了一下
- dates=datenum(dates);
- if size(dates, 2) ~= 1
- error('finance:candle:invalidDateSize', ...
- 'DATES must be a column vector.');
- elseif size(dates, 1) ~= size(hi, 1)
- error('finance:candle:mismatchDatesData', ...
- 'Number of dates must correspond to number of data.');
- end
- end
- %%以下作图进行了修改
- backg='g';
- backr='r';
- % Determine if current plot is held or not
- if ishold
- hldflag = 1;
- else
- hldflag = 0;
- end
- m = length(hi(:));
- figure(1)
- scrsz=get(0,'ScreenSize');
- set(figure(1),'Position',[scrsz(3)*0.1 scrsz(4)*0.25 scrsz(3)*0.95 scrsz(4)]*0.7,...
- 'color','w')
- movegui(figure(1),'center')
- % Need to pad all inputs with NaN's to leave spaces between day data
- tmp = nan;
- nanpad = tmp(1, ones(1, m));
- hilo = [hi'; lo'; nanpad];
- index = 1:m;
- indhilo = index(ones(3, 1), :);
- plot(indhilo(:), hilo(:), 'color', color)
- clpad = [cl(:)';nanpad];
- clpad = clpad(:)';
- oppad = [op(:)'; nanpad];
- oppad = oppad(:)';
- % Create boundaries for filled regions
- xbottom = index - 0.25;
- xbotpad = [xbottom(:)'; nanpad];
- xbotpad = xbotpad(:)';
- xtop = index + 0.25;
- xtoppad = [xtop(:)'; nanpad];
- xtoppad = xtoppad(:)';
- ybottom = min(clpad, oppad);
- ytop = max(clpad, oppad);
- % Plot lines between high and low price for day
- hold on
- % z-data used to stagger layering. This prevents renderer layering issues.
- zdata = xtoppad;
- zdata(~isnan(zdata)) = .01;
- zdata2 = zdata + .01;
- % Plot box representing closing and opening price span
- % If the opening price is less than the close, box is empty
- i = find(oppad(:) <= clpad(:));
- boxes(i) = patch([xbotpad(i); xbotpad(i); xtoppad(i); xtoppad(i)],...
- [ytop(i); ybottom(i); ybottom(i); ytop(i)], ...
- [zdata(i); zdata(i); zdata(i); zdata(i)], ...
- backr, 'edgecolor', 'r');
- % If the opening price is greater than the close, box is filled
- % If the opening price is greater than the close, box is filled
- i = find(oppad(:) > clpad(:));
- boxes(i) = patch([xbotpad(i); xbotpad(i); xtoppad(i); xtoppad(i)],...
- [ytop(i); ybottom(i); ybottom(i); ytop(i)],...
- [zdata2(i); zdata2(i); zdata2(i); zdata2(i)], ...
- backg, 'edgecolor', 'g'); %#ok
- % set tag for use with timeser.m
- setappdata(gca, 'plottype', 'Candle ') % set tag for use with timeser.m
- [Highest,hind] = max(hi);
- [Lowest,lind] = min(lo);
- % If original figure was not held, turn hold off
- if ~hldflag
- hold off
- end
- %[EOF]
- hold on;
- if nargin < 6
- text(hind,Highest*1.001,['\leftarrow',num2str(Highest)],'fontname','Times','fontsize',14);
- text(lind,Lowest*0.999,['\leftarrow',num2str(Lowest)],'fontname','Times','fontsize',14);
- end
- if nargin >=6
- dateset = dates;
- text(dateset(hind),Highest*1.001,['\leftarrow',num2str(Highest)],'fontname','Times','fontsize',14);
- text(dateset(lind),Lowest*0.999,['\leftarrow',num2str(Lowest)],'fontname','Times','fontsize',14);
- end
- % Add support for providing dates.
- % Add support for providing dates.
- if nargin == 6 || nargin == 7
- dateset = dates;
- hcdl_vl = findobj(gca, 'Type', 'line');
- hcdl_bx = findobj(gca, 'Type', 'patch');
- % The CANDLE plot is made up of patch(es) and a line.hcdl_vl is the
- % handle to the vertical lines; it's actually only 1 line object.
- % hcdl_bx contains the handle(s) of the patch object(s) that make up the
- % empty and filled boxes.The XData of those objects need to be changed
- % to dates so that ZOOM works correctly.
- line_xdata = get(hcdl_vl, 'XData');
- set(hcdl_vl, 'XData', dateset(line_xdata));
- for pidx=1:length(hcdl_bx), % Need to do loop since there can be 1 or 2 patches.
- patch_xdata = get(hcdl_bx(pidx), 'XData');
- offset = [-0.25*ones(2, size(patch_xdata, 2)); ...
- +0.25*ones(2, size(patch_xdata, 2))] * min(abs(diff(dateset)));
- set(hcdl_bx(pidx), 'XData', dateset(round(patch_xdata))+offset);
- end
- % Change XTickLabel to date string format.
- if ~exist('dateform', 'var') || isempty(dateform)
- datetick('x',20);
- else
- datetick('x', dateform);
- end
- end
- set(gca,'fontname','Times','fontsize',10)
- hold off
- %[EOF]
复制代码- function [DIFF, DEA, MACDbar] = FT_MACD(Close,short,long,Mlen)
- %Last Modified by blake 2013/8/29
- %Last Modified by fantuanxiaot 2015/2/8
- %MACD指标计算
- %几个具体的例子
- %FT_MACD
- %FT_MACD(10*rand(100,1),9,26,12)
- %[DIFF, DEA, MACDbar] = FT_MACD
- %[DIFF, DEA, MACDbar] = FT_MACD(10*rand(100,1),9,26,12)
- %返回MACD值,如果无需返回则画图
- %Email:blake_libo@163.com
- %Input:
- % Close: 输入的序列
- % short: 短周期
- % long: 长周期
- % Mlen: 均线周期
- % handle: axes句柄
- %Output:
- % MA_value: 计算的均线返回值
- %程序实现测试所使用的MATLAB版本:MATLAB R2011b(7.13)
- %如果程序在您本机运行不了,请首先检查您MATLAB的版本号,推荐使用较新版本的MATLAB。
- %%输入输出参数设置
- if nargin==3
- Mlen = 9;
- end
- if nargin==2
- long = 26;
- Mlen = 9;
- end
- if nargin==1
- short = 12;
- long = 26;
- Mlen = 9;
- end
- if nargin==0
- Close=10*rand(100,1);
- short = 12;
- long = 26;
- Mlen = 9;
- end
- %%计算
- DIFF = FT_EMA(Close, short)-FT_EMA(Close, long);
- DEA = FT_EMA(DIFF, Mlen);
- DIFF(1:29) = 0;
- DEA(1:29) = 0;
- MACDbar = 2*(DIFF-DEA);
- MACDbar(MACDbar==0) = nan;
- DIFF(DIFF==0) = nan;
- DEA(DEA==0) = nan;
- MACDbar = MACDbar';
- DEA = DEA';
- DIFF = DIFF';
- %%Plot
- if nargout == 0
- figure(2)
- scrsz=get(0,'ScreenSize');
- set(figure(2),'Position',[scrsz(3)*0.1 scrsz(4)*0.25 scrsz(3)*0.95 scrsz(4)]*0.7,...
- 'color','w')
- movegui(figure(2),'center')
- hold on;
- pind = find(MACDbar >= 0);
- nind = find(MACDbar < 0);
- h1 = bar(pind,MACDbar(pind),'r','EdgeColor','r','LineWidth',0.1);
- h2 = bar(nind,MACDbar(nind),'g','EdgeColor','g','LineWidth',0.1);
- plot(DIFF,'k');
- plot(DEA,'b');
- legend('MACD','MACD','DIFF','DEA')
- set(gca,'fontname','华文楷体','fontsize',12)
- current_axes=gca;
- strx=get(current_axes,'XTickLabel');
- stry=get(current_axes,'YTickLabel');
- x=get(current_axes,'XTick');
- y=get(current_axes,'YTick');
- yl=ylim(current_axes);
- xl=xlim(current_axes);
- %句柄设置
- set(current_axes,'XTickLabel',[]);
- set(current_axes,'YTickLabel',[]);
- %使之倾斜
- xtoy=zeros(1,length(x))+yl(1)-(max(yl)-min(yl))/30;
- ytox=zeros(1,length(y))+xl(1)-(max(xl)-min(xl))/30;
- text(x,xtoy,strx,'rotation',-20,'HorizontalAlignment'...
- ,'center','FontName','times','FontSize',10,'backg','c');
- text(ytox,y,stry,'rotation',-40,'HorizontalAlignment'...
- ,'center','FontName','times','FontSize',12,'backg','c');
- title('MACD/DEA/DIFF figure','fontname','华文楷体','fontsize',16)
- end
- end
- function EMAvalue = FT_EMA(Price, len, coef)
- %指数移动平均线 函数
- %Last Modified by LiYang 2011/12/27
- %Email:faruto@163.com
- %程序实现测试所使用的MATLAB版本:MATLAB R2011b(7.13)
- %如果程序在您本机运行不了,请首先检查您MATLAB的版本号,推荐使用较新版本的MATLAB。
- %%输入参数检查
- error(nargchk(1, 3, nargin))
- if nargin < 3
- coef = [];
- end
- if nargin< 2
- len = 2;
- end
- %%指定EMA系数
- if isempty(coef)
- k = 2/(len + 1);
- else
- k = coef;
- end
- %%计算EMAvalue
- EMAvalue = zeros(length(Price), 1);
- EMAvalue(1:len-1) = Price(1:len-1);
- for i = len:length(Price)
- EMAvalue(i) = k*( Price(i)-EMAvalue(i-1) ) + EMAvalue(i-1);
- end
- end
- function MA_value = FT_MA(Price, MAlen)
- %移动平均线
- %by liyang 2011/12/13
- %farutoliyang@gmail.com
- %Input:
- % Price: 输入的序列
- % MAlen: 均线周期
- %Output:
- % MA_value: 计算的均线返回值
- %%输入参数检查
- if nargin < 2
- % 默认均线周期为5(5分钟线、5日线)
- MAlen = 5;
- end
- error(nargchk(1, 2, nargin));
- if MAlen <= 0
- error('The length of MA must >= 1');
- end
- %%初始化
- len = numel(Price);
- MA_value = zeros(len, 1);
- Price = Price(:);
- %%计算均线
- MA_value(1:MAlen-1) = Price(1:MAlen-1);
- for i = MAlen:len
- MA_value(i) = sum( Price(i-MAlen+1:i) )/MAlen;
- end
- end
复制代码
[/hide]
|