吧代码的传参方式从sz,000001改成sz000001

This commit is contained in:
钱纯净
2024-11-05 00:18:20 +08:00
parent 39057e5305
commit c90adef204
15 changed files with 84 additions and 139 deletions

View File

@@ -191,8 +191,8 @@ func (this *Client) GetCodeAll(exchange protocol.Exchange) (*protocol.CodeResp,
} }
// GetQuote 获取盘口五档报价 // GetQuote 获取盘口五档报价
func (this *Client) GetQuote(m map[protocol.Exchange]string) (protocol.QuotesResp, error) { func (this *Client) GetQuote(codes ...string) (protocol.QuotesResp, error) {
f, err := protocol.MQuote.Frame(m) f, err := protocol.MQuote.Frame(codes...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -204,8 +204,8 @@ func (this *Client) GetQuote(m map[protocol.Exchange]string) (protocol.QuotesRes
} }
// GetMinute 获取分时数据,todo 解析好像不对 // GetMinute 获取分时数据,todo 解析好像不对
func (this *Client) GetMinute(exchange protocol.Exchange, code string) (*protocol.MinuteResp, error) { func (this *Client) GetMinute(code string) (*protocol.MinuteResp, error) {
f, err := protocol.MMinute.Frame(exchange, code) f, err := protocol.MMinute.Frame(code)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -217,12 +217,12 @@ func (this *Client) GetMinute(exchange protocol.Exchange, code string) (*protoco
} }
// GetMinuteTrade 获取分时交易详情,服务器最多返回1800条,count-start<=1800 // GetMinuteTrade 获取分时交易详情,服务器最多返回1800条,count-start<=1800
func (this *Client) GetMinuteTrade(req protocol.MinuteTradeReq) (*protocol.MinuteTradeResp, error) { func (this *Client) GetMinuteTrade(code string, start, count uint16) (*protocol.MinuteTradeResp, error) {
f, err := protocol.MMinuteTrade.Frame(req) f, err := protocol.MMinuteTrade.Frame(code, start, count)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result, err := this.SendFrame(f, req.Code) result, err := this.SendFrame(f, code)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -230,16 +230,11 @@ func (this *Client) GetMinuteTrade(req protocol.MinuteTradeReq) (*protocol.Minut
} }
// GetMinuteTradeAll 获取分时全部交易详情,todo 只做参考 因为交易实时在进行,然后又是分页读取的,所以会出现读取间隔内产生的交易会丢失 // GetMinuteTradeAll 获取分时全部交易详情,todo 只做参考 因为交易实时在进行,然后又是分页读取的,所以会出现读取间隔内产生的交易会丢失
func (this *Client) GetMinuteTradeAll(exchange protocol.Exchange, code string) (*protocol.MinuteTradeResp, error) { func (this *Client) GetMinuteTradeAll(code string) (*protocol.MinuteTradeResp, error) {
resp := &protocol.MinuteTradeResp{} resp := &protocol.MinuteTradeResp{}
size := uint16(1800) size := uint16(1800)
for start := uint16(0); ; start += size { for start := uint16(0); ; start += size {
r, err := this.GetMinuteTrade(protocol.MinuteTradeReq{ r, err := this.GetMinuteTrade(code, start, size)
Exchange: exchange,
Code: code,
Start: start,
Count: size,
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -254,12 +249,12 @@ func (this *Client) GetMinuteTradeAll(exchange protocol.Exchange, code string) (
} }
// GetHistoryMinuteTrade 获取历史分时交易,,只能获取昨天及之前的数据,服务器最多返回2000条,count-start<=2000,如果日期输入错误,则返回0 // GetHistoryMinuteTrade 获取历史分时交易,,只能获取昨天及之前的数据,服务器最多返回2000条,count-start<=2000,如果日期输入错误,则返回0
func (this *Client) GetHistoryMinuteTrade(req protocol.HistoryMinuteTradeReq) (*protocol.HistoryMinuteTradeResp, error) { func (this *Client) GetHistoryMinuteTrade(date, code string, start, count uint16) (*protocol.HistoryMinuteTradeResp, error) {
f, err := protocol.MHistoryMinuteTrade.Frame(req) f, err := protocol.MHistoryMinuteTrade.Frame(date, code, start, count)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result, err := this.SendFrame(f, req.Code) result, err := this.SendFrame(f, code)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -267,17 +262,11 @@ func (this *Client) GetHistoryMinuteTrade(req protocol.HistoryMinuteTradeReq) (*
} }
// GetHistoryMinuteTradeAll 获取历史分时全部交易,通过多次请求来拼接,只能获取昨天及之前的数据 // GetHistoryMinuteTradeAll 获取历史分时全部交易,通过多次请求来拼接,只能获取昨天及之前的数据
func (this *Client) GetHistoryMinuteTradeAll(req protocol.HistoryMinuteTradeAllReq) (*protocol.HistoryMinuteTradeResp, error) { func (this *Client) GetHistoryMinuteTradeAll(date, code string) (*protocol.HistoryMinuteTradeResp, error) {
resp := &protocol.HistoryMinuteTradeResp{} resp := &protocol.HistoryMinuteTradeResp{}
size := uint16(2000) size := uint16(2000)
for start := uint16(0); ; start += size { for start := uint16(0); ; start += size {
r, err := this.GetHistoryMinuteTrade(protocol.HistoryMinuteTradeReq{ r, err := this.GetHistoryMinuteTrade(date, code, start, size)
Date: req.Date,
Exchange: req.Exchange,
Code: req.Code,
Start: start,
Count: size,
})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -2,7 +2,6 @@ package tdx
import ( import (
"github.com/injoyai/logs" "github.com/injoyai/logs"
"github.com/injoyai/tdx/protocol"
"testing" "testing"
) )
@@ -23,13 +22,7 @@ func init() {
func TestClient_GetStockHistoryMinuteTrade(t *testing.T) { func TestClient_GetStockHistoryMinuteTrade(t *testing.T) {
do(func(c *Client) { do(func(c *Client) {
resp, err := c.GetHistoryMinuteTrade(protocol.HistoryMinuteTradeReq{ resp, err := c.GetHistoryMinuteTrade("20241028", "sz000001", 0, 100)
Date: "20241028",
Exchange: protocol.ExchangeSZ,
Code: "000001",
Start: 0,
Count: 100,
})
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return

View File

@@ -4,17 +4,11 @@ import (
"github.com/injoyai/logs" "github.com/injoyai/logs"
"github.com/injoyai/tdx" "github.com/injoyai/tdx"
"github.com/injoyai/tdx/example/common" "github.com/injoyai/tdx/example/common"
"github.com/injoyai/tdx/protocol"
) )
func main() { func main() {
common.Test(func(c *tdx.Client) { common.Test(func(c *tdx.Client) {
resp, err := c.GetHistoryMinuteTrade(protocol.HistoryMinuteTradeReq{ resp, err := c.GetHistoryMinuteTrade("20241025", "sz000001", 0, 20)
Date: "20241027",
Exchange: protocol.ExchangeSZ,
Code: "000001",
Count: 10,
})
logs.PanicErr(err) logs.PanicErr(err)
for _, v := range resp.List { for _, v := range resp.List {

View File

@@ -4,16 +4,11 @@ import (
"github.com/injoyai/logs" "github.com/injoyai/logs"
"github.com/injoyai/tdx" "github.com/injoyai/tdx"
"github.com/injoyai/tdx/example/common" "github.com/injoyai/tdx/example/common"
"github.com/injoyai/tdx/protocol"
) )
func main() { func main() {
common.Test(func(c *tdx.Client) { common.Test(func(c *tdx.Client) {
resp, err := c.GetHistoryMinuteTradeAll(protocol.HistoryMinuteTradeAllReq{ resp, err := c.GetHistoryMinuteTradeAll("20241025", "sz000001")
Date: "20241027",
Exchange: protocol.ExchangeSZ,
Code: "000001",
})
logs.PanicErr(err) logs.PanicErr(err)
for _, v := range resp.List { for _, v := range resp.List {

View File

@@ -3,14 +3,13 @@ package main
import ( import (
"github.com/injoyai/logs" "github.com/injoyai/logs"
"github.com/injoyai/tdx" "github.com/injoyai/tdx"
"github.com/injoyai/tdx/protocol"
) )
func main() { func main() {
c, err := tdx.Dial("124.71.187.122:7709") c, err := tdx.Dial("124.71.187.122:7709", tdx.WithDebug())
logs.PanicErr(err) logs.PanicErr(err)
resp, err := c.GetMinute(protocol.ExchangeSH, "000001") resp, err := c.GetMinute("sz000001")
logs.PanicErr(err) logs.PanicErr(err)
for _, v := range resp.List { for _, v := range resp.List {

View File

@@ -4,18 +4,12 @@ import (
"github.com/injoyai/logs" "github.com/injoyai/logs"
"github.com/injoyai/tdx" "github.com/injoyai/tdx"
"github.com/injoyai/tdx/example/common" "github.com/injoyai/tdx/example/common"
"github.com/injoyai/tdx/protocol"
) )
func main() { func main() {
common.Test(func(c *tdx.Client) { common.Test(func(c *tdx.Client) {
resp, err := c.GetMinuteTrade(protocol.MinuteTradeReq{ resp, err := c.GetMinuteTrade("sz000001", 0, 100)
Exchange: protocol.ExchangeSZ,
Code: "000001",
Start: 0,
Count: 100,
})
logs.PanicErr(err) logs.PanicErr(err)
for _, v := range resp.List { for _, v := range resp.List {

View File

@@ -3,12 +3,11 @@ package main
import ( import (
"github.com/injoyai/logs" "github.com/injoyai/logs"
"github.com/injoyai/tdx" "github.com/injoyai/tdx"
"github.com/injoyai/tdx/protocol"
) )
func main() { func main() {
c, err := tdx.Dial("124.71.187.122:7709") c, err := tdx.Dial("124.71.187.122:7709", tdx.WithDebug())
logs.PanicErr(err) logs.PanicErr(err)
_ = c _ = c
@@ -16,19 +15,17 @@ func main() {
/* /*
发送: 发送:
0c02000000011a001a003e05050000000000000002000030303030303101363030303038 0c02000000011a001a003e05050000000000000002000030303030303101363030303038
0c01000000011a001a003e05050000000000000002000030303030303101363030303038
接收: 接收:
b1cb74001c00000000000d005100bd00789c6378c1cecb252ace6066c5b4898987b9050ed1f90cc5b74c18a5bc18c1b43490fecff09c81819191f13fc3c9f3bb169f5e7dfefeb5ef57f7199a305009308208e5b32bb6bcbf70148712002d7f1e13 b1cb74001c00000000000d005100bd00789c6378c1cecb252ace6066c5b4898987b9050ed1f90cc5b74c18a5bc18c1b43490fecff09c81819191f13fc3c9f3bb169f5e7dfefeb5ef57f7199a305009308208e5b32bb6bcbf70148712002d7f1e13
b1cb74000c02000000003e05ac00ac000102020000303030303031601294121a1c2d4eadabcf0ed412aae5fc01afb0024561124fbcc08301afa47900b2e3174100bf68871a4201b741b6144302bb09af334403972e96354504ac09b619560e00000000f8ff601201363030303038b60fba04060607429788a70efa04ada37ab2531c12974d91e7449dbc354184b6010001844bad324102b5679ea1014203a65abd8d0143048a6ba4dd01440587e101b3d2029613000000000000b60f b1cb74000c02000000003e05ac00ac000102020000303030303031601294121a1c2d4eadabcf0ed412aae5fc01afb0024561124fbcc08301afa47900b2e3174100bf68871a4201b741b6144302bb09af334403972e96354504ac09b619560e00000000f8ff601201363030303038b60fba04060607429788a70efa04ada37ab2531c12974d91e7449dbc354184b6010001844bad324102b5679ea1014203a65abd8d0143048a6ba4dd01440587e101b3d2029613000000000000b60f
*/ */
resp, err := c.GetQuote(map[protocol.Exchange]string{ resp, err := c.GetQuote("sz000001", "sh600008")
protocol.ExchangeSZ: "000001",
protocol.ExchangeSH: "600008",
})
logs.PanicErr(err) logs.PanicErr(err)
for _, v := range resp { for _, v := range resp {
logs.Debugf("%#v\n", v) logs.Debug(v)
} }
select {} select {}

View File

@@ -6,7 +6,7 @@ import (
) )
func Test(f func(c *tdx.Client)) { func Test(f func(c *tdx.Client)) {
c, err := tdx.Dial("124.71.187.122:7709") c, err := tdx.Dial("124.71.187.122:7709", tdx.WithDebug())
logs.PanicErr(err) logs.PanicErr(err)
f(c) f(c)
<-c.Done() <-c.Done()

View File

@@ -84,7 +84,7 @@ func Decode(bs []byte) (*Response, error) {
} }
if resp.Control&0x10 != 0x10 { if resp.Control&0x10 != 0x10 {
return nil, fmt.Errorf("请求失败,请检查参数") //return nil, fmt.Errorf("请求失败,请检查参数")
} }
if int(resp.ZipLength) != len(bs[16:]) { if int(resp.ZipLength) != len(bs[16:]) {

View File

@@ -6,29 +6,6 @@ import (
"github.com/injoyai/conv" "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 历史分时交易比实时少了单量 // HistoryMinuteTradeResp 历史分时交易比实时少了单量
type HistoryMinuteTradeResp struct { type HistoryMinuteTradeResp struct {
Count uint16 Count uint16
@@ -64,16 +41,16 @@ func (this *HistoryMinuteTrade) StatusString() string {
type historyMinuteTrade struct{} type historyMinuteTrade struct{}
func (historyMinuteTrade) Frame(req HistoryMinuteTradeReq) (*Frame, error) { func (historyMinuteTrade) Frame(date, code string, start, count uint16) (*Frame, error) {
if err := req.Check(); err != nil { exchange, number, err := DecodeCode(code)
if err != nil {
return nil, err return nil, err
} }
date := conv.Uint32(req.Date) //req.Time.Format("20060102")) dataBs := Bytes(conv.Uint32(date)) //req.Time.Format("20060102"))
dataBs := Bytes(date) dataBs = append(dataBs, exchange.Uint8(), 0x0)
dataBs = append(dataBs, req.Exchange.Uint8(), 0x0) dataBs = append(dataBs, []byte(number)...)
dataBs = append(dataBs, []byte(req.Code)...) dataBs = append(dataBs, Bytes(start)...)
dataBs = append(dataBs, Bytes(req.Start)...) dataBs = append(dataBs, Bytes(count)...)
dataBs = append(dataBs, Bytes(req.Count)...)
return &Frame{ return &Frame{
Control: Control01, Control: Control01,
Type: TypeHistoryMinuteTrade, Type: TypeHistoryMinuteTrade,
@@ -86,6 +63,11 @@ func (historyMinuteTrade) Decode(bs []byte, code string) (*HistoryMinuteTradeRes
return nil, errors.New("数据长度不足") return nil, errors.New("数据长度不足")
} }
_, number, err := DecodeCode(code)
if err != nil {
return nil, err
}
resp := &HistoryMinuteTradeResp{ resp := &HistoryMinuteTradeResp{
Count: Uint16(bs[:2]), Count: Uint16(bs[:2]),
} }
@@ -101,7 +83,7 @@ func (historyMinuteTrade) Decode(bs []byte, code string) (*HistoryMinuteTradeRes
var sub Price var sub Price
bs, sub = GetPrice(bs[2:]) bs, sub = GetPrice(bs[2:])
lastPrice += sub lastPrice += sub
mt.Price = lastPrice / basePrice(code) mt.Price = lastPrice / basePrice(number)
bs, mt.Volume = CutInt(bs) bs, mt.Volume = CutInt(bs)
bs, mt.Status = CutInt(bs) bs, mt.Status = CutInt(bs)
bs, _ = CutInt(bs) //这个得到的是0不知道是啥 bs, _ = CutInt(bs) //这个得到的是0不知道是啥

View File

@@ -7,13 +7,7 @@ import (
func Test_stockHistoryMinuteTrade_Frame(t *testing.T) { func Test_stockHistoryMinuteTrade_Frame(t *testing.T) {
// 预期 0c 02000000 00 1200 1200 b50f 84da3401 0000 30303030303100006400 // 预期 0c 02000000 00 1200 1200 b50f 84da3401 0000 30303030303100006400
// 0c000000000112001200b50f84da3401000030303030303100006400 // 0c000000000112001200b50f84da3401000030303030303100006400
f, err := MHistoryMinuteTrade.Frame(HistoryMinuteTradeReq{ f, err := MHistoryMinuteTrade.Frame("20241028", "sz000001", 0, 100)
Date: "20241028",
Exchange: ExchangeSZ,
Code: "000001",
Start: 0,
Count: 100,
})
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return

View File

@@ -16,11 +16,12 @@ type PriceNumber struct {
type minute struct{} type minute struct{}
func (this *minute) Frame(exchange Exchange, code string) (*Frame, error) { func (this *minute) Frame(code string) (*Frame, error) {
if len(code) != 6 { exchange, number, err := DecodeCode(code)
return nil, errors.New("股票代码长度错误") if err != nil {
return nil, err
} }
codeBs := []byte(code) codeBs := []byte(number)
codeBs = append(codeBs, 0x0, 0x0, 0x0, 0x0) codeBs = append(codeBs, 0x0, 0x0, 0x0, 0x0)
return &Frame{ return &Frame{
Control: Control01, Control: Control01,

View File

@@ -5,23 +5,6 @@ import (
"fmt" "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 { type MinuteTradeResp struct {
Count uint16 Count uint16
List []*MinuteTrade List []*MinuteTrade
@@ -79,22 +62,30 @@ func (this *MinuteTrade) IsSell() bool {
type minuteTrade struct{} type minuteTrade struct{}
func (minuteTrade) Frame(req MinuteTradeReq) (*Frame, error) { func (minuteTrade) Frame(code string, start, count uint16) (*Frame, error) {
if err := req.Check(); err != nil { exchange, number, err := DecodeCode(code)
if err != nil {
return nil, err return nil, err
} }
codeBs := []byte(req.Code)
codeBs = append(codeBs, Bytes(req.Start)...) codeBs := []byte(number)
codeBs = append(codeBs, Bytes(req.Count)...) codeBs = append(codeBs, Bytes(start)...)
codeBs = append(codeBs, Bytes(count)...)
return &Frame{ return &Frame{
Control: Control01, Control: Control01,
Type: TypeMinuteTrade, Type: TypeMinuteTrade,
Data: append([]byte{req.Exchange.Uint8(), 0x0}, codeBs...), Data: append([]byte{exchange.Uint8(), 0x0}, codeBs...),
}, nil }, nil
} }
func (minuteTrade) Decode(bs []byte, code string) (*MinuteTradeResp, error) { func (minuteTrade) Decode(bs []byte, code string) (*MinuteTradeResp, error) {
var err error
_, code, err = DecodeCode(code)
if err != nil {
return nil, err
}
if len(bs) < 2 { if len(bs) < 2 {
return nil, errors.New("数据长度不足") return nil, errors.New("数据长度不足")
} }

View File

@@ -1,7 +1,6 @@
package protocol package protocol
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
) )
@@ -60,20 +59,22 @@ func (this *Quote) String() string {
type quote struct{} type quote struct{}
func (this quote) Frame(m map[Exchange]string) (*Frame, error) { func (this quote) Frame(codes ...string) (*Frame, error) {
f := &Frame{ f := &Frame{
Control: Control01, Control: Control01,
Type: TypeQuote, Type: TypeQuote,
Data: []byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, Data: []byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
} }
payload := Bytes(uint16(len(m))) payload := Bytes(uint16(len(codes)))
for k, v := range m { for _, v := range codes {
if len(v) != 6 { exchange, code, err := DecodeCode(v)
return nil, errors.New("股票代码长度错误") if err != nil {
return nil, err
} }
payload = append(payload, k.Uint8())
payload = append(payload, v...) payload = append(payload, exchange.Uint8())
payload = append(payload, code...)
} }
f.Data = append(f.Data, payload...) f.Data = append(f.Data, payload...)

View File

@@ -9,6 +9,7 @@ import (
"golang.org/x/text/transform" "golang.org/x/text/transform"
"io" "io"
"math" "math"
"strings"
"time" "time"
) )
@@ -48,6 +49,20 @@ func UTF8ToGBK(text []byte) []byte {
return bytes.ReplaceAll(content, []byte{0x00}, []byte{}) return bytes.ReplaceAll(content, []byte{0x00}, []byte{})
} }
func DecodeCode(code string) (Exchange, string, error) {
if len(code) != 8 {
return 0, "", fmt.Errorf("股票代码长度错误,例如:SZ000001")
}
switch strings.ToLower(code[:2]) {
case ExchangeSH.String():
return ExchangeSH, code[2:], nil
case ExchangeSZ.String():
return ExchangeSZ, code[2:], nil
default:
return 0, "", fmt.Errorf("股票代码错误,例如:SZ000001")
}
}
func FloatUnit(f float64) (float64, string) { func FloatUnit(f float64) (float64, string) {
m := []string{"万", "亿"} m := []string{"万", "亿"}
unit := "" unit := ""