From e8aced78d443f2582b1d5541e4ce15e984a5d697 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 10 Feb 2023 11:10:52 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=AE=8C=E5=96=84sum=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/sum.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/stat/sum.go b/stat/sum.go index 851ddfb..0381832 100644 --- a/stat/sum.go +++ b/stat/sum.go @@ -19,13 +19,16 @@ func Sum[T StatType](f []T) T { case []float64: d = vek.Sum(fs) default: - // 剩下的就是int32和int64, 循环吧 - m := T(0) - for _, v := range f { - m += v - } - d = m + d = __sum(fs.([]T)) } return d.(T) } + +func __sum[T StatType](x []T) T { + sum := T(0) + for i := 0; i < len(x); i++ { + sum += x[i] + } + return sum +} -- Gitee From cc285398efecd0ed37a3bcf51b99fbdcdc7fe39d Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 10 Feb 2023 11:11:49 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0sub=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/sub.go | 39 +++++++++++++++++++++++++++++++++++++++ stat/sub_test.go | 18 ++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 stat/sub.go create mode 100644 stat/sub_test.go diff --git a/stat/sub.go b/stat/sub.go new file mode 100644 index 0000000..6a325cb --- /dev/null +++ b/stat/sub.go @@ -0,0 +1,39 @@ +package stat + +import ( + "github.com/viterin/vek" + "github.com/viterin/vek/vek32" + "golang.org/x/exp/slices" +) + +// Sub 减法 +func Sub[T StatType](x []T, y any) []T { + var d any + xLen := len(x) + var s any = x + switch vs := s.(type) { + case []float32: + f32s := AnyToSlice[float32](y, xLen) + d = vek32.Sub(vs, f32s) + case []float64: + f64s := AnyToSlice[float64](y, xLen) + d = vek.Sub(vs, f64s) + //case []int32: + // i32s := AnyToSlice[int32](y, xLen) + // d = __sub(vs, i32s) + default: + ts := AnyToSlice[T](y, xLen) + d = __sub(x, ts) + //default: + // panic(ErrUnsupportedType) + } + return d.([]T) +} + +func __sub[T StatType](x, y []T) []T { + x = slices.Clone(x) + for i := 0; i < len(x); i++ { + x[i] -= y[i] + } + return x +} diff --git a/stat/sub_test.go b/stat/sub_test.go new file mode 100644 index 0000000..6c20172 --- /dev/null +++ b/stat/sub_test.go @@ -0,0 +1,18 @@ +package stat + +import ( + "fmt" + "testing" +) + +func TestSub(t *testing.T) { + f1 := []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + f2 := []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + d2 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + d3 := []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + d4 := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + fmt.Println(Sub(f1, f2)) + fmt.Println(Sub(d2, float64(1))) + fmt.Println(Sub(d3, int32(2))) + fmt.Println(Sub(d4, int64(3))) +} -- Gitee From ff2809b3aaa2a4bd1902857d3795d2c0245c73d9 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 10 Feb 2023 11:12:36 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=88=96=E8=80=85=E5=88=87=E7=89=87=E8=BD=AC?= =?UTF-8?q?=E6=88=90=E7=A1=AE=E5=AE=9A=E7=9A=84=E5=88=87=E7=89=87=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/params.go | 14 ++++++++++++++ stat/params_test.go | 13 +++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 stat/params_test.go diff --git a/stat/params.go b/stat/params.go index 826450b..c815844 100644 --- a/stat/params.go +++ b/stat/params.go @@ -11,3 +11,17 @@ func detectParam[T StatType](v any) (T, []T, error) { } return base, slice, nil } + +// AnyToSlice any转切片 +func AnyToSlice[T StatType](A any, n int) []T { + switch v := A.(type) { + case /*nil, */ int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, float32, float64 /*, bool, string*/ : + //x := S.EWM(pandas.EW{Alpha: 1 / stat.Any2DType(N), Adjust: false}).Mean().DTypes() + //return x + return Repeat[T](v.(T), n) + case []T: + return Align(v, T(0), n) + default: + panic(ErrUnsupportedType) + } +} diff --git a/stat/params_test.go b/stat/params_test.go new file mode 100644 index 0000000..9ec9bd9 --- /dev/null +++ b/stat/params_test.go @@ -0,0 +1,13 @@ +package stat + +import ( + "fmt" + "testing" +) + +func TestAnyToSlice(t *testing.T) { + d1 := []float64{1, 2, 3, 4} + fmt.Println(AnyToSlice[float64](float64(1), 5)) + fmt.Println(AnyToSlice[float64](d1, 3)) + fmt.Println(AnyToSlice[int32](d1, 5)) +} -- Gitee From cfa5baa221972e42012c56d48b618519728c5a44 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 10 Feb 2023 11:17:40 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/sub.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stat/sub.go b/stat/sub.go index 6a325cb..75a7cba 100644 --- a/stat/sub.go +++ b/stat/sub.go @@ -18,14 +18,9 @@ func Sub[T StatType](x []T, y any) []T { case []float64: f64s := AnyToSlice[float64](y, xLen) d = vek.Sub(vs, f64s) - //case []int32: - // i32s := AnyToSlice[int32](y, xLen) - // d = __sub(vs, i32s) default: ts := AnyToSlice[T](y, xLen) d = __sub(x, ts) - //default: - // panic(ErrUnsupportedType) } return d.([]T) } -- Gitee From 23910a36d590397d594635475f70541a2a14d1f5 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 10 Feb 2023 11:18:11 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E6=96=B0=E5=A2=9Emean=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/mean.go | 25 +++++++++++++++++++++++++ stat/mean_test.go | 17 +++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 stat/mean.go create mode 100644 stat/mean_test.go diff --git a/stat/mean.go b/stat/mean.go new file mode 100644 index 0000000..ca01bad --- /dev/null +++ b/stat/mean.go @@ -0,0 +1,25 @@ +package stat + +import ( + "github.com/viterin/vek" + "github.com/viterin/vek/vek32" +) + +// Mean 求均值 +func Mean[T StatType](x []T) T { + var d any + var s any = x + switch vs := s.(type) { + case []float32: + d = vek32.Mean(vs) + case []float64: + d = vek.Mean(vs) + default: + d = __mean(x) + } + return d.(T) +} + +func __mean[T StatType](x []T) T { + return __sum(x) / T(len(x)) +} diff --git a/stat/mean_test.go b/stat/mean_test.go new file mode 100644 index 0000000..ded6183 --- /dev/null +++ b/stat/mean_test.go @@ -0,0 +1,17 @@ +package stat + +import ( + "fmt" + "testing" +) + +func TestMean(t *testing.T) { + d1 := []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + d2 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + d3 := []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + d4 := []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + fmt.Println(Mean(d1)) + fmt.Println(Mean(d2)) + fmt.Println(Mean(d3)) + fmt.Println(Mean(d4)) +} -- Gitee From d7a67d0c51e89280b6e78bb9e655d332a085d0d6 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 10 Feb 2023 11:19:02 +0800 Subject: [PATCH 6/6] =?UTF-8?q?#I6CYOX=20=E5=AE=9E=E7=8E=B0AVEDEV=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- formula/README.md | 2 +- formula/avedev.go | 19 +++++++++++++++++++ formula/avedev_test.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 formula/avedev.go create mode 100644 formula/avedev_test.go diff --git a/formula/README.md b/formula/README.md index d3ba96b..b1e72bb 100644 --- a/formula/README.md +++ b/formula/README.md @@ -27,7 +27,7 @@ formula | 0 | STD | 计算N周期内的标准差 | STD(CLOSE,20) | [√] | [√] | | 0 | SUM | 求总和, 如果N=0则从第一个有效值开始 | SUM(CLOSE,5) | [√] | [√] | | 0 | CONST | 返回序列S最后的值组成常量序列 | CONST(CLOSE) | [√] | [ ] | -| 0 | AVEDEV | 平均绝对差,序列与其平均值的绝对差的平均值 | AVEDEV(CLOSE,5) | [X] | [X] | +| 0 | AVEDEV | 平均绝对差,序列与其平均值的绝对差的平均值 | AVEDEV(CLOSE,5) | [√] | [√] | | 0 | SLOPE | S序列N周期回线性回归斜率 | SLOPE(CLOSE,5) | [√] | [√] | | 0 | FORCAST | S序列N周期回线性回归后的预测值 | FORCAST(CLOSE,5) | [X] | [X] | | 0 | LAST | 从前A日到前B日一直满足S条件,要求A>B & A>0 & B>=0 | LAST(CLOSE>REF(CLOSE,1),LOW,HIGH) | [√] | [√] | diff --git a/formula/avedev.go b/formula/avedev.go new file mode 100644 index 0000000..f0f1bf0 --- /dev/null +++ b/formula/avedev.go @@ -0,0 +1,19 @@ +package formula + +import ( + "gitee.com/quant1x/pandas" + "gitee.com/quant1x/pandas/stat" +) + +// AVEDEV 平均绝对偏差, (序列与其平均值的绝对差的平均值) +// +// AVEDEV(S,N) 返回平均绝对偏差 +func AVEDEV(S pandas.Series, N any) any { + return S.Rolling(N).Apply(func(X pandas.Series, W stat.DType) stat.DType { + x := X.DTypes() + x1 := X.Mean() + r := stat.Sub(x, x1) + r = stat.Abs(r) + return stat.Mean(r) + }).Values() +} diff --git a/formula/avedev_test.go b/formula/avedev_test.go new file mode 100644 index 0000000..4959cad --- /dev/null +++ b/formula/avedev_test.go @@ -0,0 +1,30 @@ +package formula + +import ( + "fmt" + "gitee.com/quant1x/pandas" + "testing" +) + +func TestAVEDEV(t *testing.T) { + x := []float64{0.0, 0.1, 0.2, 0.3, 0.5, 0.8, 1.0} + y := []float64{1.0, 0.41, 0.50, 0.61, 0.91, 2.02, 2.46} + X := pandas.NewSeriesWithoutType("x", x) + Y := pandas.NewSeriesWithoutType("y", y) + fmt.Println(AVEDEV(Y, 5)) + + csv := "~/.quant1x/data/cn/002528.csv" + df := pandas.ReadCSV(csv) + df.SetNames("data", "open", "close", "high", "low", "volume", "amount", "zf", "zdf", "zde", "hsl") + fmt.Println(df) + fmt.Println(df.Names()) + df.SetName("收盘", "close") + CLOSE := df.Col("close") + + c1 := AVEDEV(CLOSE, 5) + C := pandas.NewSeriesWithoutType("c1", c1) + df = pandas.NewDataFrame(C) + fmt.Println(df) + + _ = X +} -- Gitee