mirror of
https://github.com/injoyai/tdx.git
synced 2025-11-26 21:25:35 +08:00
增加分时成交函数,数据已经校对,和通达信和东方财富能对应上
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
|
||||
|
||||
### 开发进度
|
||||
* 能通讯,有响应数据,还未解析响应数据
|
||||

|
||||
* 基本信息(5档报价)
|
||||

|
||||
* 基本信息(股票列表)
|
||||

|
||||
* 股票列表
|
||||

|
||||
* 分时成交
|
||||

|
||||
16
client.go
16
client.go
@@ -82,6 +82,9 @@ func (this *Client) handlerDealMessage(c *client.Client, msg ios.Acker) {
|
||||
case protocol.TypeStockMinute:
|
||||
resp, err = protocol.MStockMinute.Decode(f.Data)
|
||||
|
||||
case protocol.TypeStockMinuteTrade:
|
||||
resp, err = protocol.MStockMinuteTrade.Decode(f.Data, "") //todo
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -162,3 +165,16 @@ func (this *Client) GetStockMinute(exchange protocol.Exchange, code string) (*pr
|
||||
}
|
||||
return result.(*protocol.StockMinuteResp), nil
|
||||
}
|
||||
|
||||
// GetStockMinuteTrade 获取分时交易详情
|
||||
func (this *Client) GetStockMinuteTrade(exchange protocol.Exchange, code string, start, count uint16) (*protocol.StockMinuteTradeResp, error) {
|
||||
f, err := protocol.MStockMinuteTrade.Frame(exchange, code, start, count)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := this.SendFrame(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*protocol.StockMinuteTradeResp), nil
|
||||
}
|
||||
|
||||
45
const.go
45
const.go
@@ -1,45 +0,0 @@
|
||||
package tdx
|
||||
|
||||
const (
|
||||
MarketSH = 0 // 上海
|
||||
MarketSZ = 1 // 深圳
|
||||
MarketBJ = 2 // 北京
|
||||
)
|
||||
|
||||
const (
|
||||
KMSG_CMD1 = 0x000d // 建立链接
|
||||
KMSG_CMD2 = 0x0fdb // 建立链接
|
||||
KMSG_PING = 0x0015 // 测试连接
|
||||
KMSG_HEARTBEAT = 0xFFFF // 心跳(自定义)
|
||||
KMSG_SECURITYCOUNT = 0x044e // 证券数量
|
||||
KMSG_BLOCKINFOMETA = 0x02c5 // 板块文件信息
|
||||
KMSG_BLOCKINFO = 0x06b9 // 板块文件
|
||||
KMSG_COMPANYCATEGORY = 0x02cf // 公司信息文件信息
|
||||
KMSG_COMPANYCONTENT = 0x02d0 // 公司信息描述
|
||||
KMSG_FINANCEINFO = 0x0010 // 财务信息
|
||||
KMSG_HISTORYMINUTETIMEDATE = 0x0fb4 // 历史分时信息
|
||||
KMSG_HISTORYTRANSACTIONDATA = 0x0fb5 // 历史分笔成交信息
|
||||
KMSG_INDEXBARS = 0x052d // 指数K线
|
||||
KMSG_SECURITYBARS = 0x052d // 股票K线
|
||||
KMSG_MINUTETIMEDATA = 0x0537 // 分时数据
|
||||
KMSG_SECURITYLIST = 0x0450 // 证券列表
|
||||
KMSG_SECURITYQUOTES = 0x053e // 行情信息
|
||||
KMSG_TRANSACTIONDATA = 0x0fc5 // 分笔成交信息
|
||||
KMSG_XDXRINFO = 0x000f // 除权除息信息
|
||||
|
||||
)
|
||||
|
||||
const (
|
||||
KLINE_TYPE_5MIN = 0 // 5分钟K 线
|
||||
KLINE_TYPE_15MIN = 1 // 15分钟K 线
|
||||
KLINE_TYPE_30MIN = 2 // 30分钟K 线
|
||||
KLINE_TYPE_1HOUR = 3 // 1小时K 线
|
||||
KLINE_TYPE_DAILY = 4 // 日K 线
|
||||
KLINE_TYPE_WEEKLY = 5 // 周K 线
|
||||
KLINE_TYPE_MONTHLY = 6 // 月K 线
|
||||
KLINE_TYPE_EXHQ_1MIN = 7 // 1分钟
|
||||
KLINE_TYPE_1MIN = 8 // 1分钟K 线
|
||||
KLINE_TYPE_RI_K = 9 // 日K 线
|
||||
KLINE_TYPE_3MONTH = 10 // 季K 线
|
||||
KLINE_TYPE_YEARLY = 11 // 年K 线
|
||||
)
|
||||
BIN
docs/plan.png
BIN
docs/plan.png
Binary file not shown.
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 374 KiB After Width: | Height: | Size: 374 KiB |
@@ -10,7 +10,7 @@ func main() {
|
||||
c, err := tdx.Dial("124.71.187.122:7709")
|
||||
logs.PanicErr(err)
|
||||
|
||||
resp, err := c.GetStockList(protocol.ExchangeSH, 200)
|
||||
resp, err := c.GetStockList(protocol.ExchangeSH, 255)
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
|
||||
23
example/GetStockMinuteTrade/main.go
Normal file
23
example/GetStockMinuteTrade/main.go
Normal file
@@ -0,0 +1,23 @@
|
||||
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.GetStockMinuteTrade(protocol.ExchangeSH, "000001", 0, 100)
|
||||
logs.PanicErr(err)
|
||||
|
||||
for _, v := range resp.List {
|
||||
logs.Debug(v)
|
||||
}
|
||||
|
||||
logs.Debug("总数:", resp.Count)
|
||||
|
||||
})
|
||||
}
|
||||
13
example/common/common.go
Normal file
13
example/common/common.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/injoyai/logs"
|
||||
"github.com/injoyai/tdx"
|
||||
)
|
||||
|
||||
func Test(f func(c *tdx.Client)) {
|
||||
c, err := tdx.Dial("124.71.187.122:7709")
|
||||
logs.PanicErr(err)
|
||||
f(c)
|
||||
<-c.Done()
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
package protocol
|
||||
|
||||
const (
|
||||
TypeConnect = 0x000D //建立连接
|
||||
TypeHeart = 0x0004 //心跳
|
||||
TypeStockCount = 0x044E //获取股票数量
|
||||
TypeStockList = 0x0450 //获取股票代码
|
||||
TypeStockQuote = 0x053E //行情信息
|
||||
TypeStockMinute = 0x051D //分时数据
|
||||
TypeConnect = 0x000D //建立连接
|
||||
TypeHeart = 0x0004 //心跳
|
||||
TypeStockCount = 0x044E //获取股票数量
|
||||
TypeStockList = 0x0450 //获取股票代码
|
||||
TypeStockQuote = 0x053E //行情信息
|
||||
TypeStockMinute = 0x051D //分时数据
|
||||
TypeStockMinuteTrade = 0x0FC5 //分时交易
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,12 +9,13 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
MConnect = connect{}
|
||||
MHeart = heart{}
|
||||
MStockCount = stockCount{}
|
||||
MStockQuote = stockQuote{}
|
||||
MStockList = stockList{}
|
||||
MStockMinute = stockMinute{}
|
||||
MConnect = connect{}
|
||||
MHeart = heart{}
|
||||
MStockCount = stockCount{}
|
||||
MStockQuote = stockQuote{}
|
||||
MStockList = stockList{}
|
||||
MStockMinute = stockMinute{}
|
||||
MStockMinuteTrade = stockMinuteTrade{}
|
||||
)
|
||||
|
||||
type ConnectResp struct {
|
||||
|
||||
101
protocol/model_stock_minute_trade.go
Normal file
101
protocol/model_stock_minute_trade.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type StockMinuteTradeResp struct {
|
||||
Count uint16
|
||||
List []*StockMinuteTrade
|
||||
}
|
||||
|
||||
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%-6d(手) \t%-4d(单) \t%-4s", this.Time, this.Price, this.Volume, this.Number, this.StatusString())
|
||||
}
|
||||
|
||||
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: GetTime([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
|
||||
}
|
||||
@@ -61,3 +61,22 @@ func FloatUnitString(f float64) string {
|
||||
func IntUnitString(n int) string {
|
||||
return FloatUnitString(float64(n))
|
||||
}
|
||||
|
||||
func GetTime(bs [2]byte) string {
|
||||
n := Uint16(bs[:])
|
||||
h := n / 60
|
||||
m := n % 60
|
||||
return fmt.Sprintf("%02d:%02d", h, m)
|
||||
}
|
||||
|
||||
func basePrice(code string) Price {
|
||||
if len(code) == 0 {
|
||||
return 1
|
||||
}
|
||||
switch code[:2] {
|
||||
case "60", "30", "68", "00":
|
||||
return 1
|
||||
default:
|
||||
return 10
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user