-
Notifications
You must be signed in to change notification settings - Fork 6
/
tick2bar.m
156 lines (125 loc) · 4.85 KB
/
tick2bar.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
function [ varargout ] = tick2bar(dates,price,amount,barlength,bartype,sparse)
%tick2bar Converts ticks to OHLCV matrix
%
% Copyright (C) 2015 Petr Javorik [email protected]
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.
%
%
% Input
% dates: datetime array
% price: traded price in tick granularity
% amount: volume in tick granularity
% barlength: barlength in bartype resolution
% bartype: choose one from
% s(seconds),m(minutes),h(hours),d(days),M(months),Y(years)
% sparsity: {0,1} determine whether you want to include zero volume
% intervals in output OHLCV matrix. Default behaviour is sparse = 0
% because it's common for ordinary OHLCV bars.
% Output
% varargout(1): datetime array for particular interval(interval starting datetime)
% varargout(2): OHLCV matrix
%
% Example:
% If we want 2min bars we choose barlength = 2 and bartype = 'm'
%
%% Input variables check
narginchk(5,6)
assert(ismember(bartype,{'s','m','h','d','M','Y'}),'Not valid bartype input!');
refsize = size(dates,1);
assert(...
(size(price,1) == refsize) && ...
(size(amount,1) == refsize), ...
'Input vector sizes don''t match!');
assert(isnumeric(barlength),'Not valid barlength input!');
if exist('sparse','var')
assert(sparse == 0 || sparse == 1,'Not valid sparse input, valid inputs are 0 or 1!');
end
switch nargin
case 5
sparsity = 0;
case 6
sparsity = 1;
end
%% Aggregate by interval
switch bartype
case 's'
assert(barlength >= 1 && barlength <= 59,'Not valid barlength for seconds!');
workdatevec = 6;
case 'm'
assert(barlength >= 1 && barlength <= 59,'Not valid barlength for minutes!');
workdatevec = 5;
case 'h'
assert(barlength >= 1 && barlength <= 23,'Not valid barlength for hours!');
workdatevec = 4;
case 'd'
assert(barlength >= 1 && barlength <= 30,'Not valid barlength for days!');
workdatevec = 3;
case 'M'
assert(barlength >= 1 && barlength <= 11,'Not valid barlength for months!');
workdatevec = 2;
case 'Y'
assert(barlength >= 1 && barlength <= 10,'Not valid barlength for years!');
workdatevec = 1;
end
datetimemesh = (dates(1):1/24/60/60:dates(end))';
datetimemesh = datevec(datetimemesh);
datetimemesh2 = datetimemesh(:,1:workdatevec);
datetimemesh2(:,workdatevec) = floor(datetimemesh(:,workdatevec)/barlength);
[uniqdatetimemesh,~,~] = unique(datetimemesh2(:,1:workdatevec),'rows');
datevector = datevec(dates);
datevector2 = datevector(:,1:workdatevec);
datevector2(:,workdatevec) = floor(datevector(:,workdatevec)/barlength);
[uniqdatevec,~,subs] = unique(datevector2(:,1:workdatevec),'rows');
% Interval Open calculation
O = accumarray(subs,price,[],@(x) x(1));
% Interval High calculation
H = accumarray(subs,price,[],@max);
% Interval Low calculation
L = accumarray(subs,price,[],@min);
% Interval Close calculation
C = accumarray(subs,price,[],@(x) x(end));
% Interval Volume calculation
V = accumarray(subs,amount,[],@sum);
%% Output
uniqdatevec(:,workdatevec) = uniqdatevec(:,workdatevec).*barlength;
if size(uniqdatevec,2) < 6
uniqdatevec = [uniqdatevec,zeros(size(uniqdatevec,1),6-size(uniqdatevec,2))];
end
datesout = datetime(uniqdatevec);
OHLCV = [O,H,L,C,V];
% OHLCV "sparse" matrix without zero volume bars
if sparsity == 1
varargout{1} = datesout;
varargout{2} = OHLCV;
% OHLCV matrix with zero volume bars
elseif sparsity == 0
uniqdatetimemesh(:,workdatevec) = uniqdatetimemesh(:,workdatevec).*barlength;
if size(uniqdatetimemesh,2) < 6
uniqdatetimemesh = [uniqdatetimemesh,zeros(size(uniqdatetimemesh,1),6-size(uniqdatetimemesh,2))];
end
datesoutmesh = datetime(uniqdatetimemesh);
[~,id] = ismember(datesout,datesoutmesh);
OHLCV_on_date_mesh(id,:) = OHLCV;
for rows = 1:length(OHLCV_on_date_mesh)
for cols = 1:4
if OHLCV_on_date_mesh(rows,cols) == 0
OHLCV_on_date_mesh(rows,cols) = OHLCV_on_date_mesh(rows - 1,4);
end
end
end
varargout{1} = datesoutmesh;
varargout{2} = OHLCV_on_date_mesh;
end
end