Skip to content

Commit 351fbaf

Browse files
committed
support Clone on BarEnv/Series
1 parent 7a71254 commit 351fbaf

File tree

3 files changed

+156
-2
lines changed

3 files changed

+156
-2
lines changed

core.go

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,61 @@ func (e *BarEnv) NewSeries(data []float64) *Series {
7171
subs := make(map[string]map[int]*Series)
7272
xlogs := make(map[int]*CrossLog)
7373
lock := &sync.Mutex{}
74-
res := &Series{e.VNum, e, data, nil, e.TimeStart, nil, subs, xlogs, lock}
74+
res := &Series{e.VNum, e, data, nil, e.TimeStart, nil, nil, subs, xlogs, lock}
7575
e.VNum += 1
76+
if e.Items == nil {
77+
e.Items = make(map[int]*Series)
78+
}
79+
e.Items[res.ID] = res
7680
return res
7781
}
7882

7983
func (e *BarEnv) BarCount(start int64) float64 {
8084
return float64(e.TimeStop-start) / float64(e.TFMSecs)
8185
}
8286

87+
func (e *BarEnv) Clone() *BarEnv {
88+
res := &BarEnv{
89+
TimeStart: e.TimeStart,
90+
TimeStop: e.TimeStop,
91+
Exchange: e.Exchange,
92+
MarketType: e.MarketType,
93+
Symbol: e.Symbol,
94+
TimeFrame: e.TimeFrame,
95+
TFMSecs: e.TFMSecs,
96+
BarNum: e.BarNum,
97+
MaxCache: e.MaxCache,
98+
VNum: e.VNum,
99+
Items: make(map[int]*Series),
100+
Data: make(map[string]interface{}),
101+
}
102+
for k, v := range e.Data {
103+
res.Data[k] = v
104+
}
105+
if e.Open != nil {
106+
res.Open = e.Open.CopyTo(res)
107+
}
108+
if e.High != nil {
109+
res.High = e.High.CopyTo(res)
110+
}
111+
if e.Low != nil {
112+
res.Low = e.Low.CopyTo(res)
113+
}
114+
if e.Close != nil {
115+
res.Close = e.Close.CopyTo(res)
116+
}
117+
if e.Volume != nil {
118+
res.Volume = e.Volume.CopyTo(res)
119+
}
120+
if e.Info != nil {
121+
res.Info = e.Info.CopyTo(res)
122+
}
123+
for _, v := range e.Items {
124+
v.CopyTo(res)
125+
}
126+
return res
127+
}
128+
83129
func (s *Series) Set(obj interface{}) *Series {
84130
if !s.Cached() {
85131
return s.Append(obj)
@@ -329,6 +375,42 @@ func (s *Series) To(k string, v int) *Series {
329375
return old
330376
}
331377

378+
func (s *Series) CopyTo(e *BarEnv) *Series {
379+
if e == nil {
380+
e = s.Env
381+
}
382+
if e.Items == nil {
383+
e.Items = make(map[int]*Series)
384+
}
385+
if old, ok := e.Items[s.ID]; ok {
386+
return old
387+
}
388+
cols := make([]*Series, len(s.Cols))
389+
for i, v := range s.Cols {
390+
cols[i] = v.CopyTo(e)
391+
}
392+
subs := make(map[string]map[int]*Series)
393+
for fn, idMap := range s.Subs {
394+
sub := make(map[int]*Series)
395+
for id, v := range idMap {
396+
sub[id] = v.CopyTo(e)
397+
}
398+
subs[fn] = sub
399+
}
400+
xlogs := make(map[int]*CrossLog)
401+
for id, v := range s.XLogs {
402+
xlogs[id] = v.Clone()
403+
}
404+
lock := &sync.Mutex{}
405+
res := &Series{s.ID, e, s.Data, cols, s.Time, nil, s.DupMore, subs, xlogs, lock}
406+
res.More = s.More
407+
if s.DupMore != nil && s.More != nil {
408+
res.More = s.DupMore(s.More)
409+
}
410+
e.Items[s.ID] = res
411+
return res
412+
}
413+
332414
/*
333415
Cross 计算最近一次交叉的距离。比较对象必须是常数或Series对象
334416
返回值:正数上穿,负数下穿,0表示未知或重合;abs(ret) - 1表示交叉点与当前bar的距离
@@ -390,3 +472,22 @@ func (s *Series) Cross(obj2 interface{}) int {
390472
func Cross(obj1 *Series, obj2 interface{}) int {
391473
return obj1.Cross(obj2)
392474
}
475+
476+
func (c *CrossLog) Clone() *CrossLog {
477+
res := &CrossLog{
478+
Time: c.Time,
479+
PrevVal: c.PrevVal,
480+
Hist: make([]*XState, len(c.Hist)),
481+
}
482+
for i, v := range c.Hist {
483+
res.Hist[i] = v.Clone()
484+
}
485+
return res
486+
}
487+
488+
func (s *XState) Clone() *XState {
489+
return &XState{
490+
Sign: s.Sign,
491+
BarNum: s.BarNum,
492+
}
493+
}

sta_inds.go

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func Sum(obj *Series, period int) *Series {
5050
if sta == nil {
5151
sta = &sumState{}
5252
res.More = sta
53+
res.DupMore = func(more interface{}) interface{} {
54+
sta := more.(*sumState)
55+
return &sumState{sta.sumVal, append([]float64{}, sta.arr...)}
56+
}
5357
}
5458
curVal := obj.Get(0)
5559
if !math.IsNaN(curVal) {
@@ -104,6 +108,10 @@ func VWMA(price *Series, vol *Series, period int) *Series {
104108
if more == nil {
105109
more = &moreVWMA{}
106110
res.More = more
111+
res.DupMore = func(mAny interface{}) interface{} {
112+
m := mAny.(*moreVWMA)
113+
return &moreVWMA{m.sumCost, m.sumWei, append([]float64{}, m.costs...), append([]float64{}, m.volumes...)}
114+
}
107115
}
108116
if math.IsNaN(cost) {
109117
return res.Append(math.NaN())
@@ -254,6 +262,10 @@ func WMA(obj *Series, period int) *Series {
254262
if more == nil {
255263
more = &wmaSta{}
256264
res.More = more
265+
res.DupMore = func(mAny interface{}) interface{} {
266+
m := mAny.(*wmaSta)
267+
return &wmaSta{append([]float64{}, m.arr...), m.allSum, m.weiSum}
268+
}
257269
}
258270
more.arr = append(more.arr, val)
259271
if len(more.arr) > period {
@@ -362,6 +374,9 @@ func rsiBy(obj *Series, period int, subVal float64) *Series {
362374
// 状态: [0:prevVal, 1:avgGain, 2:avgLoss, 3:validCount]
363375
more = []float64{math.NaN(), 0, 0, 0}
364376
res.More = more
377+
res.DupMore = func(more interface{}) interface{} {
378+
return append([]float64{}, more.([]float64)...)
379+
}
365380
}
366381

367382
prevVal := more[0]
@@ -742,6 +757,9 @@ func WrapFloatArr(res *Series, period int, inVal float64) []float64 {
742757
var more []float64
743758
if res.More == nil {
744759
more = make([]float64, 0, period)
760+
res.DupMore = func(more interface{}) interface{} {
761+
return append([]float64{}, more.([]float64)...)
762+
}
745763
} else {
746764
more = res.More.([]float64)
747765
}
@@ -946,6 +964,10 @@ func pluMinDMBy(high *Series, low *Series, close *Series, period, method int) (*
946964
if state == nil {
947965
state = &dmState{}
948966
res.More = state
967+
res.DupMore = func(more interface{}) interface{} {
968+
m := more.(*dmState)
969+
return &dmState{m.Num, m.DmPosMA, m.DmNegMA, m.TRMA}
970+
}
949971
}
950972
if math.IsNaN(tr) {
951973
res.Append([]float64{math.NaN(), math.NaN()})
@@ -987,7 +1009,12 @@ func ROC(obj *Series, period int) *Series {
9871009
if res.Cached() {
9881010
return res
9891011
}
990-
prevs, _ := res.More.([]float64)
1012+
prevs, ok := res.More.([]float64)
1013+
if !ok {
1014+
res.DupMore = func(more interface{}) interface{} {
1015+
return append([]float64{}, more.([]float64)...)
1016+
}
1017+
}
9911018
curVal := obj.Get(0)
9921019
if math.IsNaN(curVal) {
9931020
return res.Append(math.NaN())
@@ -1063,6 +1090,10 @@ func ER(obj *Series, period int) *Series {
10631090
prevIn: math.NaN(),
10641091
}
10651092
res.More = sta
1093+
res.DupMore = func(more interface{}) interface{} {
1094+
m := more.(*tnrState)
1095+
return &tnrState{append([]float64{}, m.arr...), m.sumVal, m.prevIn, append([]float64{}, m.arrIn...)}
1096+
}
10661097
}
10671098
inVal := obj.Get(0)
10681099
curVal := math.Abs(inVal - sta.prevIn)
@@ -1187,6 +1218,10 @@ func CMF(env *BarEnv, period int) *Series {
11871218
if sta == nil {
11881219
sta = &cmfState{}
11891220
res.More = sta
1221+
res.DupMore = func(more interface{}) interface{} {
1222+
m := more.(*cmfState)
1223+
return &cmfState{append([]float64{}, m.mfSum...), append([]float64{}, m.volSum...), m.sumMfVal, m.sumVol}
1224+
}
11901225
}
11911226

11921227
var resVal = math.NaN()
@@ -1358,6 +1393,10 @@ func MFI(e *BarEnv, period int) *Series {
13581393
if sta == nil {
13591394
sta = &mfiState{sumNeg: math.NaN(), sumPos: math.NaN(), prev: math.NaN()}
13601395
res.More = sta
1396+
res.DupMore = func(more interface{}) interface{} {
1397+
m := more.(*mfiState)
1398+
return &mfiState{append([]float64{}, m.posArr...), append([]float64{}, m.negArr...), m.sumPos, m.sumNeg, m.prev}
1399+
}
13611400
}
13621401
avgPrice := AvgPrice(e)
13631402
price0 := avgPrice.Get(0)
@@ -1569,6 +1608,10 @@ func CMOBy(obj *Series, period int, maType int) *Series {
15691608
prevIn: math.NaN(),
15701609
}
15711610
res.More = sta
1611+
res.DupMore = func(more interface{}) interface{} {
1612+
m := more.(*cmdSta)
1613+
return &cmdSta{append([]float64{}, m.subs...), m.sumPos, m.sumNeg, m.prevIn}
1614+
}
15721615
}
15731616
inVal := obj.Get(0)
15741617
val := inVal - sta.prevIn
@@ -1736,6 +1779,10 @@ func DV2(h, l, c *Series, period, maLen int) *Series {
17361779
if sta == nil {
17371780
sta = &dv2Sta{}
17381781
res.More = sta
1782+
res.DupMore = func(more interface{}) interface{} {
1783+
m := more.(*dv2Sta)
1784+
return &dv2Sta{append([]float64{}, m.chl...), append([]float64{}, m.dv...)}
1785+
}
17391786
}
17401787
h0, l0, c0 := h.Get(0), l.Get(0), c.Get(0)
17411788
// 如果当前输入值为 NaN,返回 NaN然后跳过,不重置状态
@@ -1889,6 +1936,10 @@ func STC(obj *Series, period, fast, slow int, alpha float64) *Series {
18891936
prevSTC: math.NaN(),
18901937
}
18911938
res.More = s
1939+
res.DupMore = func(more interface{}) interface{} {
1940+
m := more.(*stcSta)
1941+
return &stcSta{append([]float64{}, m.macdHis...), append([]float64{}, m.dddHis...), m.prevDDD, m.prevSTC}
1942+
}
18921943
}
18931944
// 1. 计算MACD差值
18941945
fastEMA := EMA(obj, fast).Get(0)

types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type BarEnv struct {
3737
Volume *Series
3838
Info *Series
3939
Data map[string]interface{}
40+
Items map[int]*Series
4041
}
4142

4243
type Series struct {
@@ -46,6 +47,7 @@ type Series struct {
4647
Cols []*Series
4748
Time int64
4849
More interface{}
50+
DupMore func(interface{}) interface{}
4951
Subs map[string]map[int]*Series // 由此序列派生的;function:hash:object
5052
XLogs map[int]*CrossLog // 此序列交叉记录
5153
subLock *sync.Mutex

0 commit comments

Comments
 (0)