From 52dba5ad8a24be5dc5e40a574d0956d51ac883c0 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 05:50:42 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0int32=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/ndarray_type.go | 1 + 1 file changed, 1 insertion(+) diff --git a/stat/ndarray_type.go b/stat/ndarray_type.go index bdf97db..436ea7a 100644 --- a/stat/ndarray_type.go +++ b/stat/ndarray_type.go @@ -13,6 +13,7 @@ type Type = reflect.Kind const ( SERIES_TYPE_INVAILD = reflect.Invalid // 无效类型 SERIES_TYPE_BOOL = reflect.Bool // 布尔类型 + SERIES_TYPE_INT32 = reflect.Int32 // int64 SERIES_TYPE_INT64 = reflect.Int64 // int64 SERIES_TYPE_FLOAT32 = reflect.Float32 // float32 SERIES_TYPE_FLOAT64 = reflect.Float64 // float64 -- Gitee From 11478c97b9162976058a4b44faa39318f7dcf094 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 05:57:26 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/series.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stat/series.go b/stat/series.go index 990d0b8..4ed3178 100644 --- a/stat/series.go +++ b/stat/series.go @@ -52,6 +52,12 @@ type Series interface { Shift(periods int) Series // Rolling 序列化版本 Rolling(param any) RollingAndExpandingMixin + // EWM Provide exponentially weighted (EW) calculations. + // + // Exactly one of ``com``, ``span``, ``halflife``, or ``alpha`` must be + // provided if ``times`` is not provided. If ``times`` is provided, + // ``halflife`` and one of ``com``, ``span`` or ``alpha`` may be provided. + EWM(alpha EW) ExponentialMovingWindow // Mean calculates the average value of a series Mean() DType // StdDev calculates the standard deviation of a series @@ -82,12 +88,6 @@ type Series interface { Std() DType // Sum 计算累和 Sum() DType - // EWM Provide exponentially weighted (EW) calculations. - // - // Exactly one of ``com``, ``span``, ``halflife``, or ``alpha`` must be - // provided if ``times`` is not provided. If ``times`` is provided, - // ``halflife`` and one of ``com``, ``span`` or ``alpha`` may be provided. - EWM(alpha EW) ExponentialMovingWindow } // DetectTypeBySlice 检测类型 -- Gitee From 67fb37ec3091328b532230174785f280a8739937 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 05:58:18 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/series.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stat/series.go b/stat/series.go index 4ed3178..4b7afe1 100644 --- a/stat/series.go +++ b/stat/series.go @@ -47,6 +47,9 @@ type Series interface { Subset(start, end int, opt ...any) Series // Repeat elements of an array. Repeat(x any, repeats int) Series + // FillNa Fill NA/NaN values using the specified method. + FillNa(v any, inplace bool) Series + // Shift index by desired number of periods with an optional time freq. // 使用可选的时间频率按所需的周期数移动索引. Shift(periods int) Series @@ -62,8 +65,6 @@ type Series interface { Mean() DType // StdDev calculates the standard deviation of a series StdDev() DType - // FillNa Fill NA/NaN values using the specified method. - FillNa(v any, inplace bool) Series // Max 找出最大值 Max() any // ArgMax Returns the indices of the maximum values along an axis -- Gitee From a49b1dc6d96b6c7d11822391833c9f3a6caa07f0 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 05:59:28 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/series.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stat/series.go b/stat/series.go index 4b7afe1..49ed233 100644 --- a/stat/series.go +++ b/stat/series.go @@ -15,12 +15,12 @@ type Series interface { Type() Type // Values 获得全部数据集 Values() any + // NaN 输出默认的NaN + NaN() any // Reverse 序列反转 Reverse() Series - // NaN 输出默认的NaN - NaN() any // Floats 强制转成[]float32 Floats() []float32 // DTypes 强制转[]stat.DType -- Gitee From 5695e3abd02a7233cb7bea3ac0e2246a08544ec0 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 06:03:40 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/series.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/stat/series.go b/stat/series.go index 49ed233..101b04e 100644 --- a/stat/series.go +++ b/stat/series.go @@ -18,9 +18,6 @@ type Series interface { // NaN 输出默认的NaN NaN() any - // Reverse 序列反转 - Reverse() Series - // Floats 强制转成[]float32 Floats() []float32 // DTypes 强制转[]stat.DType @@ -41,6 +38,13 @@ type Series interface { Empty(t ...Type) Series // Copy 复制 Copy() Series + // Reverse 序列反转 + Reverse() Series + // Select 选取一段记录 + Select(r ScopeLimit) Series + // Append 增加一批记录 + Append(values ...any) Series + // Records returns the elements of a Series as a []string Records() []string // Subset 获取子集 @@ -55,12 +59,17 @@ type Series interface { Shift(periods int) Series // Rolling 序列化版本 Rolling(param any) RollingAndExpandingMixin + // Apply 接受一个回调函数 + Apply(f func(idx int, v any)) + // Logic 逻辑处理 + Logic(f func(idx int, v any) bool) []bool // EWM Provide exponentially weighted (EW) calculations. // // Exactly one of ``com``, ``span``, ``halflife``, or ``alpha`` must be // provided if ``times`` is not provided. If ``times`` is provided, // ``halflife`` and one of ``com``, ``span`` or ``alpha`` may be provided. EWM(alpha EW) ExponentialMovingWindow + // Mean calculates the average value of a series Mean() DType // StdDev calculates the standard deviation of a series @@ -73,14 +82,6 @@ type Series interface { Min() any // ArgMin Returns the indices of the minimum values along an axis ArgMin() int - // Select 选取一段记录 - Select(r ScopeLimit) Series - // Append 增加一批记录 - Append(values ...any) Series - // Apply 接受一个回调函数 - Apply(f func(idx int, v any)) - // Logic 逻辑处理 - Logic(f func(idx int, v any) bool) []bool // Diff 元素的第一个离散差 Diff(param any) (s Series) // Ref 引用其它周期的数据 -- Gitee From a3c4441f569aa3cd93b01280b3dfeca989bc8463 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 06:07:56 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/series.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stat/series.go b/stat/series.go index 101b04e..c9f0dd7 100644 --- a/stat/series.go +++ b/stat/series.go @@ -54,6 +54,8 @@ type Series interface { // FillNa Fill NA/NaN values using the specified method. FillNa(v any, inplace bool) Series + // Ref 引用其它周期的数据 + Ref(param any) (s Series) // Shift index by desired number of periods with an optional time freq. // 使用可选的时间频率按所需的周期数移动索引. Shift(periods int) Series @@ -84,8 +86,6 @@ type Series interface { ArgMin() int // Diff 元素的第一个离散差 Diff(param any) (s Series) - // Ref 引用其它周期的数据 - Ref(param any) (s Series) // Std 计算标准差 Std() DType // Sum 计算累和 -- Gitee From 3b997670cf3ff7221ce0cd7b56b50b10afd13038 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 06:31:53 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/type.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stat/type.go b/stat/type.go index a239602..2d925bd 100644 --- a/stat/type.go +++ b/stat/type.go @@ -203,7 +203,7 @@ func __anyToNumber[T Number](v any) T { case float64: return T(val) case bool: - return T(bool2Int(val)) + return T(BoolToInt(val)) case string: vt := ParseFloat64(val, v) if Float64IsNaN(vt) { -- Gitee From 63f52082e7d01a1abbc57f9ff865e6a4955cf0e9 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:19:43 +0800 Subject: [PATCH 08/16] =?UTF-8?q?series=20=E5=A2=9E=E5=8A=A0=E5=9B=9B?= =?UTF-8?q?=E5=88=99=E8=BF=90=E7=AE=97=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- series.go | 20 ++++++++++ stat/ndarray_fromnumeric.go | 80 +++++++++++++++++++++++++++++++++++++ stat/series.go | 4 ++ 3 files changed, 104 insertions(+) diff --git a/series.go b/series.go index 9e63db5..60c7a3e 100644 --- a/series.go +++ b/series.go @@ -345,3 +345,23 @@ func (self *NDFrame) FillNa(v any, inplace bool) stat.Series { } return self } + +func (self *NDFrame) Add(x any) stat.Series { + //TODO implement me + panic("implement me") +} + +func (self *NDFrame) Sub(x any) stat.Series { + //TODO implement me + panic("implement me") +} + +func (self *NDFrame) Mul(x any) stat.Series { + //TODO implement me + panic("implement me") +} + +func (self *NDFrame) Div(x any) stat.Series { + //TODO implement me + panic("implement me") +} diff --git a/stat/ndarray_fromnumeric.go b/stat/ndarray_fromnumeric.go index ef7c449..6215487 100644 --- a/stat/ndarray_fromnumeric.go +++ b/stat/ndarray_fromnumeric.go @@ -7,3 +7,83 @@ func (self NDArray[T]) ArgMax() int { func (self NDArray[T]) ArgMin() int { return ArgMin2(self) } + +func (self NDArray[T]) Add(x any) Series { + length := self.Len() + var b []DType + switch sx := x.(type) { + case Series: + b = sx.DTypes() + case int: + b = Repeat[DType](DType(sx), length) + case DType: + b = Repeat[DType](sx, length) + //case int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, uintptr, float32, float64: + // b = Repeat[DType](DType(sx), length) + default: + panic(Throw(x)) + } + a := self.DTypes() + s := Add(a, b) + return NDArray[DType](s) +} + +func (self NDArray[T]) Sub(x any) Series { + length := self.Len() + var b []DType + switch sx := x.(type) { + case Series: + b = sx.DTypes() + case int: + b = Repeat[DType](DType(sx), length) + case DType: + b = Repeat[DType](sx, length) + //case int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, uintptr, float32, float64: + // b = Repeat[DType](DType(sx), length) + default: + panic(Throw(x)) + } + a := self.DTypes() + s := Sub(a, b) + return NDArray[DType](s) +} + +func (self NDArray[T]) Mul(x any) Series { + length := self.Len() + var b []DType + switch sx := x.(type) { + case Series: + b = sx.DTypes() + case int: + b = Repeat[DType](DType(sx), length) + case DType: + b = Repeat[DType](sx, length) + //case int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, uintptr, float32, float64: + // b = Repeat[DType](DType(sx), length) + default: + panic(Throw(x)) + } + a := self.DTypes() + s := Mul(a, b) + return NDArray[DType](s) +} + +func (self NDArray[T]) Div(x any) Series { + length := self.Len() + var b []DType + switch sx := x.(type) { + case Series: + b = sx.DTypes() + case int: + b = Repeat[DType](DType(sx), length) + case DType: + b = Repeat[DType](sx, length) + //case int8, uint8, int16, uint16, int32, uint32, int64, uint64, int, uint, uintptr, float32, float64: + // b = Repeat[DType](DType(sx), length) + default: + panic(Throw(x)) + } + a := self.DTypes() + s := Div(a, b) + return NDArray[DType](s) +} diff --git a/stat/series.go b/stat/series.go index c9f0dd7..3bc6a9a 100644 --- a/stat/series.go +++ b/stat/series.go @@ -90,6 +90,10 @@ type Series interface { Std() DType // Sum 计算累和 Sum() DType + Add(x any) Series + Sub(x any) Series + Mul(x any) Series + Div(x any) Series } // DetectTypeBySlice 检测类型 -- Gitee From 858477a90fae13d830ad30acec9e5a66724459ca Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:20:28 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E7=9A=84=E6=BA=90=E6=96=87=E4=BB=B6=E5=88=86?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ndarray_convert.go => series_convert.go} | 97 +++++++++++-------- ...convert_test.go => series_convert_test.go} | 0 2 files changed, 59 insertions(+), 38 deletions(-) rename stat/{ndarray_convert.go => series_convert.go} (44%) rename stat/{ndarray_convert_test.go => series_convert_test.go} (100%) diff --git a/stat/ndarray_convert.go b/stat/series_convert.go similarity index 44% rename from stat/ndarray_convert.go rename to stat/series_convert.go index a11827f..7e2f9f0 100644 --- a/stat/ndarray_convert.go +++ b/stat/series_convert.go @@ -3,7 +3,6 @@ package stat import ( "github.com/viterin/vek" "github.com/viterin/vek/vek32" - "reflect" ) // 这里做数组统一转换 @@ -15,69 +14,73 @@ func convert[T GenericType](s Series, v T) { _ = ok } +// ToFloat32 转换Float32 func ToFloat32(s Series) []float32 { - length := s.Len() - defaultSlice := vek32.Repeat(Nil2Float32, length) values := s.Values() __type := s.Type() - if __type == SERIES_TYPE_INVAILD { - return defaultSlice - } else if __type == SERIES_TYPE_BOOL { - return vek32.FromBool(values.([]bool)) - } else if __type == SERIES_TYPE_INT64 { - return vek32.FromInt64(values.([]int64)) - } else if __type == SERIES_TYPE_FLOAT32 { - return values.([]float32) - } else if __type == SERIES_TYPE_FLOAT64 { + switch __type { + case SERIES_TYPE_FLOAT32: + return values.([]float32) // TODO:是否复制 + case SERIES_TYPE_FLOAT64: return vek32.FromFloat64(values.([]float64)) - } else if __type == reflect.Int32 { + case SERIES_TYPE_INT32: return vek32.FromInt32(values.([]int32)) - } else { + case SERIES_TYPE_INT64: + return vek32.FromInt64(values.([]int64)) + case SERIES_TYPE_BOOL: + return vek32.FromBool(values.([]bool)) + default: + length := s.Len() + defaultSlice := vek32.Repeat(Nil2Float32, length) return defaultSlice } } func ToFloat64(s Series) []float64 { - length := s.Len() - defaultSlice := vek.Repeat(Nil2Float64, length) values := s.Values() __type := s.Type() - if __type == SERIES_TYPE_INVAILD { - return defaultSlice - } else if __type == SERIES_TYPE_BOOL { - return vek.FromBool(values.([]bool)) - } else if __type == SERIES_TYPE_INT64 { - return vek.FromInt64(values.([]int64)) - } else if __type == SERIES_TYPE_FLOAT32 { + switch __type { + case SERIES_TYPE_FLOAT32: return vek.FromFloat32(values.([]float32)) - } else if __type == SERIES_TYPE_FLOAT64 { - return values.([]float64) // 是否复制 - } else if __type == reflect.Int32 { + case SERIES_TYPE_FLOAT64: + return values.([]float64) // TODO:是否复制 + case SERIES_TYPE_INT32: return vek.FromInt32(values.([]int32)) - } else { + case SERIES_TYPE_INT64: + return vek.FromInt64(values.([]int64)) + case SERIES_TYPE_BOOL: + return vek.FromBool(values.([]bool)) + default: + length := s.Len() + defaultSlice := vek.Repeat(Nil2Float64, length) return defaultSlice } } func ToBool(s Series) []bool { - length := s.Len() - defaultSlice := make([]bool, length) values := s.Values() __type := s.Type() - if __type == SERIES_TYPE_INVAILD { - return defaultSlice - } else if __type == SERIES_TYPE_BOOL { + switch __type { + case SERIES_TYPE_FLOAT32: + return __NumberToBool_S(values.([]float32)) + case SERIES_TYPE_FLOAT64: + return __NumberToBool_S(values.([]int64)) + case SERIES_TYPE_INT32: + return __NumberToBool_S(values.([]int32)) + case SERIES_TYPE_INT64: + return __NumberToBool_S(values.([]int64)) + case SERIES_TYPE_BOOL: return values.([]bool) - } else if __type == SERIES_TYPE_INT64 { - return __toBool(values.([]int64)) - } else if __type == SERIES_TYPE_FLOAT32 { - return __toBool(values.([]float32)) - } else { + case SERIES_TYPE_STRING: + return __StringToBool_S(values.([]string)) + default: + length := s.Len() + defaultSlice := make([]bool, length) return defaultSlice } } -func __toBool[T Number](values []T) []bool { +func __NumberToBool_S[T Number](values []T) []bool { length := len(values) vs := make([]bool, length) for i, v := range values { @@ -89,3 +92,21 @@ func __toBool[T Number](values []T) []bool { } return vs } + +func __StringToBool_S(values []string) []bool { + length := len(values) + vs := make([]bool, length) + for i, v := range values { + if StringIsTrue(v) { + vs[i] = true + } else { + vs[i] = false + } + } + return vs +} + +func __NumberToSeries[T Number](x T, n int) Series { + s := Repeat[T](x, n) + return NDArray[T](s) +} diff --git a/stat/ndarray_convert_test.go b/stat/series_convert_test.go similarity index 100% rename from stat/ndarray_convert_test.go rename to stat/series_convert_test.go -- Gitee From 51ee529b2eec5ae3aac2c2ef3cb66dda3b51f804 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:21:13 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=97=A5=E7=BA=BF=E8=A1=8C=E6=83=85=E6=95=B0=E6=8D=AE=E7=9A=84?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/cache/cache_fast.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/data/cache/cache_fast.go b/data/cache/cache_fast.go index a166dfe..b2ae630 100644 --- a/data/cache/cache_fast.go +++ b/data/cache/cache_fast.go @@ -2,6 +2,7 @@ package cache import ( "errors" + "gitee.com/quant1x/pandas" "gitee.com/quant1x/pandas/data/category" "github.com/mymmsc/gox/logger" "os" @@ -101,3 +102,11 @@ func GetCache(fullCode string) *os.File { } return file } + +// KLine 加载K线 +func KLine(code string) pandas.DataFrame { + filename := GetCacheFilename(code) + df := pandas.ReadCSV(filename) + _ = df.SetNames("date", "open", "high", "low", "close", "volume") + return df +} -- Gitee From 0483470ea63d574093311cb5f9f15aa258a909fe Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:21:48 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E6=89=A9=E5=85=85=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/argmax.go | 6 +++--- stat/argmin.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/stat/argmax.go b/stat/argmax.go index 0023926..7aab779 100644 --- a/stat/argmax.go +++ b/stat/argmax.go @@ -67,11 +67,11 @@ func __arg_max_go[T Ordered](x []T) int { } func __arg_max_go_bool(x []bool) int { - max := bool2Int(x[0]) + max := BoolToInt(x[0]) idx := 0 for i, v := range x[1:] { - if bool2Int(v) > max { - max = bool2Int(v) + if BoolToInt(v) > max { + max = BoolToInt(v) idx = 1 + i } } diff --git a/stat/argmin.go b/stat/argmin.go index d77e568..264692b 100644 --- a/stat/argmin.go +++ b/stat/argmin.go @@ -67,11 +67,11 @@ func __arg_min_go[T Ordered](x []T) int { } func __arg_min_go_bool(x []bool) int { - min := bool2Int(x[0]) + min := BoolToInt(x[0]) idx := 0 for i, v := range x[1:] { - if bool2Int(v) < min { - min = bool2Int(v) + if BoolToInt(v) < min { + min = BoolToInt(v) idx = 1 + i } } -- Gitee From 68aa893d561436cbcf4cafab942028cbf7b8dad0 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:22:35 +0800 Subject: [PATCH 12/16] =?UTF-8?q?fixed:=20rolling=E9=87=8C=E9=9D=A2series?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E9=87=8D=E6=96=B0=E8=B5=8B=E5=80=BC=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/rolling_max.go | 12 +----------- stat/rolling_mean.go | 1 - stat/rolling_min.go | 12 +----------- stat/rolling_std.go | 12 +----------- 4 files changed, 3 insertions(+), 34 deletions(-) diff --git a/stat/rolling_max.go b/stat/rolling_max.go index 5636076..e8cc2e4 100644 --- a/stat/rolling_max.go +++ b/stat/rolling_max.go @@ -3,17 +3,7 @@ package stat func (r RollingAndExpandingMixin) Max() (s Series) { s = r.Series.Empty() for _, block := range r.GetBlocks() { - //// 1. 排序处理方式 - //if block.Len() == 0 { - // s.Append(s.NaN()) - // continue - //} - //sort.Sort(block) - //r := RangeFinite(-1) - //_s := block.Select(r) - //s.Append(_s.Values()) - // 2. Series.Max方法 - s.Append(block.Max()) + s = s.Append(block.Max()) } return } diff --git a/stat/rolling_mean.go b/stat/rolling_mean.go index 8b8bd6d..99a6762 100644 --- a/stat/rolling_mean.go +++ b/stat/rolling_mean.go @@ -6,7 +6,6 @@ func (r RollingAndExpandingMixin) Mean() (s Series) { for _, block := range r.GetBlocks() { d = append(d, block.Mean()) } - //s = pandas.NewSeries(SERIES_TYPE_DTYPE, r.series.Name(), d) s = r.Series.Empty(SERIES_TYPE_DTYPE) s.Rename(r.Series.Name()) s = s.Append(d) diff --git a/stat/rolling_min.go b/stat/rolling_min.go index 1881d58..8edd010 100644 --- a/stat/rolling_min.go +++ b/stat/rolling_min.go @@ -3,17 +3,7 @@ package stat func (r RollingAndExpandingMixin) Min() (s Series) { s = r.Series.Empty() for _, block := range r.GetBlocks() { - //// 1. 排序处理方式 - //if block.Len() == 0 { - // s.Append(s.NaN()) - // continue - //} - //sort.Sort(block) - //r := RangeFinite(0, 1) - //_s := block.Select(r) - //s.Append(_s.Values()) - // 2. Series.Max方法 - s.Append(block.Min()) + s = s.Append(block.Min()) } return } diff --git a/stat/rolling_std.go b/stat/rolling_std.go index 7ef3761..1bdd0a1 100644 --- a/stat/rolling_std.go +++ b/stat/rolling_std.go @@ -3,17 +3,7 @@ package stat func (r RollingAndExpandingMixin) Std() Series { s := r.Series.Empty() for _, block := range r.GetBlocks() { - //// 1. 排序处理方式 - //if block.Len() == 0 { - // s.Append(s.NaN()) - // continue - //} - //sort.Sort(block) - //r := RangeFinite(-1) - //_s := block.Select(r) - //s.Append(_s.Values()) - // 2. Series.Max方法 - s.Append(block.Std()) + s = s.Append(block.Std()) } return s } -- Gitee From 9e84f040089235d480dd0ef3b77d47658aca9a1c Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:23:28 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=9A=84=E5=85=AC=E5=BC=80=E5=92=8C=E7=A7=81?= =?UTF-8?q?=E6=9C=89=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stat/type_bool.go | 29 +++++++++++++++-------------- stat/type_float32.go | 6 +++--- stat/type_float64.go | 6 +++--- stat/type_int32.go | 6 +++--- stat/type_int64.go | 6 +++--- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/stat/type_bool.go b/stat/type_bool.go index 7aefcc6..d9f1ed2 100644 --- a/stat/type_bool.go +++ b/stat/type_bool.go @@ -19,7 +19,7 @@ const ( StringFalse2Bool = false // 字符串false转bool ) -func isTrue(s string) bool { +func StringIsTrue(s string) bool { if s == "true" || s == "TRUE" || s == "True" || s == "1" || s == "真" || s == "对" || s == "好" { return true } else { @@ -27,7 +27,7 @@ func isTrue(s string) bool { } } -func isFalse(s string) bool { +func StringIsFalse(s string) bool { if s == "false" || s == "FALSE" || s == "False" || s == "0" || s == "假" || s == "错" || s == "坏" { return true } else { @@ -35,37 +35,37 @@ func isFalse(s string) bool { } } -func bool2Int(b bool) int8 { +func BoolToInt(b bool) int8 { if b { return int8(1) } return int8(0) } -func boolToInt32(b bool) int32 { +func BoolToInt32(b bool) int32 { if b { return True2Int32 } return False2Int32 } -func boolToInt64(b bool) int64 { +func BoolToInt64(b bool) int64 { if b { return True2Int64 } return False2Int64 } -// bool转float32 -func boolToFloat32(b bool) float32 { +// BoolToFloat32 bool转float32 +func BoolToFloat32(b bool) float32 { if b { return True2Float32 } return False2Float32 } -// bool转float64 -func boolToFloat64(b bool) float64 { +// BoolToFloat64 bool转float64 +func BoolToFloat64(b bool) float64 { if b { return True2Float64 } @@ -73,7 +73,8 @@ func boolToFloat64(b bool) float64 { } // ParseBool 字符串转bool -// 任意组合的nan字符串都会被解析成NaN +// +// 任意组合的nan字符串都会被解析成NaN func ParseBool(s string, v any) bool { defer func() { // 解析失败以后输出日志, 以备检查 @@ -138,9 +139,9 @@ func AnyToBool(v any) bool { if IsEmpty(*val) { return Nil2Bool } - if isTrue(*val) { + if StringIsTrue(*val) { return StringTrue2Bool - } else if isFalse(*val) { + } else if StringIsFalse(*val) { return StringFalse2Bool } f := ParseBool(*val, v) @@ -149,9 +150,9 @@ func AnyToBool(v any) bool { if IsEmpty(val) { return Nil2Bool } - if isTrue(val) { + if StringIsTrue(val) { return StringTrue2Bool - } else if isFalse(val) { + } else if StringIsFalse(val) { return StringFalse2Bool } f := ParseBool(val, v) diff --git a/stat/type_float32.go b/stat/type_float32.go index dd70c57..1fb7250 100644 --- a/stat/type_float32.go +++ b/stat/type_float32.go @@ -106,9 +106,9 @@ func ParseFloat32(s string, v any) float32 { // TODO:NaN是针对64位, 这样直接转换应该有问题, 需要进一步确认 return Nil2Float32 } - if isTrue(s) { + if StringIsTrue(s) { return StringTrue2Float32 - } else if isFalse(s) { + } else if StringIsFalse(s) { return StringFalse2Float32 } @@ -128,6 +128,6 @@ func AnyToFloat32(v any) float32 { v = vv } - f := valueToNumber(v, Nil2Float32, boolToFloat32, ParseFloat32) + f := valueToNumber(v, Nil2Float32, BoolToFloat32, ParseFloat32) return f } diff --git a/stat/type_float64.go b/stat/type_float64.go index 0085e15..d583634 100644 --- a/stat/type_float64.go +++ b/stat/type_float64.go @@ -58,9 +58,9 @@ func ParseFloat64(s string, v any) float64 { if IsEmpty(s) { return Nil2Float64 } - if isTrue(s) { + if StringIsTrue(s) { return StringTrue2Float64 - } else if isFalse(s) { + } else if StringIsFalse(s) { return StringFalse2Float64 } f, err := strconv.ParseFloat(s, 64) @@ -79,7 +79,7 @@ func AnyToFloat64(v any) float64 { v = vv } - f := valueToNumber(v, Nil2Float64, boolToFloat64, ParseFloat64) + f := valueToNumber(v, Nil2Float64, BoolToFloat64, ParseFloat64) return f } diff --git a/stat/type_int32.go b/stat/type_int32.go index e829669..5f31856 100644 --- a/stat/type_int32.go +++ b/stat/type_int32.go @@ -30,9 +30,9 @@ func ParseInt32(s string, v any) int32 { if IsEmpty(s) { return Nil2Int32 } - if isTrue(s) { + if StringIsTrue(s) { return StringTrue2Int32 - } else if isFalse(s) { + } else if StringIsFalse(s) { return StringFalse2Int32 } i, err := strconv.ParseInt(s, 10, 32) @@ -66,6 +66,6 @@ func AnyToInt32(v any) int32 { v = vv } - f := valueToNumber[int32](v, Nil2Int32, boolToInt32, ParseInt32) + f := valueToNumber[int32](v, Nil2Int32, BoolToInt32, ParseInt32) return f } diff --git a/stat/type_int64.go b/stat/type_int64.go index f23cfed..c63863c 100644 --- a/stat/type_int64.go +++ b/stat/type_int64.go @@ -30,9 +30,9 @@ func ParseInt64(s string, v any) int64 { if IsEmpty(s) { return Nil2Int64 } - if isTrue(s) { + if StringIsTrue(s) { return StringTrue2Int64 - } else if isFalse(s) { + } else if StringIsFalse(s) { return StringFalse2Int64 } i, err := strconv.ParseInt(s, 10, 64) @@ -66,6 +66,6 @@ func AnyToInt64(v any) int64 { v = vv } - f := valueToNumber[int64](v, Nil2Int64, boolToInt64, ParseInt64) + f := valueToNumber[int64](v, Nil2Int64, BoolToInt64, ParseInt64) return f } -- Gitee From d53ae5e6d37244b50980c8d7230b584a17038569 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:24:01 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E4=BF=AE=E6=94=B9ema=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=80=BC=E4=B8=BAstat.Series?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- formula/ema.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/formula/ema.go b/formula/ema.go index 33590e7..ac8310c 100644 --- a/formula/ema.go +++ b/formula/ema.go @@ -8,7 +8,7 @@ import ( // EMA 指数移动平均,为了精度 S>4*N EMA至少需要120周期 // alpha=2/(span+1) // TODO:这个版本是对的, 通达信EMA居然实现了真的序列, 那为啥SMA不是呢?! -func EMA(S stat.Series, N any) any { +func EMA(S stat.Series, N any) stat.Series { var X []stat.DType switch v := N.(type) { case int: @@ -28,7 +28,7 @@ func EMA(S stat.Series, N any) any { k = j } return stat.DType(stat.DType(2) / (j + 1)) - }, Adjust: false}).Mean().Values() + }, Adjust: false}).Mean() _ = k return x } -- Gitee From b4ad09f561259ffcecd6f8ac23a0b3d213077393 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:25:00 +0800 Subject: [PATCH 15/16] =?UTF-8?q?dataframe=E5=A2=9E=E5=8A=A0colAsNDArray?= =?UTF-8?q?=E6=B3=9B=E5=9E=8Bseries=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dataframe_select.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/dataframe_select.go b/dataframe_select.go index 0c2dc0d..1f281e3 100644 --- a/dataframe_select.go +++ b/dataframe_select.go @@ -19,6 +19,19 @@ func (self DataFrame) Col(colname string) stat.Series { return self.columns[idx].Copy() } +func (self DataFrame) ColAsNDArray(colname string) stat.Series { + if self.Err != nil { + return stat.NewSeries[stat.DType]() + } + // Check that colname exist on dataframe + idx := findInStringSlice(colname, self.Names()) + if idx < 0 { + return stat.NewSeries[stat.DType]() + } + vs := self.columns[idx].DTypes() + return stat.NewSeries[stat.DType](vs...) +} + // SetNames changes the column names of a DataFrame to the ones passed as an // argument. // 修改全部的列名 -- Gitee From bbb69c1403c5adc7f115a73bff322f522c6039e0 Mon Sep 17 00:00:00 2001 From: wangfeng Date: Fri, 17 Feb 2023 08:25:47 +0800 Subject: [PATCH 16/16] =?UTF-8?q?#I6CC23=20=E5=AE=9E=E7=8E=B0KDJ=E6=8C=87?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- indicator/kdj.go | 45 +++++++++++++++++++++++++++++++++++++++++++ indicator/kdj_test.go | 14 ++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 indicator/kdj.go create mode 100644 indicator/kdj_test.go diff --git a/indicator/kdj.go b/indicator/kdj.go new file mode 100644 index 0000000..00ed318 --- /dev/null +++ b/indicator/kdj.go @@ -0,0 +1,45 @@ +package indicator + +import ( + "gitee.com/quant1x/pandas" + . "gitee.com/quant1x/pandas/formula" +) + +// KDJ 指标 +// +// RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100; +// RSV赋值:(收盘价-N日内最低价的最低值)/(N日内最高价的最高值-N日内最低价的最低值)*100 +// K:EMA(RSV,M1,1); +// 输出K:RSV的M1日[1日权重]移动平均 +// D:EMA(K,M2,1); +// 输出D:K的M2日[1日权重]移动平均 +// J:3*K-2*D; +// 输出J:3*K-2*D +func KDJ(df pandas.DataFrame, N, M1, M2 int) pandas.DataFrame { + //CLOSE, HIGH, LOW stat.Series + var ( + CLOSE = df.ColAsNDArray("close") + HIGH = df.ColAsNDArray("high") + LOW = df.ColAsNDArray("low") + ) + + // 计算N周期的最高价序列 + x01 := HHV(HIGH, N) + // 计算N周期的最低价序列 + x02 := LLV(LOW, N) + + // CLOSE-LLV(LOW,N) + x11 := CLOSE.Sub(x02) + // (HHV(HIGH,N)-LLV(LOW,N))*100 + x12 := x01.Sub(x02) + + //(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100 + RSV := x11.Div(x12).Mul(100) + //K:SMA(RSV,M1,1); + K := EMA(RSV, M1*2-1) + D := EMA(K, M2*2-1) + // 3*K-2*D; + J := K.Mul(3).Sub(D.Mul(2)) + + return pandas.NewDataFrame(K, D, J) +} diff --git a/indicator/kdj_test.go b/indicator/kdj_test.go new file mode 100644 index 0000000..2099560 --- /dev/null +++ b/indicator/kdj_test.go @@ -0,0 +1,14 @@ +package indicator + +import ( + "fmt" + "gitee.com/quant1x/pandas/data/cache" + "testing" +) + +func TestKDJ(t *testing.T) { + df := cache.KLine("sz002528") + fmt.Println(df) + df1 := KDJ(df, 9, 3, 3) + fmt.Println(df1) +} -- Gitee