-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdac2.py
732 lines (618 loc) · 21.6 KB
/
dac2.py
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
# -*-coding:utf-8 -*-
'''
dac的@indicator版本
提供更简单的使用方式和实现方式
'''
import operator
from collections import (
deque,
)
from base import (
BaseObject,
fcustom,
indicator,
icache,
t2order_if,
)
from dac import (
XBASE, #100
CBASE, #XBASE*XBASE,用于XATR
FBASE, #10
)
XBASE = 100 #整数运算的放大倍数
CBASE = XBASE * XBASE #XATR倍数
FBASE = 10 #整数运算的放大倍数2
##########
#编写指标时,请务必确保这个判断中的标识字符串和下面赋值的名称的一致性,否则会每次都赋值和计算,内存立马挂掉
# if not hasattr(_ts,'ss'):
# _ts.ss = []
#
##########
###############
# 基本序列运算
#
###############
@indicator
def OPER1(source,oper,_ts=None):
'''
单参数序列运算
'''
if not _ts.initialized:
_ts.initialized = True
_ts.ss = []
for i in range(len(_ts.ss),len(source)):
#print 'new data:',source[i]
_ts.ss.append(oper(source[i]))
return _ts.ss
'''
不同的operator.xxx, 使OPER1下缓存的key不同,不会导致混淆
'''
NEG = fcustom(OPER1,oper=operator.neg)
ABS = fcustom(OPER1,oper=operator.abs)
NOT = fcustom(OPER1,oper=operator.not_)
@indicator
def OPER2(source1,source2,oper,_ts=None):
'''
双参数序列运算
'''
assert len(source1) == len(source2),'len(source1) != len(source2)'
if not _ts.initialized:
_ts.initialized = True
#print 'new oper2 ss'
_ts.ss = []
for i in range(len(_ts.ss),len(source1)):
#print 'new data:',source1[i],source2[i]
_ts.ss.append(oper(source1[i],source2[i]))
return _ts.ss
ADD = fcustom(OPER2,oper=operator.add)
SUB = fcustom(OPER2,oper=operator.sub)
MUL = fcustom(OPER2,oper=operator.mul)
#AND = fcustom(OPER2,oper=operator.and_) #这个是位操作
#OR = fcustom(OPER2,oper=operator.or_) #这个是位操作
#XOR = fcustom(OPER2,oper=operator.xor) #这个是位操作
LT = fcustom(OPER2,oper=operator.lt)
LE = fcustom(OPER2,oper=operator.le)
EQ = fcustom(OPER2,oper=operator.eq)
GT = fcustom(OPER2,oper=operator.gt)
GE = fcustom(OPER2,oper=operator.ge)
@indicator
def OPER21(source1,vs,oper,_ts=None):
'''
双参数运算,第一个为序列,第二个为数值
'''
if not _ts.initialized:
_ts.initialized = True
_ts.ss = []
for i in range(len(_ts.ss),len(source1)):
#print 'new data:',source1[i]
_ts.ss.append(oper(source1[i],vs))
return _ts.ss
ADD1 = fcustom(OPER21,oper=operator.add)
SUB1 = fcustom(OPER21,oper=operator.sub)
MUL1 = fcustom(OPER21,oper=operator.mul)
#AND1 = fcustom(OPER21,oper=operator.and_) #这个是位操作
#OR1 = fcustom(OPER21,oper=operator.or_) #这个是位操作
#XOR1 = fcustom(OPER21,oper=operator.xor) #这个是位操作
LT1 = fcustom(OPER21,oper=operator.lt)
LE1 = fcustom(OPER21,oper=operator.le)
EQ1 = fcustom(OPER21,oper=operator.eq)
GT1 = fcustom(OPER21,oper=operator.gt)
GE1 = fcustom(OPER21,oper=operator.ge)
@indicator
def AND(source1,source2,_ts=None):
'''
双序列参数AND运算
'''
assert len(source1) == len(source2),'len(source1) != len(source2)'
if not _ts.initialized:
_ts.initialized = True
_ts.ss = []
for i in range(len(_ts.ss),len(source1)):
#print 'new data:',source1[i],source2[i]
_ts.ss.append((source1[i] and source2[i])!=0)
return _ts.ss
@indicator
def GAND(_ts=None,*args):
assert len(args)>0,'GAND params number less than 1'
if not _ts.initialized:
_ts.initialized = True
_ts.ga = []
for i in range(len(_ts.ga),len(args[0])):
rv = all([vs[i] for vs in args])
_ts.ga.append(rv!=0)
return _ts.ga
@indicator
def GOR(_ts=None,*args):
assert len(args)>0,'GOR params number less than 1'
#print 'ts=%s,args=%s' % (_ts,args)
if not _ts.initialized:
_ts.initialized = True
_ts.gor = []
for i in range(len(_ts.gor),len(args[0])):
rv = any([vs[i] for vs in args])
_ts.gor.append(rv!=0)
return _ts.gor
#GAND = fcustom(GOPER,oper=all) #有可变参数时,就不能再有_ts之外的参数用fcustom指定默认值
#GOR = fcustom(GOPER,oper=any) #有可变参数时,就不能再有_ts之外的参数用fcustom指定默认值
@indicator
def DIV(source1,source2,_ts=None):
'''
序列除法
'''
assert len(source1) == len(source2),'len(source1) != len(source2)'
if not _ts.initialized:
_ts.initialized = True
_ts.ss = []
for i in range(len(_ts.ss),len(source1)):
#print 'new data:',source1[i],source2[i]
r = (source1[i]+source2[i]/2)/source2[i] if source2[i] != 0 else source1[i]*1000
_ts.ss.append(r)
return _ts.ss
@indicator
def DIV1(source1,vs,_ts=None):
'''
序列除常数
'''
assert vs!=0,'divisor vs == 0'
if not _ts.initialized:
_ts.initialized = True
_ts.ss = []
for i in range(len(_ts.ss),len(source1)):
#print 'new data:',source1[i]
_ts.ss.append((source1[i]+vs/2)/vs)
return _ts.ss
############
# 常用指标
#
############
@indicator
def ACCUMULATE(source,_ts=None):
'''
累加
'''
if not _ts.initialized:
_ts.initialized = True
_ts.sa = []
ss = _ts.sa[-1] if _ts.sa else 0
for i in range(len(_ts.sa),len(source)):
ss += source[i]
_ts.sa.append(ss)
#print id(_ts),id(source),source,_ts.sa
return _ts.sa
NSUM = ACCUMULATE
@indicator
def MSUM(source,mlen,_ts=None):
'''
移动求和
'''
if not _ts.initialized:
_ts.initialized = True
_ts.ms = []
ss = ACCUMULATE(source)
for i in range(len(_ts.ms),len(source)):
v = ss[i] - ss[i-mlen] if i>=mlen else ss[i]
_ts.ms.append(v)
return _ts.ms
@indicator
def MA(source,mlen,_ts=None):
'''
移动平均. 使用MSUM
使用方式:
rev = MA(source,13) #返回source的13期移动平均
当序列中元素个数<mlen时,结果序列为到该元素为止的所有元素值的平均
'''
assert mlen>0,u'mlen should > 0'
if not _ts.initialized:
_ts.initialized = True
_ts.ma = []
ms = MSUM(source,mlen)
for i in range(len(_ts.ma),len(source)):
#当累计个数<nlen时,求其平均值,而不是累计值/mlen
rlen = mlen if i>=mlen else i+1
_ts.ma.append((ms[i]+rlen/2)/rlen)
return _ts.ma
@indicator
def MA_2(source,mlen,_ts=None):
'''
移动平均. 直接计
使用方式:
rev = MA(source,13) #返回source的13期移动平均
当序列中元素个数<mlen时,结果序列为到该元素为止的所有元素值的平均
'''
assert mlen>0,u'mlen should > 0'
if not _ts.initialized:
_ts.initialized = True
_ts.sa = [0]*mlen #哨兵
_ts.ma = []
slen = len(_ts.ma)
ss = _ts.sa[-1]
for i in range(slen,len(source)):
ss += source[i]
_ts.sa.append(ss)
#print ss,_ts.sa[i-mlen]
#当累计个数<nlen时,求其平均值,而不是累计值/mlen
rlen = mlen if mlen < i+1 else i+1
_ts.ma.append((ss-_ts.sa[-rlen-1]+rlen/2)/rlen)
#print _ts.sa
return _ts.ma
@indicator
def NMA(source,_ts=None):
'''
总平均
使用方式:
rev = MA(source) #返回source的当期及之前的平均值
'''
if not _ts.initialized:
_ts.initialized = True
_ts.sa = [0] #哨兵
_ts.nma = []
#print 'initial NMA'
slen = len(_ts.nma)
ss = _ts.sa[-1]
for i in range(slen,len(source)):
ss += source[i]
_ts.sa.append(ss)
#print ss,_ts.sa[-1]
_ts.nma.append((ss+(i+1)/2)/(i+1))
#print _ts.sa
return _ts.nma
@indicator
def CEXPMA(source,mlen,_ts=None):
assert mlen>0,u'mlen should > 0'
if len(source) == 0:#不计算空序列,直接返回
return []
if not _ts.initialized:
_ts.initialized = True
#print 'new cexpma ema'
_ts.ema = [source[0]] #哨兵元素是source[0],确保计算得到的值在<mlen元素的情况下也正确
cur = _ts.ema[-1]
for i in range(len(_ts.ema),len(source)):
cur = (source[i]*2 + cur*(mlen-1) + (mlen+1)/2)/(mlen+1)
_ts.ema.append(cur)
return _ts.ema
EMA = CEXPMA
@indicator
def MACD(source,ifast=12,islow=26,idiff=9,_ts=None):
if not _ts.initialized:
_ts.initialized = True
_ts.diff = []
_ts.dea = []
src = MUL1(source,FBASE)
sfast = EMA(src,ifast)
sslow = EMA(src,islow)
_ts.diff = SUB(sfast,sslow)
_ts.dea = EMA(_ts.diff,idiff)
return _ts
@indicator
def TR(sclose,shigh,slow,_ts=None):
if len(sclose) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
_ts.tr = [(shigh[0]-slow[0]) * XBASE]
for i in range(len(_ts.tr),len(sclose)):
#c,h,l = sclose[slen-1],shigh[slen],sclose[slen]
hh = shigh[i] if shigh[i] > sclose[i-1] else sclose[i-1]
ll = slow[i] if slow[i] < sclose[i-1] else sclose[i-1]
_ts.tr.append((hh-ll)*XBASE)
return _ts.tr
@indicator
def ATR(sclose,shigh,slow,length=20,_ts=None):
ltr = TR(sclose,shigh,slow)
return CEXPMA(ltr,length)
@indicator
def XATR(sclose,shigh,slow,length=20,_ts=None):
latr = ATR(sclose,shigh,slow,length)
return DIV(MUL1(latr,CBASE),sclose)
@indicator
def STREND(source,_ts=None):
''' 简单累积趋势2
与strend相比,上升过程中,平也当作上,下降中平作下
若当前趋势为上升或0,trend值为n>0
则新trend值为:
n+1 当前值 >= pre
-1 当前值 < pre
若当前趋势为下降,trend值为n(负数)
则下一trend值为:
n-1 当前值 <= pre
1 当前值 > pre
0为初始趋势(缺少判断时)
'''
if len(source) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
_ts.sd = [0] #第一个是无趋势
slen = len(_ts.sd)
scur = _ts.sd[-1]
vpre = source[slen-1]
for i in range(slen,len(source)):
vcur = source[i]
if vcur > vpre:
scur = scur + 1 if scur > 0 else 1
elif vcur < vpre:
scur = scur - 1 if scur < 0 else -1
else: #curv == pre_v
scur = scur + 1 if scur >= 0 else scur-1 #最初为0时,也算上升
_ts.sd.append(scur)
vpre = vcur
return _ts.sd
#TMAX,TMIN,UCROSS,DCROSS
@indicator
def TMM(source,covered,vmm,fcmp,fgroup,_ts=None):
'''
vmm: 比较用的极值
fcmp: 比较函数
fgroup:整体比较函数
cover=0时,返回的是截止到当前元素的最值(cover<0也如此)
'''
assert covered >=0, 'TMM: cover <0'
if len(source) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
#print 'new tmm'
_ts.tmm = [] #第一个是无趋势
_ts.buffer = None
slen = len(source)
pre_len = slen if slen <= covered else covered
cmm = _ts.tmm[-1] if _ts.tmm else vmm
for i in range(len(_ts.tmm),pre_len):
if fcmp(source[i],cmm):
cmm = source[i]
_ts.tmm.append(cmm)
if slen <= covered:
return _ts.tmm
tlen = len(_ts.tmm)
if _ts.buffer:
buffer = _ts.buffer
else:
buffer = _ts.buffer = deque(source[tlen-covered:tlen])
#print 'in tmm:tlen=%s,len(source)=%s' % (tlen,len(source))
for i in range(tlen,len(source)):
v = source[i]
buffer.append(v)
vquit=buffer.popleft()
if fcmp(v,cmm):
cmm = v
if cmm == vquit and v != cmm: #退出的正好是最大值,计算前covered-1个元素的最大值, pre=source[i-1]
#cmm = fgroup(source[i-covered+1:i+1])
cmm = fgroup(buffer)
_ts.tmm.append(cmm)
return _ts.tmm
TMAX = fcustom(TMM,vmm=-99999999,fcmp=operator.gt,fgroup=max)
TMIN = fcustom(TMM,vmm=99999999,fcmp=operator.lt,fgroup=min)
@indicator
def NMM(source,vmm,fcmp,_ts=None):
'''
从index0算起的极值.
相当于covered取最大值时的TMM
'''
if len(source) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
#print 'new nmm'
_ts.nmm = [] #第一个是无趋势
slen = len(source)
cmm = _ts.nmm[-1] if _ts.nmm else vmm
for i in range(len(_ts.nmm),len(source)):
if fcmp(source[i],cmm):
cmm = source[i]
_ts.nmm.append(cmm)
return _ts.nmm
NMAX = fcustom(NMM,vmm=-99999999,fcmp=operator.gt)
NMIN = fcustom(NMM,vmm=99999999,fcmp=operator.lt)
@indicator
def CROSS(source1,source2,rcmp,_ts=None):
'''
source2去交叉source1
rcmp为判断已交叉状态的函数
返回值中,0为未×,1为×
'''
if len(source1) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
_ts.crs = [1 if rcmp(source2[0],source1[0]) else 0] #第一个取决于状态,如果为已×,则为1
ps = _ts.crs[-1]
for i in range(len(_ts.crs),len(source1)):
cs = rcmp(source2[i],source1[i])
_ts.crs.append(1 if not ps and cs else 0)
ps = cs
return _ts.crs
UPCROSS = fcustom(CROSS,rcmp = operator.gt) #追击-平-平-超越,以及超越-平-超越均算×
DOWNCROSS = fcustom(CROSS,rcmp = operator.lt) #追击-平-平-超越,以及超越-平-超越均算×
@indicator
def NCROSS(source,target,rcmp,_ts=None):
'''
source去交叉target, target为数字
rcmp为判断已交叉状态的函数
返回值中,0为未×,1为×
'''
if len(source) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
_ts.crs = [1 if rcmp(source[0],target) else 0] #第一个取决于状态,如果为已×,则为1
ps = _ts.crs[-1]
for i in range(len(_ts.crs),len(source)):
cs = rcmp(source[i],target)
_ts.crs.append(1 if not ps and cs else 0)
ps = cs
return _ts.crs
NUPCROSS = fcustom(NCROSS,rcmp = operator.gt) #追击-平-平-超越,以及超越-平-超越均算×
NDOWNCROSS = fcustom(NCROSS,rcmp = operator.lt) #追击-平-平-超越,以及超越-平-超越均算×
@indicator
def REF(source,offset=1,_ts=None):
'''
取得偏移为offset的序列
前offset部分用第一元素填充
如果仅用于比较,不建议用这个函数,而直接用[-1]下标比较
只有在偏移CROSS时才有意义
'''
if len(source) == 0:
return []
if not _ts.initialized:
_ts.initialized = True
_ts.ref = [source[0]]
#print 'initialize REF'
for i in range(len(_ts.ref),offset if offset <= len(source) else len(source)):
_ts.ref.append(source[0])
for i in range(len(_ts.ref),len(source)):
_ts.ref.append(source[i-offset])
return _ts.ref
NullMinute = BaseObject(sopen=[],sclose=[],shigh=[],slow=[],svol=[],iorder=[],sholding=[])
@indicator
def MINUTE(ticks,pre_min1=None,t2order=t2order_if,_ts=None):
'''
分钟切分
这个实现的最大问题是未处理最后一分钟的收尾
但这种场景仅用于保存数据, 可以在使用MINUTE之后, 由特别的语句去判断最后一个tick,并收尾最后一分钟
pre_min1为默认时,只能用当日分钟
反之延续之前的分钟
'''
if len(ticks) == 0:
return NullMinute
if not _ts.initialized:
_ts.initialized = True
if pre_min1 == None: #不接续
_ts.sopen = []
_ts.sclose = []
_ts.shigh = []
_ts.slow = []
_ts.svol = []
_ts.sholding=[]
_ts.iorder = []
_ts.min1 = []
else:
_ts.sopen = pre_min1.sopen
_ts.sclose = pre_min1.sclose
_ts.shigh = pre_min1.shigh
_ts.slow = pre_min1.slow
_ts.svol = pre_min1.svol
_ts.sholding=pre_min1.sholding
_ts.iorder = pre_min1.iorder
_ts.min1 = pre_min1.min1
_ts.cur = BaseObject(vopen = ticks[0].price,
vclose = ticks[0].price,
vhigh=ticks[0].price,
vlow=ticks[0].price,
open_dvol=ticks[0].dvolume,#存在初始误差
close_dvol=ticks[0].dvolume,
holding = ticks[0].holding,
min1=ticks[0].min1, #当日第一min1
iorder=t2order[ticks[0].min1]
) #这里对dvol的处理,使得中断恢复也必须从当日最开始开始,否则所有前述成交量被归结到第一tick
_ts.ilast = 0
_ts.modified = False #上周期完成标志
scur = _ts.cur
for i in range(_ts.ilast,len(ticks)):
tcur = ticks[i]
#if tcur.min1 != scur.min1: #切换
if tcur.min1 > scur.min1: #切换, 避免ticks数据错误引发分钟序列紊乱,如20120905:958:59:500插入在20120905:959:00:00之后,虽然非常罕见,但会导致分钟序列出现958->959->958->959...这个情况
_ts.sopen.append(scur.vopen)
_ts.sclose.append(scur.vclose)
_ts.shigh.append(scur.vhigh)
_ts.slow.append(scur.vlow)
_ts.svol.append(scur.close_dvol - scur.open_dvol)
_ts.sholding.append(scur.holding)
_ts.min1.append(scur.min1)
_ts.iorder.append(scur.iorder)
scur.vopen = scur.vclose = scur.vhigh = scur.vlow = tcur.price
scur.open_dvol = scur.close_dvol
scur.close_dvol = tcur.dvolume
scur.dvol = tcur.dvolume
scur.holding = tcur.holding
scur.min1 = tcur.min1
scur.iorder = t2order[tcur.min1]
_ts.modified = True
else: #未切换
scur.vclose = tcur.price
scur.close_dvol = tcur.dvolume
scur.holding = tcur.holding
#print scur.min1,'close:',scur.vclose
if tcur.price > scur.vhigh:
scur.vhigh = tcur.price
elif tcur.price < scur.vlow:
scur.vlow = tcur.price
_ts.modified = False
_ts.ilast = len(ticks)
return _ts
##以下为确认周期结束的iorder函数
XS3 = lambda x:x%3==0 and x>0 ##914归入下一周期
XS5 = lambda x: x%5==0 and x>0
XS10 = lambda x: x%10== 0 and x>0
XS15 = lambda x:x%15 == 0 and x>0
XS30 = lambda x:x%30 == 0 and x>0
XSDAY = lambda x:x == 270
NullXMinute = BaseObject(sopen=[],sclose=[],shigh=[],slow=[],svol=[],iorder=[],sholding=[])
@indicator
def XMINUTE(m1,sfunc,_ts=None):
'''
1分钟以上周期
sfunc为确认周期结束的点
'''
if len(m1.sclose) == 0:
return NullXMinute
if not _ts.initialized:
_ts.initialized = True
_ts.sopen = []
_ts.sclose = []
_ts.shigh = []
_ts.slow = []
_ts.svol = []
_ts.sholding=[]
_ts.iorder = []
_ts.xmin = [] #开盘分钟
_ts.cur = BaseObject(vopen = 0,
vclose = 0,
vhigh=0,
vlow=99999999,
xmin =0,
svol=0,
holding=0,
iorder=0,
)
_ts.ilast = 0
_ts.modified = False #上周期完成标志
scur = _ts.cur
for i in range(_ts.ilast,len(m1.sclose)):
morder = m1.iorder[i]
if scur.vopen == 0:
scur.vopen = m1.sopen[i]
scur.xmin = m1.min1[i]
scur.vclose = m1.sclose[i]
scur.svol += m1.svol[i]
scur.holding = m1.sholding[i]
if m1.shigh[i] > scur.vhigh:
scur.vhigh = m1.shigh[i]
if m1.slow[i] < scur.vlow:
scur.vlow = m1.slow[i]
_ts.modified = False
if sfunc(morder): #切换
_ts.sopen.append(scur.vopen)
_ts.sclose.append(scur.vclose)
_ts.shigh.append(scur.vhigh)
_ts.slow.append(scur.vlow)
_ts.svol.append(scur.svol)
_ts.sholding.append(scur.holding)
_ts.iorder.append(scur.iorder)
_ts.xmin.append(scur.xmin)
scur.vopen = 0
scur.vclose = 0
scur.vhigh = 0
scur.vlow = 99999999
scur.svol = 0
scur.xmin = 0
scur.holding = 0
scur.iorder += 1
_ts.modified = True
_ts.ilast = len(m1.sclose)
return _ts
MINUTE3 = fcustom(XMINUTE,sfunc=XS3)
MINUTE5 = fcustom(XMINUTE,sfunc=XS5)
MINUTE10 = fcustom(XMINUTE,sfunc=XS10)
MINUTE15 = fcustom(XMINUTE,sfunc=XS15)
MINUTE30 = fcustom(XMINUTE,sfunc=XS30)
MINUTED = fcustom(XMINUTE,sfunc=XSDAY)