2025-08-14 23:41:29 +00:00
|
|
|
|
package strategy
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"container/list"
|
|
|
|
|
"github.com/shopspring/decimal"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/************** 基礎的固定長度隊列,用來計算移動平均 **************/
|
2025-08-15 01:36:36 +00:00
|
|
|
|
// 請注意: 目前為非併發版本,使用場警還不需要
|
|
|
|
|
|
2025-08-14 23:41:29 +00:00
|
|
|
|
type ringQD struct {
|
2025-08-15 01:36:36 +00:00
|
|
|
|
N uint // 窗口大小(需要保留的資料數量)需要保留的數量沒有負數
|
2025-08-14 23:41:29 +00:00
|
|
|
|
l *list.List // 用於儲存資料的雙向鏈表
|
|
|
|
|
sum decimal.Decimal // 當前窗口的總和,方便快速計算平均值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 建立一個固定長度的隊列
|
2025-08-15 01:36:36 +00:00
|
|
|
|
func newRingQD(n uint) *ringQD {
|
2025-08-14 23:41:29 +00:00
|
|
|
|
return &ringQD{N: n, l: list.New(), sum: decimal.Zero}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// push:將新的數值放入隊列,並維護總和
|
|
|
|
|
func (q *ringQD) push(x decimal.Decimal) {
|
|
|
|
|
q.l.PushBack(x)
|
|
|
|
|
q.sum = q.sum.Add(x)
|
|
|
|
|
// 如果超出最大長度,移除最舊的數值
|
2025-08-15 01:36:36 +00:00
|
|
|
|
|
|
|
|
|
if uint(q.l.Len()) > q.N {
|
2025-08-14 23:41:29 +00:00
|
|
|
|
f := q.l.Front()
|
|
|
|
|
q.sum = q.sum.Sub(f.Value.(decimal.Decimal))
|
|
|
|
|
q.l.Remove(f)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ready:判斷隊列是否已經填滿
|
2025-08-15 01:36:36 +00:00
|
|
|
|
func (q *ringQD) ready() bool { return q.N > 0 && uint(q.l.Len()) == q.N }
|
2025-08-14 23:41:29 +00:00
|
|
|
|
|
|
|
|
|
// mean:計算平均值
|
|
|
|
|
func (q *ringQD) mean() decimal.Decimal {
|
|
|
|
|
if q.l.Len() == 0 {
|
|
|
|
|
return decimal.Zero
|
|
|
|
|
}
|
2025-08-15 01:36:36 +00:00
|
|
|
|
|
2025-08-14 23:41:29 +00:00
|
|
|
|
return q.sum.Div(decimal.NewFromInt(int64(q.l.Len())))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// values:返回隊列中所有的值(複製一份,不影響原資料)
|
|
|
|
|
func (q *ringQD) values() []decimal.Decimal {
|
|
|
|
|
out := make([]decimal.Decimal, 0, q.l.Len())
|
|
|
|
|
for e := q.l.Front(); e != nil; e = e.Next() {
|
|
|
|
|
out = append(out, e.Value.(decimal.Decimal))
|
|
|
|
|
}
|
2025-08-15 01:36:36 +00:00
|
|
|
|
|
2025-08-14 23:41:29 +00:00
|
|
|
|
return out
|
|
|
|
|
}
|