代码拉取完成,页面将自动刷新
package base
import (
"gitee.com/quant1x/engine/cache"
"gitee.com/quant1x/exchange"
"gitee.com/quant1x/gotdx"
"gitee.com/quant1x/gotdx/proto"
"gitee.com/quant1x/gotdx/quotes"
"gitee.com/quant1x/gox/api"
"gitee.com/quant1x/gox/logger"
"gitee.com/quant1x/pandas/stat"
)
var (
// BasicFields 特征基础字段
BasicFields = []string{"date", "open", "close", "high", "low", "volume", "amount"}
)
var (
// DataDaysDiff 日期差异偏移量
DataDaysDiff = 1
)
// KLine 日K线基础结构
type KLine struct {
Date string `name:"日期" dataframe:"date"` // 日期
Open float64 `name:"开盘" dataframe:"open"` // 开盘价
Close float64 `name:"收盘" dataframe:"close"` // 收盘价
High float64 `name:"最高" dataframe:"high"` // 最高价
Low float64 `name:"最低" dataframe:"low"` // 最低价
Volume float64 `name:"成交量(股)" dataframe:"volume"` // 成交量
Amount float64 `name:"成交额(元)" dataframe:"amount"` // 成交金额
Up int `name:"上涨/外盘" dataframe:"up"` // 上涨家数
Down int `name:"下跌/内盘" dataframe:"down"` // 下跌家数
}
// LoadBasicKline 加载基础K线
func LoadBasicKline(securityCode string) []KLine {
filename := cache.KLineFilename(securityCode)
var klines []KLine
_ = api.CsvToSlices(filename, &klines)
return klines
}
// UpdateAllBasicKLine 更新全部日K线基础数据并保存文件
func UpdateAllBasicKLine(securityCode string) []KLine {
startDate := exchange.MARKET_CN_FIRST_DATE
securityCode = exchange.CorrectSecurityCode(securityCode)
isIndex := exchange.AssertIndexBySecurityCode(securityCode)
cacheKLines := LoadBasicKline(securityCode)
kLength := len(cacheKLines)
var klineDaysOffset = DataDaysDiff
if kLength > 0 {
if klineDaysOffset > kLength {
klineDaysOffset = kLength
}
startDate = cacheKLines[kLength-klineDaysOffset].Date
} else {
//f10 := flash.GetL5F10(securityCode)
//if f10 != nil && len(f10.IpoDate) > 0 {
// startDate = f10.IpoDate
// startDate = trading.FixTradeDate(startDate)
//}
}
endDate := exchange.Today()
ts := exchange.TradeRange(startDate, endDate)
history := make([]quotes.SecurityBar, 0)
step := uint16(quotes.TDX_SECURITY_BARS_MAX)
total := uint16(len(ts))
start := uint16(0)
hs := make([]quotes.SecurityBarsReply, 0)
kType := uint16(proto.KLINE_TYPE_RI_K)
tdxApi := gotdx.GetTdxApi()
for {
count := step
if total-start >= step {
count = step
} else {
count = total - start
}
var data *quotes.SecurityBarsReply
var err error
retryTimes := 0
for retryTimes < quotes.DefaultRetryTimes {
if isIndex {
data, err = tdxApi.GetIndexBars(securityCode, kType, start, count)
} else {
data, err = tdxApi.GetKLine(securityCode, kType, start, count)
}
if err == nil && data != nil {
break
}
retryTimes++
}
if err != nil {
logger.Errorf("code=%s, error=%s", securityCode, err.Error())
return []KLine{}
}
hs = append(hs, *data)
if data.Count < count {
// 已经是最早的记录
// 需要排序
break
}
start += count
if start >= total {
break
}
}
hs = stat.Reverse(hs)
startDate = exchange.FixTradeDate(startDate)
for _, v := range hs {
for _, row := range v.List {
dateTime := exchange.FixTradeDate(row.DateTime)
if dateTime < startDate {
continue
}
row.Vol = row.Vol * 100
history = append(history, row)
}
}
var newKLines []KLine
for _, v := range history {
date := exchange.FixTradeDate(v.DateTime)
kline := KLine{
Date: date,
Open: v.Open,
Close: v.Close,
High: v.High,
Low: v.Low,
Volume: v.Vol,
Amount: v.Amount,
Up: int(v.UpCount),
Down: int(v.DownCount),
}
newKLines = append(newKLines, kline)
}
if len(newKLines) > 0 {
// 复权之前, 假定当前缓存之中的数据都是复权过的数据
// 那么就应该只拉取缓存最后1条记录之后的除权除息记录进行复权
// 前复权adjust
xdxrs := GetCacheXdxrList(securityCode)
cacheLastDay := newKLines[len(newKLines)-1].Date
for i := 0; i < len(xdxrs); i++ {
xdxr := xdxrs[i]
if xdxr.Category != 1 || xdxr.Date < startDate || xdxr.Date > cacheLastDay {
// 忽略非除权信息以及除权数据在新数据之前的除权记录
continue
}
xdxrDate := xdxr.Date
factor := xdxr.Adjust()
for j := 0; j < len(newKLines); j++ {
kl := &newKLines[j]
barCurrentDate := kl.Date
if barCurrentDate > xdxrDate {
break
}
if barCurrentDate < xdxrDate {
kl.Open = factor(kl.Open)
kl.Close = factor(kl.Close)
kl.High = factor(kl.High)
kl.Low = factor(kl.Low)
// 成交量复权
// 1. 计算均价线
maPrice := kl.Amount / kl.Volume
// 2. 均价线复权
maPrice = factor(maPrice)
// 3. 以成交金额为基准, 用复权均价线计算成交量
kl.Volume = kl.Amount / maPrice
}
//plc := m1["last_close"].(reflect.Value)
//plc.SetFloat(fuquan(plc.Float()))
if barCurrentDate == xdxrDate {
break
}
}
}
}
var klines []KLine
if kLength > klineDaysOffset {
klines = cacheKLines[:kLength-klineDaysOffset]
}
if len(klines) > 0 {
klines = append(klines, newKLines...)
} else {
klines = newKLines
}
if len(klines) > 0 {
UpdateCacheKLines(securityCode, klines)
fname := cache.KLineFilename(securityCode)
_ = api.SlicesToCsv(fname, klines)
}
return klines
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。