2 Star 3 Fork 10

王布衣 / engine

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
tdx_kline.go 4.21 KB
一键复制 编辑 原始数据 按行查看 历史
王布衣 提交于 2024-03-17 11:23 . 新增输出周线(非dataframe)函数
package base
import (
"gitee.com/quant1x/exchange"
"gitee.com/quant1x/gox/api"
"gitee.com/quant1x/num"
"gitee.com/quant1x/pandas"
"sync"
)
var (
klineMutex sync.RWMutex
routineLocalKLines = map[string][]KLine{}
)
func checkKLineOffset(klines []KLine, date string) (offset int) {
rows := len(klines)
offset = 0
for i := 0; i < rows; i++ {
klineDate := klines[rows-1-i].Date
if klineDate < date {
return -1
} else if klineDate == date {
break
} else {
offset++
}
}
if offset+1 >= rows {
return -1
}
return
}
// UpdateCacheKLines 更新缓存K线
func UpdateCacheKLines(securityCode string, klines []KLine) {
if len(klines) == 0 {
return
}
klineMutex.Lock()
routineLocalKLines[securityCode] = klines
klineMutex.Unlock()
}
// CheckoutKLines 捡出指定日期的K线数据
func CheckoutKLines(code, date string) []KLine {
securityCode := exchange.CorrectSecurityCode(code)
date = exchange.FixTradeDate(date)
// 1. 取缓存的K线
klineMutex.RLock()
cacheKLines, ok := routineLocalKLines[securityCode]
klineMutex.RUnlock()
if !ok {
cacheKLines = LoadBasicKline(securityCode)
UpdateCacheKLines(securityCode, cacheKLines)
}
rows := len(cacheKLines)
if rows == 0 {
return nil
}
// 1.1 检查是否最新数据
kline := cacheKLines[rows-1]
if kline.Date < date {
// 数据太旧, 重新加载
cacheKLines = LoadBasicKline(securityCode)
UpdateCacheKLines(securityCode, cacheKLines)
}
// 2. 对齐数据缓存的日期, 过滤可能存在停牌没有数据的情况
offset := checkKLineOffset(cacheKLines, date)
if offset < 0 {
return nil
}
// 3. 返回指定日期前的K线数据
klines := cacheKLines[0 : rows-offset]
return klines
}
// 由日线计算日线以上级别的K线
func getPeriodKLine(checkPeriod func(date ...string) (s, e string), securityCode string, cacheKLine ...[]KLine) (list []KLine) {
baseKLines := []KLine{}
if len(cacheKLine) > 0 {
baseKLines = cacheKLine[0]
} else {
baseKLines = LoadBasicKline(securityCode)
}
if len(baseKLines) == 0 {
return
}
var klines []KLine
var kline KLine
length := len(baseKLines)
for i, v := range baseKLines {
// 确定时间, 周线的日期是本周内最后一个交易日
if len(kline.Date) == 0 {
// 重新计算周线, 先确认周线范围
ws, we := checkPeriod(v.Date)
_ = ws
periodLastDate := exchange.FixTradeDate(we)
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
}
// 周线开盘价以第一天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 = KLine{}
}
}
return klines
}
// 由日线计算日线以上级别的K线
func periodKLine(checkPeriod func(date ...string) (s, e string), securityCode string, cacheKLine ...[]KLine) (df pandas.DataFrame) {
klines := getPeriodKLine(checkPeriod, securityCode, cacheKLine...)
df = pandas.LoadStructs(klines)
return
}
// WKLine 周线
func WKLine(securityCode string, cacheKLine ...[]KLine) []KLine {
klines := getPeriodKLine(api.GetWeekDay, securityCode, cacheKLine...)
return klines
}
// WeeklyKLine 周线
func WeeklyKLine(securityCode string, cacheKLine ...[]KLine) (df pandas.DataFrame) {
return periodKLine(api.GetWeekDay, securityCode, cacheKLine...)
}
// MonthlyKLine 月K线
func MonthlyKLine(securityCode string, cacheKLine ...[]KLine) (df pandas.DataFrame) {
return periodKLine(api.GetMonthDay, securityCode, cacheKLine...)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/quant1x/engine.git
git@gitee.com:quant1x/engine.git
quant1x
engine
engine
v1.8.10

搜索帮助

344bd9b3 5694891 D2dac590 5694891