5
5
* Author: fasiondog
6
6
*/
7
7
8
+ #include " hikyuu/indicator/crt/ALIGN.h"
9
+ #include " hikyuu/indicator/crt/PRICELIST.h"
8
10
#include " ICycle.h"
9
11
10
12
#if HKU_SUPPORT_SERIALIZATION
@@ -58,6 +60,168 @@ void ICycle::_checkParam(const string& name) const {
58
60
}
59
61
}
60
62
63
+ static void calculate_no_delay (const DatetimeList& datelist, int adjust_cycle, const string& mode,
64
+ PriceList& buf) {
65
+ if (" week" == mode) {
66
+ Datetime cur_cycle_end = datelist.front ().nextWeek ();
67
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
68
+ const auto & date = datelist[i];
69
+ bool adjust = (date.dayOfWeek () == adjust_cycle);
70
+ if (adjust) {
71
+ cur_cycle_end = date.nextWeek ();
72
+ }
73
+ if (cur_cycle_end >= datelist.back ()) {
74
+ cur_cycle_end = datelist.back () + Seconds (1 );
75
+ }
76
+ buf[i] = adjust;
77
+ }
78
+ } else if (" month" == mode) {
79
+ Datetime cur_cycle_end = datelist.front ().nextMonth ();
80
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
81
+ const auto & date = datelist[i];
82
+ bool adjust = (date.day () == adjust_cycle);
83
+ if (adjust) {
84
+ cur_cycle_end = date.nextMonth ();
85
+ }
86
+ if (cur_cycle_end >= datelist.back ()) {
87
+ cur_cycle_end = datelist.back () + Seconds (1 );
88
+ }
89
+ buf[i] = adjust;
90
+ }
91
+ } else if (" quarter" == mode) {
92
+ Datetime cur_cycle_end = datelist.front ().nextQuarter ();
93
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
94
+ const auto & date = datelist[i];
95
+ bool adjust = (date.day () == adjust_cycle);
96
+ if (adjust) {
97
+ cur_cycle_end = date.nextQuarter ();
98
+ }
99
+ if (cur_cycle_end >= datelist.back ()) {
100
+ cur_cycle_end = datelist.back () + Seconds (1 );
101
+ }
102
+ buf[i] = adjust;
103
+ }
104
+ } else if (" year" == mode) {
105
+ Datetime cur_cycle_end = datelist.front ().nextYear ();
106
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
107
+ const auto & date = datelist[i];
108
+ bool adjust = (date.dayOfYear () == adjust_cycle);
109
+ if (adjust) {
110
+ cur_cycle_end = date.nextYear ();
111
+ }
112
+ if (cur_cycle_end >= datelist.back ()) {
113
+ cur_cycle_end = datelist.back () + Seconds (1 );
114
+ }
115
+ buf[i] = adjust;
116
+ }
117
+ }
118
+ }
119
+
120
+ static void calculate_delay (const DatetimeList& datelist, int adjust_cycle, const string& mode,
121
+ PriceList& buf) {
122
+ std::set<Datetime> adjust_date_set;
123
+ if (" week" == mode) {
124
+ Datetime cur_cycle_end = datelist.front ().nextWeek ();
125
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
126
+ const auto & date = datelist[i];
127
+ Datetime adjust_date = date.startOfWeek () + Days (adjust_cycle - 1 );
128
+ bool adjust = false ;
129
+ if (date == adjust_date) {
130
+ adjust = true ;
131
+ adjust_date_set.emplace (adjust_date);
132
+ } else if (adjust_date_set.find (adjust_date) == adjust_date_set.end () &&
133
+ date > adjust_date) {
134
+ adjust = true ;
135
+ adjust_date_set.emplace (adjust_date);
136
+ }
137
+
138
+ if (adjust) {
139
+ cur_cycle_end = date.nextWeek ();
140
+ }
141
+ if (cur_cycle_end >= datelist.back ()) {
142
+ cur_cycle_end = datelist.back () + Seconds (1 );
143
+ }
144
+
145
+ buf[i] = adjust;
146
+ }
147
+
148
+ } else if (" month" == mode) {
149
+ Datetime cur_cycle_end = datelist.front ().nextMonth ();
150
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
151
+ const auto & date = datelist[i];
152
+ Datetime adjust_date = date.startOfMonth () + Days (adjust_cycle - 1 );
153
+ bool adjust = false ;
154
+ if (date == adjust_date) {
155
+ adjust = true ;
156
+ adjust_date_set.emplace (adjust_date);
157
+ } else if (adjust_date_set.find (adjust_date) == adjust_date_set.end () &&
158
+ date > adjust_date) {
159
+ adjust = true ;
160
+ adjust_date_set.emplace (adjust_date);
161
+ }
162
+
163
+ if (adjust) {
164
+ cur_cycle_end = date.nextMonth ();
165
+ }
166
+ if (cur_cycle_end >= datelist.back ()) {
167
+ cur_cycle_end = datelist.back () + Seconds (1 );
168
+ }
169
+
170
+ buf[i] = adjust;
171
+ }
172
+
173
+ } else if (" quarter" == mode) {
174
+ Datetime cur_cycle_end = datelist.front ().nextQuarter ();
175
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
176
+ const auto & date = datelist[i];
177
+ Datetime adjust_date = date.startOfQuarter () + Days (adjust_cycle - 1 );
178
+ bool adjust = false ;
179
+ if (date == adjust_date) {
180
+ adjust = true ;
181
+ adjust_date_set.emplace (adjust_date);
182
+ } else if (adjust_date_set.find (adjust_date) == adjust_date_set.end () &&
183
+ date > adjust_date) {
184
+ adjust = true ;
185
+ adjust_date_set.emplace (adjust_date);
186
+ }
187
+
188
+ if (adjust) {
189
+ cur_cycle_end = date.nextQuarter ();
190
+ }
191
+ if (cur_cycle_end >= datelist.back ()) {
192
+ cur_cycle_end = datelist.back () + Seconds (1 );
193
+ }
194
+
195
+ buf[i] = adjust;
196
+ }
197
+
198
+ } else if (" year" == mode) {
199
+ Datetime cur_cycle_end = datelist.front ().nextYear ();
200
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
201
+ const auto & date = datelist[i];
202
+ Datetime adjust_date = date.startOfYear () + Days (adjust_cycle - 1 );
203
+ bool adjust = false ;
204
+ if (date == adjust_date) {
205
+ adjust = true ;
206
+ adjust_date_set.emplace (adjust_date);
207
+ } else if (adjust_date_set.find (adjust_date) == adjust_date_set.end () &&
208
+ date > adjust_date) {
209
+ adjust = true ;
210
+ adjust_date_set.emplace (adjust_date);
211
+ }
212
+
213
+ if (adjust) {
214
+ cur_cycle_end = date.nextYear ();
215
+ }
216
+ if (cur_cycle_end >= datelist.back ()) {
217
+ cur_cycle_end = datelist.back () + Seconds (1 );
218
+ }
219
+
220
+ buf[i] = adjust;
221
+ }
222
+ }
223
+ }
224
+
61
225
void ICycle::_calculate (const Indicator& data) {
62
226
HKU_WARN_IF (!isLeaf () && !data.empty (),
63
227
" The input is ignored because {} depends on the context!" , m_name);
@@ -67,14 +231,57 @@ void ICycle::_calculate(const Indicator& data) {
67
231
HKU_IF_RETURN (total == 0 , void ());
68
232
69
233
_readyBuffer (total, 1 );
234
+
235
+ DatetimeList datelist = k.getStock ().getTradingCalendar (k.getQuery ());
236
+ HKU_IF_RETURN (datelist.empty (), void ());
237
+
238
+ int adjust_cycle = getParam<int >(" adjust_cycle" );
239
+ string adjust_mode = getParam<string>(" adjust_mode" );
240
+ bool delay_to_trading_day = getParam<bool >(" delay_to_trading_day" );
241
+
242
+ PriceList buf (datelist.size ());
243
+ if (" query" == adjust_mode || " day" == adjust_mode) {
244
+ size_t cur_adjust_ix = 0 ;
245
+ Datetime cur_cycle_end;
246
+ for (size_t i = 0 , total = datelist.size (); i < total; i++) {
247
+ bool adjust = false ;
248
+ if (i == cur_adjust_ix) {
249
+ adjust = true ;
250
+ cur_adjust_ix += adjust_cycle;
251
+ cur_cycle_end =
252
+ cur_adjust_ix < total ? datelist[cur_adjust_ix] : datelist.back () + Seconds (1 );
253
+ }
254
+ buf[i] = adjust;
255
+ }
256
+
257
+ } else if (delay_to_trading_day) {
258
+ calculate_delay (datelist, adjust_cycle, adjust_mode, buf);
259
+ } else {
260
+ calculate_no_delay (datelist, adjust_cycle, adjust_mode, buf);
261
+ }
262
+
263
+ Indicator tmpind = ALIGN (PRICELIST (buf, datelist), k);
264
+ const auto * src = tmpind.data ();
265
+ auto * dst = this ->data ();
266
+ HKU_ASSERT (tmpind.size () == total);
267
+ memcpy (dst, src, sizeof (value_t ) * total);
70
268
}
71
269
72
- Indicator HKU_API CYCLE () {
73
- return make_shared<ICycle>()->calculate ();
270
+ Indicator HKU_API CYCLE (int adjust_cycle, const string& adjust_mode, bool delay_to_trading_day) {
271
+ auto p = make_shared<ICycle>();
272
+ p->setParam <int >(" adjust_cycle" , adjust_cycle);
273
+ p->setParam <string>(" adjust_mode" , adjust_mode);
274
+ p->setParam <bool >(" delay_to_trading_day" , delay_to_trading_day);
275
+ return Indicator (p);
74
276
}
75
277
76
- Indicator HKU_API CYCLE (const KData& k) {
77
- return Indicator (make_shared<ICycle>(k));
278
+ Indicator HKU_API CYCLE (const KData& k, int adjust_cycle, const string& adjust_mode,
279
+ bool delay_to_trading_day) {
280
+ auto p = make_shared<ICycle>(k);
281
+ p->setParam <int >(" adjust_cycle" , adjust_cycle);
282
+ p->setParam <string>(" adjust_mode" , adjust_mode);
283
+ p->setParam <bool >(" delay_to_trading_day" , delay_to_trading_day);
284
+ return p->calculate ();
78
285
}
79
286
80
287
} /* namespace hku */
0 commit comments