mirror of
https://github.com/injoyai/tdx.git
synced 2025-11-26 21:25:35 +08:00
校对了数据,上海的没啥问题,深圳的还不行
This commit is contained in:
@@ -55,7 +55,6 @@ func (this *Client) handlerDealMessage(c *client.Client, msg ios.Acker) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logs.Debug(f.Type)
|
|
||||||
switch f.Type {
|
switch f.Type {
|
||||||
case protocol.TypeSecurityQuote:
|
case protocol.TypeSecurityQuote:
|
||||||
resp := protocol.MSecurityQuote.Decode(f.Data)
|
resp := protocol.MSecurityQuote.Decode(f.Data)
|
||||||
|
|||||||
@@ -1,15 +1,5 @@
|
|||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
type Exchange uint8
|
|
||||||
|
|
||||||
func (this Exchange) Uint8() uint8 { return uint8(this) }
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExchangeSH Exchange = iota //上海交易所
|
|
||||||
ExchangeSZ //深圳交易所
|
|
||||||
ExchangeBJ //北京交易所
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Control = 0x01
|
Control = 0x01
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package protocol
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
bytes2 "github.com/injoyai/base/bytes"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -85,25 +85,28 @@ func (securityList) Decode(bs []byte) (*SecurityListResp, error) {
|
|||||||
|
|
||||||
type SecurityQuotesResp []*SecurityQuote
|
type SecurityQuotesResp []*SecurityQuote
|
||||||
|
|
||||||
|
func (this SecurityQuotesResp) String() string {
|
||||||
|
ls := []string(nil)
|
||||||
|
for _, v := range this {
|
||||||
|
ls = append(ls, v.String())
|
||||||
|
}
|
||||||
|
return strings.Join(ls, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
type SecurityQuote struct {
|
type SecurityQuote struct {
|
||||||
Market uint8 // 市场
|
Exchange Exchange // 市场
|
||||||
Code string // 代码
|
Code string // 代码
|
||||||
Active1 uint16 // 活跃度
|
Active1 uint16 // 活跃度
|
||||||
//Price float64 // 现价
|
|
||||||
//Close float64 // 昨收
|
|
||||||
//Open float64 // 开盘
|
|
||||||
//High float64 // 最高
|
|
||||||
//Low float64 // 最低
|
|
||||||
K K //k线
|
K K //k线
|
||||||
|
|
||||||
ServerTime string // 时间
|
ServerTime string // 时间
|
||||||
ReversedBytes0 int // 保留(时间 ServerTime)
|
ReversedBytes0 int // 保留(时间 ServerTime)
|
||||||
ReversedBytes1 int // 保留
|
ReversedBytes1 int // 保留
|
||||||
Vol int // 总量
|
TotalHand int // 总手(东财的盘口-总手)
|
||||||
CurVol int // 现量
|
Intuition int // 现量(东财的盘口-现量)
|
||||||
Amount float64 // 总金额
|
Amount float64 // 金额(东财的盘口-金额)
|
||||||
SVol int // 内盘
|
InsideDish int // 内盘(东财的盘口-外盘)(和东财对不上)
|
||||||
BVol int // 外盘
|
OuterDisc int // 外盘(东财的盘口-外盘)(和东财对不上)
|
||||||
|
|
||||||
ReversedBytes2 int // 保留
|
ReversedBytes2 int // 保留
|
||||||
ReversedBytes3 int // 保留
|
ReversedBytes3 int // 保留
|
||||||
BidLevels [5]PriceLevel
|
BidLevels [5]PriceLevel
|
||||||
@@ -138,6 +141,13 @@ type SecurityQuote struct {
|
|||||||
Active2 uint16 // 活跃度
|
Active2 uint16 // 活跃度
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *SecurityQuote) String() string {
|
||||||
|
return this.K.String() + fmt.Sprintf(", 总量:%s, 现量:%s, 总金额:%s, 内盘:%s, 外盘:%s",
|
||||||
|
IntUnitString(this.TotalHand), IntUnitString(this.Intuition), FloatUnitString(this.Amount),
|
||||||
|
IntUnitString(this.InsideDish), IntUnitString(this.OuterDisc)) + "\n" +
|
||||||
|
fmt.Sprintf("%#v\n", this)
|
||||||
|
}
|
||||||
|
|
||||||
type securityQuote struct{}
|
type securityQuote struct{}
|
||||||
|
|
||||||
func (this securityQuote) Frame(m map[Exchange]string) (*Frame, error) {
|
func (this securityQuote) Frame(m map[Exchange]string) (*Frame, error) {
|
||||||
@@ -176,34 +186,36 @@ func (this securityQuote) Decode(bs []byte) SecurityQuotesResp {
|
|||||||
|
|
||||||
for i := uint16(0); i < number; i++ {
|
for i := uint16(0); i < number; i++ {
|
||||||
sec := &SecurityQuote{
|
sec := &SecurityQuote{
|
||||||
Market: bs[0],
|
Exchange: Exchange(bs[0]),
|
||||||
Code: string(UTF8ToGBK(bytes2.Reverse(bs[1:7]))),
|
Code: string(UTF8ToGBK(bs[1:7])),
|
||||||
Active1: Uint16(bs[7:9]),
|
Active1: Uint16(bs[7:9]),
|
||||||
}
|
}
|
||||||
bs, sec.K = DecodeK(bs[9:])
|
bs, sec.K = DecodeK(bs[9:])
|
||||||
bs, sec.ReversedBytes0 = CutInt(bs)
|
bs, sec.ReversedBytes0 = CutInt(bs)
|
||||||
sec.ServerTime = fmt.Sprintf("%d", sec.ReversedBytes0)
|
sec.ServerTime = fmt.Sprintf("%d", sec.ReversedBytes0)
|
||||||
bs, sec.ReversedBytes1 = CutInt(bs)
|
bs, sec.ReversedBytes1 = CutInt(bs)
|
||||||
bs, sec.Vol = CutInt(bs)
|
bs, sec.TotalHand = CutInt(bs)
|
||||||
bs, sec.CurVol = CutInt(bs)
|
bs, sec.Intuition = CutInt(bs)
|
||||||
sec.Amount = getVolume(Uint32(bs[:4]))
|
sec.Amount = getVolume(Uint32(bs[:4]))
|
||||||
bs, sec.SVol = CutInt(bs[4:])
|
bs, sec.InsideDish = CutInt(bs[4:])
|
||||||
bs, sec.BVol = CutInt(bs)
|
bs, sec.OuterDisc = CutInt(bs)
|
||||||
bs, sec.ReversedBytes2 = CutInt(bs)
|
bs, sec.ReversedBytes2 = CutInt(bs)
|
||||||
bs, sec.ReversedBytes3 = CutInt(bs)
|
bs, sec.ReversedBytes3 = CutInt(bs)
|
||||||
|
|
||||||
var p Price
|
var p Price
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
bidele := PriceLevel{}
|
bidele := PriceLevel{}
|
||||||
|
offerele := PriceLevel{}
|
||||||
|
|
||||||
bs, p = GetPrice(bs)
|
bs, p = GetPrice(bs)
|
||||||
bidele.Price = p + sec.K.Close
|
bidele.Price = p + sec.K.Close
|
||||||
bs, bidele.Vol = CutInt(bs)
|
|
||||||
sec.BidLevels[i] = bidele
|
|
||||||
|
|
||||||
offerele := PriceLevel{}
|
|
||||||
bs, p = GetPrice(bs)
|
bs, p = GetPrice(bs)
|
||||||
offerele.Price = p + sec.K.Close
|
offerele.Price = p + sec.K.Close
|
||||||
|
|
||||||
|
bs, bidele.Vol = CutInt(bs)
|
||||||
bs, offerele.Vol = CutInt(bs)
|
bs, offerele.Vol = CutInt(bs)
|
||||||
|
|
||||||
|
sec.BidLevels[i] = bidele
|
||||||
sec.AskLevels[i] = offerele
|
sec.AskLevels[i] = offerele
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ func (this Price) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PriceLevel struct {
|
type PriceLevel struct {
|
||||||
Price Price
|
Price Price //价
|
||||||
Vol int
|
Vol int //量,是否是成交量?
|
||||||
}
|
}
|
||||||
|
|
||||||
// K k线图
|
// K k线图
|
||||||
@@ -30,6 +30,10 @@ type K struct {
|
|||||||
Close Price //今日收盘价
|
Close Price //今日收盘价
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this K) String() string {
|
||||||
|
return fmt.Sprintf("昨收:%0.2f, 今开:%0.2f, 最高:%0.2f, 最低:%0.2f, 今收:%0.2f", this.Last.Float64(), this.Open.Float64(), this.High.Float64(), this.Low.Float64(), this.Close.Float64())
|
||||||
|
}
|
||||||
|
|
||||||
func DecodeK(bs []byte) ([]byte, K) {
|
func DecodeK(bs []byte) ([]byte, K) {
|
||||||
k := K{}
|
k := K{}
|
||||||
|
|
||||||
|
|||||||
37
protocol/types.go
Normal file
37
protocol/types.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package protocol
|
||||||
|
|
||||||
|
type Exchange uint8
|
||||||
|
|
||||||
|
func (this Exchange) Uint8() uint8 { return uint8(this) }
|
||||||
|
|
||||||
|
func (this Exchange) String() string {
|
||||||
|
switch this {
|
||||||
|
case ExchangeSH:
|
||||||
|
return "sh"
|
||||||
|
case ExchangeSZ:
|
||||||
|
return "sz"
|
||||||
|
case ExchangeBJ:
|
||||||
|
return "bj"
|
||||||
|
default:
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this Exchange) Name() string {
|
||||||
|
switch this {
|
||||||
|
case ExchangeSH:
|
||||||
|
return "上海"
|
||||||
|
case ExchangeSZ:
|
||||||
|
return "深圳"
|
||||||
|
case ExchangeBJ:
|
||||||
|
return "北京"
|
||||||
|
default:
|
||||||
|
return "未知"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExchangeSH Exchange = iota //上海交易所
|
||||||
|
ExchangeSZ //深圳交易所
|
||||||
|
ExchangeBJ //北京交易所
|
||||||
|
)
|
||||||
@@ -2,6 +2,7 @@ package protocol
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
bytes2 "github.com/injoyai/base/bytes"
|
bytes2 "github.com/injoyai/base/bytes"
|
||||||
"github.com/injoyai/conv"
|
"github.com/injoyai/conv"
|
||||||
"golang.org/x/text/encoding/simplifiedchinese"
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
@@ -32,41 +33,24 @@ func UTF8ToGBK(text []byte) []byte {
|
|||||||
return bytes.ReplaceAll(content, []byte{0x00}, []byte{})
|
return bytes.ReplaceAll(content, []byte{0x00}, []byte{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getprice(b []byte, pos *int) int {
|
func FloatUnit(f float64) (float64, string) {
|
||||||
/*
|
m := []string{"万", "亿"}
|
||||||
0x7f与常量做与运算实质是保留常量(转换为二进制形式)的后7位数,既取值区间为[0,127]
|
unit := ""
|
||||||
0x3f与常量做与运算实质是保留常量(转换为二进制形式)的后6位数,既取值区间为[0,63]
|
for i := 0; f > 1e4 && i < len(m); f /= 1e4 {
|
||||||
|
unit = m[i]
|
||||||
0x80 1000 0000
|
}
|
||||||
0x7f 0111 1111
|
return f, unit
|
||||||
0x40 100 0000
|
|
||||||
0x3f 011 1111
|
|
||||||
*/
|
|
||||||
posByte := 6
|
|
||||||
bData := b[*pos]
|
|
||||||
data := int(bData & 0x3f)
|
|
||||||
bSign := false
|
|
||||||
if (bData & 0x40) > 0 {
|
|
||||||
bSign = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bData & 0x80) > 0 {
|
func FloatUnitString(f float64) string {
|
||||||
for {
|
m := []string{"万", "亿"}
|
||||||
*pos += 1
|
unit := ""
|
||||||
bData = b[*pos]
|
for i := 0; f > 1e4 && i < len(m); f /= 1e4 {
|
||||||
data += (int(bData&0x7f) << posByte)
|
unit = m[i]
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%0.2f%s", f, unit)
|
||||||
|
}
|
||||||
|
|
||||||
posByte += 7
|
func IntUnitString(n int) string {
|
||||||
|
return FloatUnitString(float64(n))
|
||||||
if (bData & 0x80) <= 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*pos++
|
|
||||||
|
|
||||||
if bSign {
|
|
||||||
data = -data
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user