package protocol import ( "fmt" "strings" ) type QuotesResp []*Quote func (this QuotesResp) String() string { ls := []string(nil) for _, v := range this { ls = append(ls, v.String()) } return strings.Join(ls, "\n") } type Quote struct { Exchange Exchange // 市场 Code string // 股票代码 6个ascii字符串 Active1 uint16 // 活跃度 K K //k线 ServerTime string // 时间 ReversedBytes0 int // 保留(时间 ServerTime) ReversedBytes1 int // 保留 这个等于 负的收盘价格? TotalHand int // 总手(东财的盘口-总手) Intuition int // 现量(东财的盘口-现量)现在成交量 Amount float64 // 金额(东财的盘口-金额) InsideDish int // 内盘(东财的盘口-外盘)(和东财对不上) OuterDisc int // 外盘(东财的盘口-外盘)(和东财对不上) ReversedBytes2 int // 保留,未知 ReversedBytes3 int // 保留,未知 BuyLevel PriceLevels // 5档买盘(买1-5) SellLevel PriceLevels // 5档卖盘(卖1-5) ReversedBytes4 uint16 // 保留,未知 ReversedBytes5 int // 保留,未知 ReversedBytes6 int // 保留,未知 ReversedBytes7 int // 保留,未知 ReversedBytes8 int // 保留,未知 ReversedBytes9 uint16 // 保留,未知 Rate float64 // 涨速,好像都是0 Active2 uint16 // 活跃度 } func (this *Quote) String() string { return fmt.Sprintf(`%s%s %s 总量:%s, 现量:%s, 总金额:%s, 内盘:%s, 外盘:%s %s%s `, this.Exchange.String(), this.Code, this.K, IntUnitString(this.TotalHand), IntUnitString(this.Intuition), FloatUnitString(this.Amount), IntUnitString(this.InsideDish), IntUnitString(this.OuterDisc), this.SellLevel.String(), this.BuyLevel.String(), ) } type quote struct{} func (this quote) Frame(codes ...string) (*Frame, error) { f := &Frame{ Control: Control01, Type: TypeQuote, Data: []byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, } payload := Bytes(uint16(len(codes))) for _, v := range codes { exchange, code, err := DecodeCode(v) if err != nil { return nil, err } payload = append(payload, exchange.Uint8()) payload = append(payload, code...) } f.Data = append(f.Data, payload...) return f, nil } /* Decode 0136 0200 数量 00 交易所 303030303031 股票代码 320b 活跃度? b212 昨天收盘价1186 4c 56 10 59 87e6d10cf212b78fa801ae01293dc54e8bd740acb8670086ca1e0001af36ba0c4102b467b6054203a68a0184094304891992114405862685108d0100000000e8ff320b 01 深圳交易所 363030303038 股票代码 5909 8005 46 45 02 46 8defd10c 服务时间 c005bed2668e05be15804d8ba12cb3b13a0083c3034100badc029d014201bc990384f70443029da503b7af074403a6e501b9db044504a6e2028dd5048d050000000000005909 */ func (this quote) Decode(bs []byte) QuotesResp { //logs.Debug(hex.EncodeToString(bs)) resp := QuotesResp{} //前2字节是什么? bs = bs[2:] number := Uint16(bs[:2]) bs = bs[2:] for i := uint16(0); i < number; i++ { sec := &Quote{ Exchange: Exchange(bs[0]), Code: string(UTF8ToGBK(bs[1:7])), Active1: Uint16(bs[7:9]), } bs, sec.K = DecodeK(bs[9:]) bs, sec.ReversedBytes0 = CutInt(bs) sec.ServerTime = fmt.Sprintf("%d", sec.ReversedBytes0) bs, sec.ReversedBytes1 = CutInt(bs) bs, sec.TotalHand = CutInt(bs) bs, sec.Intuition = CutInt(bs) sec.Amount = getVolume(Uint32(bs[:4])) bs, sec.InsideDish = CutInt(bs[4:]) bs, sec.OuterDisc = CutInt(bs) bs, sec.ReversedBytes2 = CutInt(bs) bs, sec.ReversedBytes3 = CutInt(bs) var p Price for i := 0; i < 5; i++ { buyLevel := PriceLevel{Buy: true} sellLevel := PriceLevel{} bs, p = GetPrice(bs) buyLevel.Price = p + sec.K.Close bs, p = GetPrice(bs) sellLevel.Price = p + sec.K.Close bs, buyLevel.Number = CutInt(bs) bs, sellLevel.Number = CutInt(bs) sec.BuyLevel[i] = buyLevel sec.SellLevel[i] = sellLevel } sec.ReversedBytes4 = Uint16(bs[:2]) bs, sec.ReversedBytes5 = CutInt(bs[2:]) bs, sec.ReversedBytes6 = CutInt(bs) bs, sec.ReversedBytes7 = CutInt(bs) bs, sec.ReversedBytes8 = CutInt(bs) sec.ReversedBytes9 = Uint16(bs[:2]) sec.Rate = float64(sec.ReversedBytes9) / 100 sec.Active2 = Uint16(bs[2:4]) bs = bs[4:] resp = append(resp, sec) } return resp }