mirror of
https://github.com/injoyai/tdx.git
synced 2025-11-26 21:25:35 +08:00
减少方法名称长度,去掉固定前缀Stock
This commit is contained in:
@@ -16,7 +16,8 @@
|
||||
### 数据校对
|
||||
|
||||
* 日K线校对
|
||||
 
|
||||

|
||||

|
||||
|
||||
* 校对分时成交
|
||||

|
||||
@@ -40,7 +41,7 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resp, err := c.GetStockQuotes(map[protocol.Exchange]string{
|
||||
resp, err := c.GetQuote(map[protocol.Exchange]string{
|
||||
protocol.ExchangeSH: "000001",
|
||||
protocol.ExchangeSZ: "600008",
|
||||
})
|
||||
|
||||
266
client.go
266
client.go
@@ -1,7 +1,6 @@
|
||||
package tdx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/injoyai/base/maps"
|
||||
"github.com/injoyai/base/maps/wait/v2"
|
||||
@@ -102,26 +101,26 @@ func (this *Client) handlerDealMessage(c *client.Client, msg ios.Acker) {
|
||||
|
||||
case protocol.TypeHeart:
|
||||
|
||||
case protocol.TypeStockCount:
|
||||
resp, err = protocol.MStockCount.Decode(f.Data)
|
||||
case protocol.TypeCount:
|
||||
resp, err = protocol.MCount.Decode(f.Data)
|
||||
|
||||
case protocol.TypeStockList:
|
||||
resp, err = protocol.MStockList.Decode(f.Data)
|
||||
case protocol.TypeCode:
|
||||
resp, err = protocol.MCode.Decode(f.Data)
|
||||
|
||||
case protocol.TypeStockQuote:
|
||||
resp = protocol.MStockQuote.Decode(f.Data)
|
||||
case protocol.TypeQuote:
|
||||
resp = protocol.MQuote.Decode(f.Data)
|
||||
|
||||
case protocol.TypeStockMinute:
|
||||
resp, err = protocol.MStockMinute.Decode(f.Data)
|
||||
case protocol.TypeMinute:
|
||||
resp, err = protocol.MMinute.Decode(f.Data)
|
||||
|
||||
case protocol.TypeStockMinuteTrade:
|
||||
resp, err = protocol.MStockMinuteTrade.Decode(f.Data, conv.String(val)) //todo
|
||||
case protocol.TypeMinuteTrade:
|
||||
resp, err = protocol.MMinuteTrade.Decode(f.Data, conv.String(val)) //todo
|
||||
|
||||
case protocol.TypeStockHistoryMinuteTrade:
|
||||
resp, err = protocol.MStockHistoryMinuteTrade.Decode(f.Data, conv.String(val))
|
||||
case protocol.TypeHistoryMinuteTrade:
|
||||
resp, err = protocol.MHistoryMinuteTrade.Decode(f.Data, conv.String(val))
|
||||
|
||||
case protocol.TypeStockKline:
|
||||
resp, err = protocol.MStockKline.Decode(f.Data, protocol.TypeKline(conv.Uint16(val)))
|
||||
case protocol.TypeKline:
|
||||
resp, err = protocol.MKline.Decode(f.Data, conv.Uint8(val))
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("通讯类型未解析:0x%X", f.Type)
|
||||
@@ -149,36 +148,36 @@ func (this *Client) SendFrame(f *protocol.Frame, cache ...any) (any, error) {
|
||||
return this.Wait.Wait(conv.String(this.msgID))
|
||||
}
|
||||
|
||||
// GetStockCount 获取市场内的股票数量
|
||||
func (this *Client) GetStockCount(exchange protocol.Exchange) (*protocol.StockCountResp, error) {
|
||||
f := protocol.MStockCount.Frame(exchange)
|
||||
// GetCount 获取市场内的股票数量
|
||||
func (this *Client) GetCount(exchange protocol.Exchange) (*protocol.CountResp, error) {
|
||||
f := protocol.MCount.Frame(exchange)
|
||||
result, err := this.SendFrame(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockCountResp), nil
|
||||
return result.(*protocol.CountResp), nil
|
||||
}
|
||||
|
||||
// GetStockList 获取市场内指定范围内的所有证券代码,一次固定返回1000只,上证股票有效范围370-1480
|
||||
// GetCode 获取市场内指定范围内的所有证券代码,一次固定返回1000只,上证股票有效范围370-1480
|
||||
// 上证前370只是395/399开头的(中证500/总交易等辅助类),在后面的话是一些100开头的国债
|
||||
// 600开头的股票是上证A股,属于大盘股,其中6006开头的股票是最早上市的股票, 6016开头的股票为大盘蓝筹股;900开头的股票是上证B股;
|
||||
// 000开头的股票是深证A股,001、002开头的股票也都属于深证A股, 其中002开头的股票是深证A股中小企业股票;200开头的股票是深证B股;
|
||||
// 300开头的股票是创业板股票;400开头的股票是三板市场股票。
|
||||
func (this *Client) GetStockList(exchange protocol.Exchange, start uint16) (*protocol.StockListResp, error) {
|
||||
f := protocol.MStockList.Frame(exchange, start)
|
||||
func (this *Client) GetCode(exchange protocol.Exchange, start uint16) (*protocol.CodeResp, error) {
|
||||
f := protocol.MCode.Frame(exchange, start)
|
||||
result, err := this.SendFrame(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockListResp), nil
|
||||
return result.(*protocol.CodeResp), nil
|
||||
}
|
||||
|
||||
// GetStockAll 通过多次请求的方式获取全部证券代码
|
||||
func (this *Client) GetStockAll(exchange protocol.Exchange) (*protocol.StockListResp, error) {
|
||||
resp := &protocol.StockListResp{}
|
||||
// GetCodeAll 通过多次请求的方式获取全部证券代码
|
||||
func (this *Client) GetCodeAll(exchange protocol.Exchange) (*protocol.CodeResp, error) {
|
||||
resp := &protocol.CodeResp{}
|
||||
size := uint16(1000)
|
||||
for start := uint16(0); ; start += size {
|
||||
r, err := this.GetStockList(exchange, start)
|
||||
r, err := this.GetCode(exchange, start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -191,9 +190,9 @@ func (this *Client) GetStockAll(exchange protocol.Exchange) (*protocol.StockList
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetStockQuotes 获取盘口五档报价
|
||||
func (this *Client) GetStockQuotes(m map[protocol.Exchange]string) (protocol.StockQuotesResp, error) {
|
||||
f, err := protocol.MStockQuote.Frame(m)
|
||||
// GetQuote 获取盘口五档报价
|
||||
func (this *Client) GetQuote(m map[protocol.Exchange]string) (protocol.QuotesResp, error) {
|
||||
f, err := protocol.MQuote.Frame(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -201,12 +200,12 @@ func (this *Client) GetStockQuotes(m map[protocol.Exchange]string) (protocol.Sto
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(protocol.StockQuotesResp), nil
|
||||
return result.(protocol.QuotesResp), nil
|
||||
}
|
||||
|
||||
// GetStockMinute 获取分时数据,todo 解析好像不对
|
||||
func (this *Client) GetStockMinute(exchange protocol.Exchange, code string) (*protocol.StockMinuteResp, error) {
|
||||
f, err := protocol.MStockMinute.Frame(exchange, code)
|
||||
// GetMinute 获取分时数据,todo 解析好像不对
|
||||
func (this *Client) GetMinute(exchange protocol.Exchange, code string) (*protocol.MinuteResp, error) {
|
||||
f, err := protocol.MMinute.Frame(exchange, code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -214,31 +213,33 @@ func (this *Client) GetStockMinute(exchange protocol.Exchange, code string) (*pr
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockMinuteResp), nil
|
||||
return result.(*protocol.MinuteResp), nil
|
||||
}
|
||||
|
||||
// GetStockMinuteTrade 获取分时交易详情,服务器最多返回1800条,count-start<=1800
|
||||
func (this *Client) GetStockMinuteTrade(exchange protocol.Exchange, code string, start, count uint16) (*protocol.StockMinuteTradeResp, error) {
|
||||
if count > 1800 {
|
||||
return nil, errors.New("数量不能超过1800")
|
||||
}
|
||||
f, err := protocol.MStockMinuteTrade.Frame(exchange, code, start, count)
|
||||
// GetMinuteTrade 获取分时交易详情,服务器最多返回1800条,count-start<=1800
|
||||
func (this *Client) GetMinuteTrade(req protocol.MinuteTradeReq) (*protocol.MinuteTradeResp, error) {
|
||||
f, err := protocol.MMinuteTrade.Frame(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := this.SendFrame(f, code)
|
||||
result, err := this.SendFrame(f, req.Code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockMinuteTradeResp), nil
|
||||
return result.(*protocol.MinuteTradeResp), nil
|
||||
}
|
||||
|
||||
// GetStockMinuteTradeAll 获取分时全部交易详情,todo 只做参考 因为交易实时在进行,然后又是分页读取的,所以会出现读取间隔内产生的交易会丢失
|
||||
func (this *Client) GetStockMinuteTradeAll(exchange protocol.Exchange, code string) (*protocol.StockMinuteTradeResp, error) {
|
||||
resp := &protocol.StockMinuteTradeResp{}
|
||||
// GetMinuteTradeAll 获取分时全部交易详情,todo 只做参考 因为交易实时在进行,然后又是分页读取的,所以会出现读取间隔内产生的交易会丢失
|
||||
func (this *Client) GetMinuteTradeAll(exchange protocol.Exchange, code string) (*protocol.MinuteTradeResp, error) {
|
||||
resp := &protocol.MinuteTradeResp{}
|
||||
size := uint16(1800)
|
||||
for i := uint16(0); ; i += size {
|
||||
r, err := this.GetStockMinuteTrade(exchange, code, i, size)
|
||||
for start := uint16(0); ; start += size {
|
||||
r, err := this.GetMinuteTrade(protocol.MinuteTradeReq{
|
||||
Exchange: exchange,
|
||||
Code: code,
|
||||
Start: start,
|
||||
Count: size,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -252,33 +253,36 @@ func (this *Client) GetStockMinuteTradeAll(exchange protocol.Exchange, code stri
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetStockHistoryMinuteTrade 获取历史分时交易,,只能获取昨天及之前的数据,服务器最多返回2000条,count-start<=2000
|
||||
func (this *Client) GetStockHistoryMinuteTrade(t time.Time, exchange protocol.Exchange, code string, start, count uint16) (*protocol.StockHistoryMinuteTradeResp, error) {
|
||||
if count > 2000 {
|
||||
return nil, errors.New("数量不能超过2000")
|
||||
}
|
||||
f, err := protocol.MStockHistoryMinuteTrade.Frame(t, exchange, code, start, count)
|
||||
// GetHistoryMinuteTrade 获取历史分时交易,,只能获取昨天及之前的数据,服务器最多返回2000条,count-start<=2000,如果日期输入错误,则返回0
|
||||
func (this *Client) GetHistoryMinuteTrade(req protocol.HistoryMinuteTradeReq) (*protocol.HistoryMinuteTradeResp, error) {
|
||||
f, err := protocol.MHistoryMinuteTrade.Frame(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := this.SendFrame(f, code)
|
||||
result, err := this.SendFrame(f, req.Code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockHistoryMinuteTradeResp), nil
|
||||
return result.(*protocol.HistoryMinuteTradeResp), nil
|
||||
}
|
||||
|
||||
// GetStockHistoryMinuteTradeAll 获取历史分时全部交易,通过多次请求来拼接,只能获取昨天及之前的数据
|
||||
func (this *Client) GetStockHistoryMinuteTradeAll(exchange protocol.Exchange, code string) (*protocol.StockMinuteTradeResp, error) {
|
||||
resp := &protocol.StockMinuteTradeResp{}
|
||||
// GetHistoryMinuteTradeAll 获取历史分时全部交易,通过多次请求来拼接,只能获取昨天及之前的数据
|
||||
func (this *Client) GetHistoryMinuteTradeAll(req protocol.HistoryMinuteTradeAllReq) (*protocol.HistoryMinuteTradeResp, error) {
|
||||
resp := &protocol.HistoryMinuteTradeResp{}
|
||||
size := uint16(2000)
|
||||
for i := uint16(0); ; i += size {
|
||||
r, err := this.GetStockMinuteTrade(exchange, code, i, size)
|
||||
for start := uint16(0); ; start += size {
|
||||
r, err := this.GetHistoryMinuteTrade(protocol.HistoryMinuteTradeReq{
|
||||
Date: req.Date,
|
||||
Exchange: req.Exchange,
|
||||
Code: req.Code,
|
||||
Start: start,
|
||||
Count: size,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp.Count += r.Count
|
||||
resp.List = append(resp.List, r.List...)
|
||||
resp.List = append(r.List, resp.List...)
|
||||
if r.Count < size {
|
||||
break
|
||||
}
|
||||
@@ -286,26 +290,26 @@ func (this *Client) GetStockHistoryMinuteTradeAll(exchange protocol.Exchange, co
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetStockKline 获取k线数据
|
||||
func (this *Client) GetStockKline(Type protocol.TypeKline, req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
f, err := protocol.MStockKline.Frame(Type, req)
|
||||
// GetKline 获取k线数据
|
||||
func (this *Client) GetKline(Type uint8, req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
f, err := protocol.MKline.Frame(Type, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := this.SendFrame(f, Type.Uint16())
|
||||
result, err := this.SendFrame(f, Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockKlineResp), nil
|
||||
return result.(*protocol.KlineResp), nil
|
||||
}
|
||||
|
||||
// GetStockKlineAll 获取全部k线数据
|
||||
func (this *Client) GetStockKlineAll(Type protocol.TypeKline, exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
resp := &protocol.StockKlineResp{}
|
||||
// GetKlineAll 获取全部k线数据
|
||||
func (this *Client) GetKlineAll(Type uint8, exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
resp := &protocol.KlineResp{}
|
||||
size := uint16(800)
|
||||
var last *protocol.StockKline
|
||||
var last *protocol.Kline
|
||||
for i := uint16(0); ; i += size {
|
||||
r, err := this.GetStockKline(Type, &protocol.StockKlineReq{
|
||||
r, err := this.GetKline(Type, protocol.KlineReq{
|
||||
Exchange: exchange,
|
||||
Code: code,
|
||||
Start: i,
|
||||
@@ -329,102 +333,102 @@ func (this *Client) GetStockKlineAll(Type protocol.TypeKline, exchange protocol.
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetStockKlineMinute 获取一分钟k线数据
|
||||
func (this *Client) GetStockKlineMinute(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineMinute, req)
|
||||
// GetKlineMinute 获取一分钟k线数据
|
||||
func (this *Client) GetKlineMinute(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineMinute, req)
|
||||
}
|
||||
|
||||
// GetStockKlineMinuteAll 获取一分钟k线全部数据
|
||||
func (this *Client) GetStockKlineMinuteAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineMinute, exchange, code)
|
||||
// GetKlineMinuteAll 获取一分钟k线全部数据
|
||||
func (this *Client) GetKlineMinuteAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineMinute, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKline5Minute 获取五分钟k线数据
|
||||
func (this *Client) GetStockKline5Minute(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKline5Minute, req)
|
||||
// GetKline5Minute 获取五分钟k线数据
|
||||
func (this *Client) GetKline5Minute(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKline5Minute, req)
|
||||
}
|
||||
|
||||
// GetStockKline5MinuteAll 获取5分钟k线全部数据
|
||||
func (this *Client) GetStockKline5MinuteAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKline5Minute, exchange, code)
|
||||
// GetKline5MinuteAll 获取5分钟k线全部数据
|
||||
func (this *Client) GetKline5MinuteAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKline5Minute, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKline15Minute 获取十五分钟k线数据
|
||||
func (this *Client) GetStockKline15Minute(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKline15Minute, req)
|
||||
// GetKline15Minute 获取十五分钟k线数据
|
||||
func (this *Client) GetKline15Minute(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKline15Minute, req)
|
||||
}
|
||||
|
||||
// GetStockKline15MinuteAll 获取十五分钟k线全部数据
|
||||
func (this *Client) GetStockKline15MinuteAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKline15Minute, exchange, code)
|
||||
// GetKline15MinuteAll 获取十五分钟k线全部数据
|
||||
func (this *Client) GetKline15MinuteAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKline15Minute, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKline30Minute 获取三十分钟k线数据
|
||||
func (this *Client) GetStockKline30Minute(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKline30Minute, req)
|
||||
// GetKline30Minute 获取三十分钟k线数据
|
||||
func (this *Client) GetKline30Minute(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKline30Minute, req)
|
||||
}
|
||||
|
||||
// GetStockKline30MinuteAll 获取三十分钟k线全部数据
|
||||
func (this *Client) GetStockKline30MinuteAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKline30Minute, exchange, code)
|
||||
// GetKline30MinuteAll 获取三十分钟k线全部数据
|
||||
func (this *Client) GetKline30MinuteAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKline30Minute, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKlineHour 获取小时k线数据
|
||||
func (this *Client) GetStockKlineHour(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineHour, req)
|
||||
// GetKlineHour 获取小时k线数据
|
||||
func (this *Client) GetKlineHour(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineHour, req)
|
||||
}
|
||||
|
||||
// GetStockKlineHourAll 获取小时k线全部数据
|
||||
func (this *Client) GetStockKlineHourAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineHour, exchange, code)
|
||||
// GetKlineHourAll 获取小时k线全部数据
|
||||
func (this *Client) GetKlineHourAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineHour, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKlineDay 获取日k线数据
|
||||
func (this *Client) GetStockKlineDay(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineDay, req)
|
||||
// GetKlineDay 获取日k线数据
|
||||
func (this *Client) GetKlineDay(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineDay, req)
|
||||
}
|
||||
|
||||
// GetStockKlineDayAll 获取日k线全部数据
|
||||
func (this *Client) GetStockKlineDayAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineDay, exchange, code)
|
||||
// GetKlineDayAll 获取日k线全部数据
|
||||
func (this *Client) GetKlineDayAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineDay, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKlineWeek 获取周k线数据
|
||||
func (this *Client) GetStockKlineWeek(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineWeek, req)
|
||||
// GetKlineWeek 获取周k线数据
|
||||
func (this *Client) GetKlineWeek(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineWeek, req)
|
||||
}
|
||||
|
||||
// GetStockKlineWeekAll 获取周k线全部数据
|
||||
func (this *Client) GetStockKlineWeekAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineWeek, exchange, code)
|
||||
// GetKlineWeekAll 获取周k线全部数据
|
||||
func (this *Client) GetKlineWeekAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineWeek, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKlineMonth 获取月k线数据
|
||||
func (this *Client) GetStockKlineMonth(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineMonth, req)
|
||||
func (this *Client) GetStockKlineMonth(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineMonth, req)
|
||||
}
|
||||
|
||||
// GetStockKlineMonthAll 获取月k线全部数据
|
||||
func (this *Client) GetStockKlineMonthAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineMonth, exchange, code)
|
||||
// GetKlineMonthAll 获取月k线全部数据
|
||||
func (this *Client) GetKlineMonthAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineMonth, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKlineQuarter 获取季k线数据
|
||||
func (this *Client) GetStockKlineQuarter(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineQuarter, req)
|
||||
// GetKlineQuarter 获取季k线数据
|
||||
func (this *Client) GetKlineQuarter(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineQuarter, req)
|
||||
}
|
||||
|
||||
// GetStockKlineQuarterAll 获取季k线全部数据
|
||||
func (this *Client) GetStockKlineQuarterAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineQuarter, exchange, code)
|
||||
// GetKlineQuarterAll 获取季k线全部数据
|
||||
func (this *Client) GetKlineQuarterAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineQuarter, exchange, code)
|
||||
}
|
||||
|
||||
// GetStockKlineYear 获取年k线数据
|
||||
func (this *Client) GetStockKlineYear(req *protocol.StockKlineReq) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKline(protocol.TypeKlineYear, req)
|
||||
// GetKlineYear 获取年k线数据
|
||||
func (this *Client) GetKlineYear(req protocol.KlineReq) (*protocol.KlineResp, error) {
|
||||
return this.GetKline(protocol.TypeKlineYear, req)
|
||||
}
|
||||
|
||||
// GetStockKlineYearAll 获取年k线数据
|
||||
func (this *Client) GetStockKlineYearAll(exchange protocol.Exchange, code string) (*protocol.StockKlineResp, error) {
|
||||
return this.GetStockKlineAll(protocol.TypeKlineYear, exchange, code)
|
||||
// GetKlineYearAll 获取年k线数据
|
||||
func (this *Client) GetKlineYearAll(exchange protocol.Exchange, code string) (*protocol.KlineResp, error) {
|
||||
return this.GetKlineAll(protocol.TypeKlineYear, exchange, code)
|
||||
}
|
||||
|
||||
@@ -23,9 +23,14 @@ func init() {
|
||||
}
|
||||
|
||||
func TestClient_GetStockHistoryMinuteTrade(t *testing.T) {
|
||||
ti := time.Date(2024, 10, 28, 0, 0, 0, 0, time.Local)
|
||||
do(func(c *Client) {
|
||||
resp, err := c.GetStockHistoryMinuteTrade(ti, protocol.ExchangeSH, "000001", 0, 100)
|
||||
resp, err := c.GetStockHistoryMinuteTrade(protocol.StockHistoryMinuteTradeReq{
|
||||
Time: time.Date(2024, 10, 28, 0, 0, 0, 0, time.Local),
|
||||
Exchange: protocol.ExchangeSZ,
|
||||
Code: "000001",
|
||||
Start: 0,
|
||||
Count: 100,
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
|
||||
@@ -10,7 +10,7 @@ func main() {
|
||||
c, err := tdx.Dial("124.71.187.122:7709")
|
||||
logs.PanicErr(err)
|
||||
|
||||
resp, err := c.GetStockList(protocol.ExchangeSH, 369)
|
||||
resp, err := c.GetCode(protocol.ExchangeSH, 369)
|
||||
logs.PanicErr(err)
|
||||
|
||||
for i, v := range resp.List {
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
func main() {
|
||||
common.Test(func(c *tdx.Client) {
|
||||
resp, err := c.GetStockAll(protocol.ExchangeSZ)
|
||||
resp, err := c.GetCodeAll(protocol.ExchangeSZ)
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
@@ -10,7 +10,7 @@ func main() {
|
||||
c, err := tdx.Dial("124.71.187.122:7709")
|
||||
logs.PanicErr(err)
|
||||
|
||||
resp, err := c.GetStockCount(protocol.ExchangeSH)
|
||||
resp, err := c.GetCount(protocol.ExchangeSH)
|
||||
logs.PanicErr(err)
|
||||
|
||||
logs.Debug(resp.Count)
|
||||
26
example/GetHistoryMinuteTrade/main.go
Normal file
26
example/GetHistoryMinuteTrade/main.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/injoyai/logs"
|
||||
"github.com/injoyai/tdx"
|
||||
"github.com/injoyai/tdx/example/common"
|
||||
"github.com/injoyai/tdx/protocol"
|
||||
)
|
||||
|
||||
func main() {
|
||||
common.Test(func(c *tdx.Client) {
|
||||
resp, err := c.GetHistoryMinuteTrade(protocol.HistoryMinuteTradeReq{
|
||||
Date: "20241027",
|
||||
Exchange: protocol.ExchangeSZ,
|
||||
Code: "000001",
|
||||
Count: 10,
|
||||
})
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
logs.Debug(v)
|
||||
}
|
||||
|
||||
logs.Debug("总数:", resp.Count)
|
||||
})
|
||||
}
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
"github.com/injoyai/tdx"
|
||||
"github.com/injoyai/tdx/example/common"
|
||||
"github.com/injoyai/tdx/protocol"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
common.Test(func(c *tdx.Client) {
|
||||
t := time.Date(2024, 10, 28, 0, 0, 0, 0, time.Local)
|
||||
resp, err := c.GetStockHistoryMinuteTrade(t, protocol.ExchangeSH, "000001", 0, 2000)
|
||||
resp, err := c.GetHistoryMinuteTradeAll(protocol.HistoryMinuteTradeAllReq{
|
||||
Date: "20241027",
|
||||
Exchange: protocol.ExchangeSZ,
|
||||
Code: "000001",
|
||||
})
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
func main() {
|
||||
common.Test(func(c *tdx.Client) {
|
||||
resp, err := c.GetStockKlineDayAll(protocol.ExchangeSH, "000001")
|
||||
resp, err := c.GetKlineDayAll(protocol.ExchangeSH, "000001")
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
@@ -10,7 +10,7 @@ func main() {
|
||||
c, err := tdx.Dial("124.71.187.122:7709")
|
||||
logs.PanicErr(err)
|
||||
|
||||
resp, err := c.GetStockMinute(protocol.ExchangeSH, "000001")
|
||||
resp, err := c.GetMinute(protocol.ExchangeSH, "000001")
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
@@ -10,7 +10,12 @@ import (
|
||||
func main() {
|
||||
common.Test(func(c *tdx.Client) {
|
||||
|
||||
resp, err := c.GetStockMinuteTrade(protocol.ExchangeSH, "000001", 0, 100)
|
||||
resp, err := c.GetMinuteTrade(protocol.MinuteTradeReq{
|
||||
Exchange: protocol.ExchangeSZ,
|
||||
Code: "000001",
|
||||
Start: 0,
|
||||
Count: 100,
|
||||
})
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
@@ -21,9 +21,9 @@ func main() {
|
||||
b1cb74001c00000000000d005100bd00789c6378c1cecb252ace6066c5b4898987b9050ed1f90cc5b74c18a5bc18c1b43490fecff09c81819191f13fc3c9f3bb169f5e7dfefeb5ef57f7199a305009308208e5b32bb6bcbf70148712002d7f1e13
|
||||
b1cb74000c02000000003e05ac00ac000102020000303030303031601294121a1c2d4eadabcf0ed412aae5fc01afb0024561124fbcc08301afa47900b2e3174100bf68871a4201b741b6144302bb09af334403972e96354504ac09b619560e00000000f8ff601201363030303038b60fba04060607429788a70efa04ada37ab2531c12974d91e7449dbc354184b6010001844bad324102b5679ea1014203a65abd8d0143048a6ba4dd01440587e101b3d2029613000000000000b60f
|
||||
*/
|
||||
resp, err := c.GetStockQuotes(map[protocol.Exchange]string{
|
||||
protocol.ExchangeSH: "000001",
|
||||
protocol.ExchangeSZ: "600008",
|
||||
resp, err := c.GetQuote(map[protocol.Exchange]string{
|
||||
protocol.ExchangeSZ: "000001",
|
||||
protocol.ExchangeSH: "600008",
|
||||
})
|
||||
logs.PanicErr(err)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package protocol
|
||||
|
||||
const (
|
||||
TypeConnect = 0x000D //建立连接
|
||||
TypeHeart = 0x0004 //心跳
|
||||
TypeStockCount = 0x044E //获取股票数量
|
||||
TypeStockList = 0x0450 //获取股票代码
|
||||
TypeStockQuote = 0x053E //行情信息
|
||||
TypeStockMinute = 0x051D //分时数据
|
||||
TypeStockMinuteTrade = 0x0FC5 //分时交易
|
||||
TypeStockHistoryMinuteTrade = 0x0FB5 //历史分时交易
|
||||
TypeStockKline = 0x052D //K线图
|
||||
TypeConnect = 0x000D //建立连接
|
||||
TypeHeart = 0x0004 //心跳
|
||||
TypeCount = 0x044E //获取股票数量
|
||||
TypeCode = 0x0450 //获取股票代码
|
||||
TypeQuote = 0x053E //行情信息
|
||||
TypeMinute = 0x051D //分时数据
|
||||
TypeMinuteTrade = 0x0FC5 //分时交易
|
||||
TypeHistoryMinuteTrade = 0x0FB5 //历史分时交易
|
||||
TypeKline = 0x052D //K线图
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,7 +84,7 @@ func Decode(bs []byte) (*Response, error) {
|
||||
}
|
||||
|
||||
if resp.Control&0x10 != 0x10 {
|
||||
//return nil, fmt.Errorf("控制码不匹配,预期0x1c,得到0x%x", resp.Control)
|
||||
return nil, fmt.Errorf("请求失败,请检查参数")
|
||||
}
|
||||
|
||||
if int(resp.ZipLength) != len(bs[16:]) {
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type StockListResp struct {
|
||||
type CodeResp struct {
|
||||
Count uint16
|
||||
List []*Stock
|
||||
List []*Code
|
||||
}
|
||||
|
||||
type Stock struct {
|
||||
type Code struct {
|
||||
Name string //股票名称
|
||||
Code string //股票代码
|
||||
Multiple uint16 //倍数,基本是0x64=100
|
||||
@@ -18,33 +18,33 @@ type Stock struct {
|
||||
PreClose float64 //未知
|
||||
}
|
||||
|
||||
func (this *Stock) String() string {
|
||||
func (this *Code) String() string {
|
||||
return fmt.Sprintf("%s(%s)", this.Code, this.Name)
|
||||
}
|
||||
|
||||
type stockList struct{}
|
||||
type code struct{}
|
||||
|
||||
func (stockList) Frame(exchange Exchange, start uint16) *Frame {
|
||||
func (code) Frame(exchange Exchange, start uint16) *Frame {
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockList,
|
||||
Type: TypeCode,
|
||||
Data: []byte{exchange.Uint8(), 0x0, uint8(start), uint8(start >> 8)},
|
||||
}
|
||||
}
|
||||
|
||||
func (stockList) Decode(bs []byte) (*StockListResp, error) {
|
||||
func (code) Decode(bs []byte) (*CodeResp, error) {
|
||||
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &StockListResp{
|
||||
resp := &CodeResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
bs = bs[2:]
|
||||
|
||||
for i := uint16(0); i < resp.Count; i++ {
|
||||
sec := &Stock{
|
||||
sec := &Code{
|
||||
Code: string(bs[:6]),
|
||||
Multiple: Uint16(bs[6:8]),
|
||||
Name: string(UTF8ToGBK(bs[8:16])),
|
||||
@@ -5,15 +5,15 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
MConnect = connect{}
|
||||
MHeart = heart{}
|
||||
MStockCount = stockCount{}
|
||||
MStockQuote = stockQuote{}
|
||||
MStockList = stockList{}
|
||||
MStockMinute = stockMinute{}
|
||||
MStockMinuteTrade = stockMinuteTrade{}
|
||||
MStockHistoryMinuteTrade = stockHistoryMinuteTrade{}
|
||||
MStockKline = stockKline{}
|
||||
MConnect = connect{}
|
||||
MHeart = heart{}
|
||||
MCount = count{}
|
||||
MQuote = quote{}
|
||||
MCode = code{}
|
||||
MMinute = minute{}
|
||||
MMinuteTrade = minuteTrade{}
|
||||
MHistoryMinuteTrade = historyMinuteTrade{}
|
||||
MKline = kline{}
|
||||
)
|
||||
|
||||
type ConnectResp struct {
|
||||
|
||||
@@ -2,24 +2,24 @@ package protocol
|
||||
|
||||
import "errors"
|
||||
|
||||
type StockCountResp struct {
|
||||
type CountResp struct {
|
||||
Count uint16
|
||||
}
|
||||
|
||||
type stockCount struct{}
|
||||
type count struct{}
|
||||
|
||||
// Frame 0c0200000001080008004e04000075c73301
|
||||
func (this *stockCount) Frame(exchange Exchange) *Frame {
|
||||
func (this *count) Frame(exchange Exchange) *Frame {
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockCount,
|
||||
Type: TypeCount,
|
||||
Data: []byte{exchange.Uint8(), 0x0, 0x75, 0xc7, 0x33, 0x01}, //后面的4字节不知道啥意思
|
||||
}
|
||||
}
|
||||
|
||||
func (this *stockCount) Decode(bs []byte) (*StockCountResp, error) {
|
||||
func (this *count) Decode(bs []byte) (*CountResp, error) {
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
return &StockCountResp{Count: Uint16(bs)}, nil
|
||||
return &CountResp{Count: Uint16(bs)}, nil
|
||||
}
|
||||
112
protocol/model_history_minute_trade.go
Normal file
112
protocol/model_history_minute_trade.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/injoyai/conv"
|
||||
)
|
||||
|
||||
// HistoryMinuteTradeAllReq 获取指定日期全部数据的请求参数
|
||||
type HistoryMinuteTradeAllReq struct {
|
||||
Date string //20241030
|
||||
Exchange Exchange
|
||||
Code string
|
||||
}
|
||||
|
||||
// HistoryMinuteTradeReq 获取指定日期分页数据的请求参数
|
||||
type HistoryMinuteTradeReq struct {
|
||||
Date string //20241030
|
||||
Exchange Exchange
|
||||
Code string
|
||||
Start uint16
|
||||
Count uint16
|
||||
}
|
||||
|
||||
func (req HistoryMinuteTradeReq) Check() error {
|
||||
if req.Count > 2000 {
|
||||
return errors.New("数量不能超过2000")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HistoryMinuteTradeResp 历史分时交易比实时少了单量
|
||||
type HistoryMinuteTradeResp struct {
|
||||
Count uint16
|
||||
List []*HistoryMinuteTrade
|
||||
}
|
||||
|
||||
type HistoryMinuteTrade struct {
|
||||
Time string //时间
|
||||
Price Price //价格
|
||||
Volume int //成交量
|
||||
Status int //0是买,1是卖,2无效(汇总出现)
|
||||
}
|
||||
|
||||
func (this *HistoryMinuteTrade) String() string {
|
||||
return fmt.Sprintf("%s \t%s \t%-6s \t%-6d(手) \t%-4s", this.Time, this.Price, this.Amount(), this.Volume, this.StatusString())
|
||||
}
|
||||
|
||||
// Amount 成交额
|
||||
func (this *HistoryMinuteTrade) Amount() Price {
|
||||
return this.Price * Price(this.Volume) * 100
|
||||
}
|
||||
|
||||
func (this *HistoryMinuteTrade) StatusString() string {
|
||||
switch this.Status {
|
||||
case 0:
|
||||
return "买入"
|
||||
case 1:
|
||||
return "卖出"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
type historyMinuteTrade struct{}
|
||||
|
||||
func (historyMinuteTrade) Frame(req HistoryMinuteTradeReq) (*Frame, error) {
|
||||
if err := req.Check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
date := conv.Uint32(req.Date) //req.Time.Format("20060102"))
|
||||
dataBs := Bytes(date)
|
||||
dataBs = append(dataBs, req.Exchange.Uint8(), 0x0)
|
||||
dataBs = append(dataBs, []byte(req.Code)...)
|
||||
dataBs = append(dataBs, Bytes(req.Start)...)
|
||||
dataBs = append(dataBs, Bytes(req.Count)...)
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeHistoryMinuteTrade,
|
||||
Data: dataBs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (historyMinuteTrade) Decode(bs []byte, code string) (*HistoryMinuteTradeResp, error) {
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &HistoryMinuteTradeResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
|
||||
//第2-6字节不知道是啥
|
||||
bs = bs[2+4:]
|
||||
|
||||
lastPrice := Price(0)
|
||||
for i := uint16(0); i < resp.Count; i++ {
|
||||
mt := &HistoryMinuteTrade{
|
||||
Time: GetHourMinute([2]byte(bs[:2])),
|
||||
}
|
||||
var sub Price
|
||||
bs, sub = GetPrice(bs[2:])
|
||||
lastPrice += sub
|
||||
mt.Price = lastPrice / basePrice(code)
|
||||
bs, mt.Volume = CutInt(bs)
|
||||
bs, mt.Status = CutInt(bs)
|
||||
bs, _ = CutInt(bs) //这个得到的是0,不知道是啥
|
||||
resp.List = append(resp.List, mt)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -8,8 +8,13 @@ import (
|
||||
func Test_stockHistoryMinuteTrade_Frame(t *testing.T) {
|
||||
// 预期 0c 02000000 00 1200 1200 b50f 84da3401 0000 30303030303100006400
|
||||
// 0c000000000112001200b50f84da3401000030303030303100006400
|
||||
ti := time.Date(2024, 10, 28, 0, 0, 0, 0, time.Local)
|
||||
f, err := MStockHistoryMinuteTrade.Frame(ti, ExchangeSH, "000001", 0, 100)
|
||||
f, err := MStockHistoryMinuteTrade.Frame(StockHistoryMinuteTradeReq{
|
||||
Time: time.Date(2024, 10, 28, 0, 0, 0, 0, time.Local),
|
||||
Exchange: ExchangeSZ,
|
||||
Code: "000001",
|
||||
Start: 0,
|
||||
Count: 100,
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
@@ -7,14 +7,14 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type StockKlineReq struct {
|
||||
type KlineReq struct {
|
||||
Exchange Exchange
|
||||
Code string
|
||||
Start uint16
|
||||
Count uint16
|
||||
}
|
||||
|
||||
func (this *StockKlineReq) Bytes(Type TypeKline) (g.Bytes, error) {
|
||||
func (this *KlineReq) Bytes(Type uint8) (g.Bytes, error) {
|
||||
if this.Count > 800 {
|
||||
return nil, errors.New("单次数量不能超过800")
|
||||
}
|
||||
@@ -23,7 +23,7 @@ func (this *StockKlineReq) Bytes(Type TypeKline) (g.Bytes, error) {
|
||||
}
|
||||
data := []byte{this.Exchange.Uint8(), 0x0}
|
||||
data = append(data, []byte(this.Code)...) //这里怎么是正序了?
|
||||
data = append(data, Bytes(Type.Uint16())...)
|
||||
data = append(data, Type, 0x0)
|
||||
data = append(data, 0x01, 0x0)
|
||||
data = append(data, Bytes(this.Start)...)
|
||||
data = append(data, Bytes(this.Count)...)
|
||||
@@ -31,12 +31,12 @@ func (this *StockKlineReq) Bytes(Type TypeKline) (g.Bytes, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
type StockKlineResp struct {
|
||||
type KlineResp struct {
|
||||
Count uint16
|
||||
List []*StockKline
|
||||
List []*Kline
|
||||
}
|
||||
|
||||
type StockKline struct {
|
||||
type Kline struct {
|
||||
Last Price //昨日收盘价,这个是列表的上一条数据的收盘价,如果没有上条数据,那么这个值为0
|
||||
Open Price //开盘价
|
||||
High Price //最高价
|
||||
@@ -47,7 +47,7 @@ type StockKline struct {
|
||||
Time time.Time //时间
|
||||
}
|
||||
|
||||
func (this *StockKline) String() string {
|
||||
func (this *Kline) String() string {
|
||||
return fmt.Sprintf("%s 昨收盘:%s 开盘价:%s 最高价:%s 最低价:%s 收盘价:%s 涨跌:%s 涨跌幅:%0.2f 成交量:%s 成交额:%s",
|
||||
this.Time.Format("2006-01-02 15:04:05"),
|
||||
this.Last, this.Open, this.High, this.Low, this.Close,
|
||||
@@ -57,12 +57,12 @@ func (this *StockKline) String() string {
|
||||
}
|
||||
|
||||
// MaxDifference 最大差值,最高-最低
|
||||
func (this *StockKline) MaxDifference() Price {
|
||||
func (this *Kline) MaxDifference() Price {
|
||||
return this.High - this.Low
|
||||
}
|
||||
|
||||
// RisePrice 涨跌金额,第一个数据不准,仅做参考
|
||||
func (this *StockKline) RisePrice() Price {
|
||||
func (this *Kline) RisePrice() Price {
|
||||
if this.Last == 0 {
|
||||
//稍微数据准确点,没减去0这么夸张,还是不准的
|
||||
return this.Close - this.Open
|
||||
@@ -72,31 +72,31 @@ func (this *StockKline) RisePrice() Price {
|
||||
}
|
||||
|
||||
// RiseRate 涨跌比例/涨跌幅,第一个数据不准,仅做参考
|
||||
func (this *StockKline) RiseRate() float64 {
|
||||
func (this *Kline) RiseRate() float64 {
|
||||
return float64(this.RisePrice()) / float64(this.Open) * 100
|
||||
}
|
||||
|
||||
type stockKline struct{}
|
||||
type kline struct{}
|
||||
|
||||
func (stockKline) Frame(Type TypeKline, req *StockKlineReq) (*Frame, error) {
|
||||
func (kline) Frame(Type uint8, req KlineReq) (*Frame, error) {
|
||||
bs, err := req.Bytes(Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockKline,
|
||||
Type: TypeKline,
|
||||
Data: bs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (stockKline) Decode(bs []byte, Type TypeKline) (*StockKlineResp, error) {
|
||||
func (kline) Decode(bs []byte, Type uint8) (*KlineResp, error) {
|
||||
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &StockKlineResp{
|
||||
resp := &KlineResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ func (stockKline) Decode(bs []byte, Type TypeKline) (*StockKlineResp, error) {
|
||||
|
||||
var last Price //上条数据(昨天)的收盘价
|
||||
for i := uint16(0); i < resp.Count; i++ {
|
||||
k := &StockKline{
|
||||
k := &Kline{
|
||||
Time: GetTime([4]byte(bs[:4]), Type),
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type StockMinuteResp struct {
|
||||
type MinuteResp struct {
|
||||
Count uint16
|
||||
List []PriceNumber
|
||||
}
|
||||
@@ -14,9 +14,9 @@ type PriceNumber struct {
|
||||
Number int
|
||||
}
|
||||
|
||||
type stockMinute struct{}
|
||||
type minute struct{}
|
||||
|
||||
func (this *stockMinute) Frame(exchange Exchange, code string) (*Frame, error) {
|
||||
func (this *minute) Frame(exchange Exchange, code string) (*Frame, error) {
|
||||
if len(code) != 6 {
|
||||
return nil, errors.New("股票代码长度错误")
|
||||
}
|
||||
@@ -24,18 +24,18 @@ func (this *stockMinute) Frame(exchange Exchange, code string) (*Frame, error) {
|
||||
codeBs = append(codeBs, 0x0, 0x0, 0x0, 0x0)
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockMinute,
|
||||
Type: TypeMinute,
|
||||
Data: append([]byte{exchange.Uint8(), 0x0}, codeBs...),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *stockMinute) Decode(bs []byte) (*StockMinuteResp, error) {
|
||||
func (this *minute) Decode(bs []byte) (*MinuteResp, error) {
|
||||
|
||||
if len(bs) < 6 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &StockMinuteResp{
|
||||
resp := &MinuteResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
//2-6字节是啥?
|
||||
125
protocol/model_minute_trade.go
Normal file
125
protocol/model_minute_trade.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type MinuteTradeReq struct {
|
||||
Exchange Exchange
|
||||
Code string
|
||||
Start uint16
|
||||
Count uint16
|
||||
}
|
||||
|
||||
func (req MinuteTradeReq) Check() error {
|
||||
if len(req.Code) != 6 {
|
||||
return errors.New("股票代码长度错误")
|
||||
}
|
||||
if req.Count > 1800 {
|
||||
return errors.New("数量不能超过1800")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MinuteTradeResp struct {
|
||||
Count uint16
|
||||
List []*MinuteTrade
|
||||
}
|
||||
|
||||
// MinuteTrade 分时成交,todo 时间没有到秒,客户端上也没有,东方客户端能显示秒
|
||||
type MinuteTrade struct {
|
||||
Time string //时间
|
||||
Price Price //价格
|
||||
Volume int //成交量
|
||||
Number int //单数,历史数据改字段无效
|
||||
Status int //0是买,1是卖,2无效(汇总出现)
|
||||
}
|
||||
|
||||
func (this *MinuteTrade) String() string {
|
||||
return fmt.Sprintf("%s \t%-6s \t%-6s \t%-6d(手) \t%-4d(单) \t%-4s",
|
||||
this.Time, this.Price, this.Amount(), this.Volume, this.Number, this.StatusString())
|
||||
}
|
||||
|
||||
// Amount 成交额
|
||||
func (this *MinuteTrade) Amount() Price {
|
||||
return this.Price * Price(this.Volume) * 100
|
||||
}
|
||||
|
||||
func (this *MinuteTrade) StatusString() string {
|
||||
switch this.Status {
|
||||
case 0:
|
||||
return "买入"
|
||||
case 1:
|
||||
return "卖出"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// AvgVolume 平均每单成交量
|
||||
func (this *MinuteTrade) AvgVolume() float64 {
|
||||
return float64(this.Volume) / float64(this.Number)
|
||||
}
|
||||
|
||||
// AvgPrice 平均每单成交金额
|
||||
func (this *MinuteTrade) AvgPrice() Price {
|
||||
return Price(this.AvgVolume() * float64(this.Price) * 100)
|
||||
}
|
||||
|
||||
// IsBuy 是否是买单
|
||||
func (this *MinuteTrade) IsBuy() bool {
|
||||
return this.Status == 0
|
||||
}
|
||||
|
||||
// IsSell 是否是卖单
|
||||
func (this *MinuteTrade) IsSell() bool {
|
||||
return this.Status == 1
|
||||
}
|
||||
|
||||
type minuteTrade struct{}
|
||||
|
||||
func (minuteTrade) Frame(req MinuteTradeReq) (*Frame, error) {
|
||||
if err := req.Check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
codeBs := []byte(req.Code)
|
||||
codeBs = append(codeBs, Bytes(req.Start)...)
|
||||
codeBs = append(codeBs, Bytes(req.Count)...)
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeMinuteTrade,
|
||||
Data: append([]byte{req.Exchange.Uint8(), 0x0}, codeBs...),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (minuteTrade) Decode(bs []byte, code string) (*MinuteTradeResp, error) {
|
||||
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &MinuteTradeResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
|
||||
bs = bs[2:]
|
||||
|
||||
lastPrice := Price(0)
|
||||
for i := uint16(0); i < resp.Count; i++ {
|
||||
mt := &MinuteTrade{
|
||||
Time: GetHourMinute([2]byte(bs[:2])),
|
||||
}
|
||||
var sub Price
|
||||
bs, sub = GetPrice(bs[2:])
|
||||
lastPrice += sub
|
||||
mt.Price = lastPrice / basePrice(code)
|
||||
bs, mt.Volume = CutInt(bs)
|
||||
bs, mt.Number = CutInt(bs)
|
||||
bs, mt.Status = CutInt(bs)
|
||||
bs, _ = CutInt(bs) //这个得到的是0,不知道是啥
|
||||
resp.List = append(resp.List, mt)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type StockQuotesResp []*StockQuote
|
||||
type QuotesResp []*Quote
|
||||
|
||||
func (this StockQuotesResp) String() string {
|
||||
func (this QuotesResp) String() string {
|
||||
ls := []string(nil)
|
||||
for _, v := range this {
|
||||
ls = append(ls, v.String())
|
||||
@@ -16,7 +16,7 @@ func (this StockQuotesResp) String() string {
|
||||
return strings.Join(ls, "\n")
|
||||
}
|
||||
|
||||
type StockQuote struct {
|
||||
type Quote struct {
|
||||
Exchange Exchange // 市场
|
||||
Code string // 股票代码 6个ascii字符串
|
||||
Active1 uint16 // 活跃度
|
||||
@@ -45,7 +45,7 @@ type StockQuote struct {
|
||||
Active2 uint16 // 活跃度
|
||||
}
|
||||
|
||||
func (this *StockQuote) String() string {
|
||||
func (this *Quote) String() string {
|
||||
return fmt.Sprintf(`%s%s
|
||||
%s
|
||||
总量:%s, 现量:%s, 总金额:%s, 内盘:%s, 外盘:%s
|
||||
@@ -58,12 +58,12 @@ func (this *StockQuote) String() string {
|
||||
)
|
||||
}
|
||||
|
||||
type stockQuote struct{}
|
||||
type quote struct{}
|
||||
|
||||
func (this stockQuote) Frame(m map[Exchange]string) (*Frame, error) {
|
||||
func (this quote) Frame(m map[Exchange]string) (*Frame, error) {
|
||||
f := &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockQuote,
|
||||
Type: TypeQuote,
|
||||
Data: []byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
}
|
||||
|
||||
@@ -105,11 +105,11 @@ b212 昨天收盘价1186
|
||||
8defd10c 服务时间
|
||||
c005bed2668e05be15804d8ba12cb3b13a0083c3034100badc029d014201bc990384f70443029da503b7af074403a6e501b9db044504a6e2028dd5048d050000000000005909
|
||||
*/
|
||||
func (this stockQuote) Decode(bs []byte) StockQuotesResp {
|
||||
func (this quote) Decode(bs []byte) QuotesResp {
|
||||
|
||||
//logs.Debug(hex.EncodeToString(bs))
|
||||
|
||||
resp := StockQuotesResp{}
|
||||
resp := QuotesResp{}
|
||||
|
||||
//前2字节是什么?
|
||||
bs = bs[2:]
|
||||
@@ -118,7 +118,7 @@ func (this stockQuote) Decode(bs []byte) StockQuotesResp {
|
||||
bs = bs[2:]
|
||||
|
||||
for i := uint16(0); i < number; i++ {
|
||||
sec := &StockQuote{
|
||||
sec := &Quote{
|
||||
Exchange: Exchange(bs[0]),
|
||||
Code: string(UTF8ToGBK(bs[1:7])),
|
||||
Active1: Uint16(bs[7:9]),
|
||||
@@ -1,66 +0,0 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/injoyai/conv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StockHistoryMinuteTradeResp 历史分时交易比实时少了单量
|
||||
type StockHistoryMinuteTradeResp struct {
|
||||
Count uint16
|
||||
List []*StockMinuteTrade
|
||||
}
|
||||
|
||||
type StockHistoryMinuteTrade struct {
|
||||
Time string //时间
|
||||
Price Price //价格
|
||||
Volume int //成交量
|
||||
Status int //0是买,1是卖,2无效(汇总出现)
|
||||
}
|
||||
|
||||
type stockHistoryMinuteTrade struct{}
|
||||
|
||||
func (stockHistoryMinuteTrade) Frame(t time.Time, exchange Exchange, code string, start, count uint16) (*Frame, error) {
|
||||
date := conv.Uint32(t.Format("20060102"))
|
||||
dataBs := Bytes(date)
|
||||
dataBs = append(dataBs, exchange.Uint8(), 0x0)
|
||||
dataBs = append(dataBs, []byte(code)...)
|
||||
dataBs = append(dataBs, Bytes(start)...)
|
||||
dataBs = append(dataBs, Bytes(count)...)
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockHistoryMinuteTrade,
|
||||
Data: dataBs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (stockHistoryMinuteTrade) Decode(bs []byte, code string) (*StockHistoryMinuteTradeResp, error) {
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &StockHistoryMinuteTradeResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
|
||||
//第2-6字节不知道是啥
|
||||
bs = bs[2+4:]
|
||||
|
||||
lastPrice := Price(0)
|
||||
for i := uint16(0); i < resp.Count; i++ {
|
||||
mt := &StockMinuteTrade{
|
||||
Time: GetHourMinute([2]byte(bs[:2])),
|
||||
}
|
||||
var sub Price
|
||||
bs, sub = GetPrice(bs[2:])
|
||||
lastPrice += sub
|
||||
mt.Price = lastPrice / basePrice(code)
|
||||
bs, mt.Volume = CutInt(bs)
|
||||
bs, mt.Status = CutInt(bs)
|
||||
bs, _ = CutInt(bs) //这个得到的是0,不知道是啥
|
||||
resp.List = append(resp.List, mt)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type StockMinuteTradeResp struct {
|
||||
Count uint16
|
||||
List []*StockMinuteTrade
|
||||
}
|
||||
|
||||
// StockMinuteTrade 分时成交,todo 时间没有到秒,客户端上也没有,东方客户端能显示秒
|
||||
type StockMinuteTrade struct {
|
||||
Time string //时间
|
||||
Price Price //价格
|
||||
Volume int //成交量
|
||||
Number int //单数
|
||||
Status int //0是买,1是卖,2无效(汇总出现)
|
||||
}
|
||||
|
||||
func (this *StockMinuteTrade) String() string {
|
||||
return fmt.Sprintf("%s \t%s \t%-6s \t%-6d(手) \t%-4d(单) \t%-4s", this.Time, this.Price, this.Amount(), this.Volume, this.Number, this.StatusString())
|
||||
}
|
||||
|
||||
// Amount 成交额
|
||||
func (this *StockMinuteTrade) Amount() Price {
|
||||
return this.Price * Price(this.Volume) * 100
|
||||
}
|
||||
|
||||
func (this *StockMinuteTrade) StatusString() string {
|
||||
switch this.Status {
|
||||
case 0:
|
||||
return "买入"
|
||||
case 1:
|
||||
return "卖出"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// AvgVolume 平均每单成交量
|
||||
func (this *StockMinuteTrade) AvgVolume() float64 {
|
||||
return float64(this.Volume) / float64(this.Number)
|
||||
}
|
||||
|
||||
// AvgPrice 平均每单成交金额
|
||||
func (this *StockMinuteTrade) AvgPrice() Price {
|
||||
return Price(this.AvgVolume() * float64(this.Price) * 100)
|
||||
}
|
||||
|
||||
// IsBuy 是否是买单
|
||||
func (this *StockMinuteTrade) IsBuy() bool {
|
||||
return this.Status == 0
|
||||
}
|
||||
|
||||
// IsSell 是否是卖单
|
||||
func (this *StockMinuteTrade) IsSell() bool {
|
||||
return this.Status == 1
|
||||
}
|
||||
|
||||
type stockMinuteTrade struct{}
|
||||
|
||||
func (stockMinuteTrade) Frame(exchange Exchange, code string, start, count uint16) (*Frame, error) {
|
||||
if len(code) != 6 {
|
||||
return nil, errors.New("股票代码长度错误")
|
||||
}
|
||||
codeBs := []byte(code)
|
||||
codeBs = append(codeBs, Bytes(start)...)
|
||||
codeBs = append(codeBs, Bytes(count)...)
|
||||
return &Frame{
|
||||
Control: Control01,
|
||||
Type: TypeStockMinuteTrade,
|
||||
Data: append([]byte{exchange.Uint8(), 0x0}, codeBs...),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (stockMinuteTrade) Decode(bs []byte, code string) (*StockMinuteTradeResp, error) {
|
||||
|
||||
if len(bs) < 2 {
|
||||
return nil, errors.New("数据长度不足")
|
||||
}
|
||||
|
||||
resp := &StockMinuteTradeResp{
|
||||
Count: Uint16(bs[:2]),
|
||||
}
|
||||
|
||||
bs = bs[2:]
|
||||
|
||||
lastPrice := Price(0)
|
||||
for i := uint16(0); i < resp.Count; i++ {
|
||||
mt := &StockMinuteTrade{
|
||||
Time: GetHourMinute([2]byte(bs[:2])),
|
||||
}
|
||||
var sub Price
|
||||
bs, sub = GetPrice(bs[2:])
|
||||
lastPrice += sub
|
||||
mt.Price = lastPrice / basePrice(code)
|
||||
bs, mt.Volume = CutInt(bs)
|
||||
bs, mt.Number = CutInt(bs)
|
||||
bs, mt.Status = CutInt(bs)
|
||||
bs, _ = CutInt(bs) //这个得到的是0,不知道是啥
|
||||
resp.List = append(resp.List, mt)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -81,7 +81,7 @@ func GetHourMinute(bs [2]byte) string {
|
||||
return fmt.Sprintf("%02d:%02d", h, m)
|
||||
}
|
||||
|
||||
func GetTime(bs [4]byte, Type TypeKline) time.Time {
|
||||
func GetTime(bs [4]byte, Type uint8) time.Time {
|
||||
switch Type {
|
||||
case TypeKlineDay2, TypeKlineMinute, TypeKlineMinute2:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user