From db7f1a760fd9af9eeb71153ad9768d5a5d968cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=B1=E7=BA=AF=E5=87=80?= <1113655791@qq.com> Date: Sat, 15 Mar 2025 15:05:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8E=86=E5=8F=B2=E5=88=86?= =?UTF-8?q?=E6=97=B6=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client.go | 36 +++++++++++++++++- protocol/model_history_minute.go | 64 ++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 protocol/model_history_minute.go diff --git a/client.go b/client.go index 11f30a8..6186783 100644 --- a/client.go +++ b/client.go @@ -133,6 +133,9 @@ func (this *Client) handlerDealMessage(c *client.Client, msg ios.Acker) { case protocol.TypeMinute: resp, err = protocol.MMinute.Decode(f.Data) + case protocol.TypeHistoryMinute: + resp, err = protocol.MHistoryMinute.Decode(f.Data) + case protocol.TypeMinuteTrade: resp, err = protocol.MMinuteTrade.Decode(f.Data, conv.String(val)) @@ -223,8 +226,10 @@ func (this *Client) GetQuote(codes ...string) (protocol.QuotesResp, error) { return result.(protocol.QuotesResp), nil } -// GetMinute 获取分时数据,todo 解析好像不对 +// GetMinute 获取分时数据,todo 解析好像不对,先用历史数据 func (this *Client) GetMinute(code string) (*protocol.MinuteResp, error) { + return this.GetHistoryMinute(time.Now().Format("20060102"), code) + f, err := protocol.MMinute.Frame(code) if err != nil { return nil, err @@ -236,6 +241,19 @@ func (this *Client) GetMinute(code string) (*protocol.MinuteResp, error) { return result.(*protocol.MinuteResp), nil } +// GetHistoryMinute 获取历史分时数据 +func (this *Client) GetHistoryMinute(date, code string) (*protocol.MinuteResp, error) { + f, err := protocol.MHistoryMinute.Frame(date, code) + if err != nil { + return nil, err + } + result, err := this.SendFrame(f) + if err != nil { + return nil, err + } + return result.(*protocol.MinuteResp), nil +} + // GetMinuteTrade 获取分时交易详情,服务器最多返回1800条,count-start<=1800 func (this *Client) GetMinuteTrade(code string, start, count uint16) (*protocol.MinuteTradeResp, error) { code = protocol.AddPrefix(code) @@ -304,6 +322,20 @@ func (this *Client) GetHistoryMinuteTradeAll(date, code string) (*protocol.Histo return resp, nil } +// GetIndex 获取指数,接口是和k线一样的,但是解析不知道怎么区分(解析方式不一致),所以加一个方法 +func (this *Client) GetIndex(Type uint8, code string, start, count uint16) (*protocol.KlineResp, error) { + code = protocol.AddPrefix(code) + f, err := protocol.MKline.Frame(Type, code, start, count) + if err != nil { + return nil, err + } + result, err := this.SendFrame(f, protocol.KlineCache{Type: Type, Kind: protocol.KindIndex}) + if err != nil { + return nil, err + } + return result.(*protocol.KlineResp), nil +} + // GetKline 获取k线数据,推荐收盘之后获取,否则会获取到当天的数据 func (this *Client) GetKline(Type uint8, code string, start, count uint16) (*protocol.KlineResp, error) { code = protocol.AddPrefix(code) @@ -311,7 +343,7 @@ func (this *Client) GetKline(Type uint8, code string, start, count uint16) (*pro if err != nil { return nil, err } - result, err := this.SendFrame(f, protocol.KlineCache{Type: Type, Code: code}) + result, err := this.SendFrame(f, protocol.KlineCache{Type: Type, Kind: protocol.KindStock}) if err != nil { return nil, err } diff --git a/protocol/model_history_minute.go b/protocol/model_history_minute.go new file mode 100644 index 0000000..c29288a --- /dev/null +++ b/protocol/model_history_minute.go @@ -0,0 +1,64 @@ +package protocol + +import ( + "errors" + "github.com/injoyai/conv" + "time" +) + +type historyMinute struct{} + +func (this historyMinute) Frame(date, code string) (*Frame, error) { + exchange, number, err := DecodeCode(code) + if err != nil { + return nil, err + } + dataBs := Bytes(conv.Uint32(date)) + dataBs = append(dataBs, exchange.Uint8()) + dataBs = append(dataBs, []byte(number)...) + return &Frame{ + Control: Control01, + Type: TypeHistoryMinute, + Data: dataBs, + }, nil +} + +func (this historyMinute) Decode(bs []byte) (*MinuteResp, error) { + + if len(bs) < 6 { + return nil, errors.New("数据长度不足") + } + + resp := &MinuteResp{ + Count: Uint16(bs[:2]), + } + + multiple := Price(1) + if bs[5] > 0x40 { + multiple = 10 + } + + //2-4字节是啥? + bs = bs[6:] + + lastPrice := Price(0) + t := time.Date(0, 0, 0, 9, 30, 0, 0, time.Local) + for i := uint16(0); i < resp.Count; i++ { + var price Price + bs, price = GetPrice(bs) + bs, _ = GetPrice(bs) //这个是什么 + lastPrice += price + var number int + bs, number = CutInt(bs) + + if i == 120 { + t = t.Add(time.Minute * 90) + } + resp.List = append(resp.List, PriceNumber{ + Time: t.Add(time.Minute * time.Duration(i+1)).Format("15:04"), + Price: lastPrice * multiple, + Number: number, + }) + } + return resp, nil +}