package factors import ( "gitee.com/quant1x/engine/cache" "gitee.com/quant1x/engine/datasource/base" "gitee.com/quant1x/exchange" "gitee.com/quant1x/gox/api" "gitee.com/quant1x/num" "gitee.com/quant1x/pandas" ) // BasicKLine 基础日K线 func BasicKLine(securityCode string) pandas.DataFrame { securityCode = exchange.CorrectSecurityCode(securityCode) filename := cache.KLineFilename(securityCode) df := pandas.ReadCSV(filename) return df } // KLine 加载日K线宽表 func KLine(securityCode string) pandas.DataFrame { securityCode = exchange.CorrectSecurityCode(securityCode) filename := cache.WideFilename(securityCode) df := pandas.ReadCSV(filename) return df } // KLineToWeekly 日线转周线 // // deprecated: 不推荐使用 func KLineToWeekly(kline pandas.DataFrame) pandas.DataFrame { // 周线 var df pandas.DataFrame //date,open,close,high,low,volume,amount,up,down var wdate string var o, c, h, l, v, a num.DType var bv, sv, ba, sa num.DType var prevClose num.DType for i := 0; i < kline.Nrow(); i++ { m := kline.IndexOf(i) //date,open,close,high,low,volume,amount,up,down // 周线日期以最后一天的日期为准 _date, ok := m["date"].(string) if ok { wdate = _date } // 周线开盘价以第一天OPEN为准 _open, ok := m["open"].(num.DType) if ok && o == num.DType(0) { o = _open } // 周线的收盘价以本周最后一个交易日的CLOSE为准 _close, ok := m["close"].(num.DType) if ok { c = _close } // 涨幅 zf := (c/prevClose - 1.00) * 100.00 _high, ok := m["high"].(num.DType) if ok && h == num.DType(0) { h = _high } if h < _high { h = _high } _low, ok := m["low"].(num.DType) if ok && l == num.DType(0) { l = _low } if l > _low { l = _low } _vol, ok := m["volume"] if ok { v += num.Any2DType(_vol) } _amount, ok := m["amount"].(num.DType) if ok { a += _amount } _bv, ok := m["bv"] if ok { bv += num.Any2DType(_bv) } _sv, ok := m["sv"] if ok { sv += num.Any2DType(_sv) } _ba, ok := m["ba"] if ok { ba += num.Any2DType(_ba) } _sa, ok := m["sa"] if ok { sa += num.Any2DType(_sa) } dt, _ := api.ParseTime(wdate) w := int(dt.Weekday()) last := false today := exchange.IndexToday() if wdate == today { last = true } // 如果是周五 if !last && w == 5 { last = true } if !last { nextDate := exchange.NextTradeDate(wdate) ndt, _ := api.ParseTime(nextDate) nw := int(ndt.Weekday()) if nw < w || api.DifferDays(ndt, dt) >= 7 { last = true } } if last { df0 := pandas.NewDataFrame( pandas.NewSeriesWithType(pandas.SERIES_TYPE_STRING, "date", wdate), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "open", o), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "close", c), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "high", h), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "low", l), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "volume", v), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "amount", a), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "bv", bv), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "sv", sv), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "ba", ba), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "sa", sa), pandas.NewSeriesWithType(pandas.SERIES_TYPE_DTYPE, "zf", zf), ) df = df.Concat(df0) wdate = "" prevClose = c o = num.DType(0) c = num.DType(0) h = num.DType(0) l = num.DType(0) v = num.DType(0) a = num.DType(0) } } return df } // MovingAverage 移动平均线(MA) type MovingAverage struct { MA5 float64 // 5日均线 MA10 float64 // 10日均线 MA20 float64 // 20日均线 } // 由日线计算日线以上级别的K线 func periodKLine(checkPeriod func(date ...string) (s, e string), securityCode string, cacheKLine ...[]base.KLine) (df pandas.DataFrame) { baseKLines := []base.KLine{} if len(cacheKLine) > 0 { baseKLines = cacheKLine[0] } else { baseKLines = base.LoadBasicKline(securityCode) } if len(baseKLines) == 0 { return } var klines []base.KLine var kline base.KLine length := len(baseKLines) for i, v := range baseKLines { // 确定时间, 周线的日期是本周内最后一个交易日 if len(kline.Date) == 0 { // 重新计算周线, 先确认周线范围 ws, we := checkPeriod(v.Date) _ = ws //dates := trading.TradeRange(ws, we) //days := len(dates) //days = 7 //if days > 0 { periodLastDate := exchange.FixTradeDate(we) //if periodLastDate == "2023-07-30" { // fmt.Println(1) //} offset := i for { destDate := baseKLines[offset].Date if destDate < periodLastDate { offset++ } if offset >= length { periodLastDate = destDate break } else if baseKLines[offset].Date == periodLastDate { periodLastDate = baseKLines[offset].Date break } else if baseKLines[offset].Date > periodLastDate { periodLastDate = destDate break } } kline.Date = periodLastDate //} else { // return //} } // 周线开盘价以第一天OPEN为准 if kline.Open == num.DType(0) { kline.Open = v.Open } // 周线的收盘价以本周最后一个交易日的CLOSE为准 kline.Close = v.Close if kline.High == num.DType(0) { kline.High = v.High } else if kline.High < v.High { kline.High = v.High } if kline.Low == num.DType(0) { kline.Low = v.Low } else if kline.Low > v.Low { kline.Low = v.Low } kline.Volume += v.Volume kline.Amount += v.Amount // 切换下一周 if kline.Date == v.Date || i+1 >= len(baseKLines) { kline.Date = v.Date klines = append(klines, kline) kline = base.KLine{} } } df = pandas.LoadStructs(klines) //fmt.Println(df) return } // WeeklyKLine 周线 func WeeklyKLine(securityCode string, cacheKLine ...[]base.KLine) (df pandas.DataFrame) { return periodKLine(api.GetWeekDay, securityCode, cacheKLine...) } // MonthlyKLine 月K线 func MonthlyKLine(securityCode string, cacheKLine ...[]base.KLine) (df pandas.DataFrame) { return periodKLine(api.GetMonthDay, securityCode, cacheKLine...) }