// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved. package tick // 本文件实现bityuan数据源接口, 实时数据和历史数据的获取和保存 import ( "log" "time" "tickserver/markinfo" "tickserver/server/market" _ "github.com/go-sql-driver/mysql" socketio "github.com/googollee/go-socket.io" ) type HBMarketOverview HBLastTimeLine type HBTradeDetail HBLastTimeLine type HBMarketDetail HBLastTimeLine type HBMarketDepthTopDiff HBLastTimeLine type HBMarketDepthDiff struct { SymbolId string `json:"symbolId"` PushType string `json:"pushType"` Percent string `json:"percent"` } type HBLastKLine struct { SymbolId string `json:"symbolId"` PushType string `json:"pushType"` Period string `json:"period"` } type HBLastTimeLine struct { SymbolId string `json:"symbolId"` PushType string `json:"pushType"` } type HBSymbolList struct { //LastTimeLine []HBLastTimeLine `json:"lastTimeLine"` //LastKLine []HBLastKLine `json:"lastKLine"` //MarketDepthDiff []HBMarketDepthDiff `json:"marketDepthDiff"` //MarketDepthTopDiff []HBMarketDepthTopDiff `json:"marketDepthTopDiff"` //MarketDetail []HBMarketDetail `json:"marketDetail"` //TradeDetail []HBTradeDetail `json:"tradeDetail"` MarketOverview []HBMarketOverview `json:"marketOverview"` } type HBCmd struct { SymbolList HBSymbolList `json:"symbolList"` Version int `json:"version"` MsgType string `json:"msgType"` RequestIndex int `json:"requestIndex"` } type MarketOverviewPL struct { SymbolId string `json:"symbolId"` PriceNew float64 `json:"priceNew"` PriceHigh float64 `json:"priceHigh"` TotalVolume float64 `json:"totalVolume"` TotalAmount float64 `json:"totalAmount"` PriceOpen float64 `json:"priceOpen"` PriceLow float64 `json:"priceLow"` PriceAsk float64 `json:"priceAsk"` PriceBid float64 `json:"priceBid"` } type HBResp struct { Version int `json:"version"` MsgType string `json:"msgType"` SymbolId string `json:"symbolId"` PayLoad MarketOverviewPL `json:"payload"` } // HuobiDS实现了dataSource接口, 并对bityuan的历史数据和实时数据保存 type HuobiDS struct { *DSBase conf *DsConf //client *socketio.Client } var lastVolume float64 var huobiInss = []int{ markinfo.BTCCNY, markinfo.LTCCNY, } func init() { drivers[Huobi] = newHuobiDS } func (hds *HuobiDS) connectHuobi(count int) (*socketio.Client, error) { var err error var client *socketio.Client for i := 0; i < count; i++ { client, err = socketio.Dial("http://hq.huobi.com:80") if err != nil { log.Println("newHuobiDS", err) time.Sleep(time.Second * 5) } else { log.Println("success") break } } return client, err } func subscribeHuobi(ns *socketio.NameSpace) error { var err error var hbcmd HBCmd hbcmd.MsgType = "reqMsgSubscribe" hbcmd.RequestIndex = 1404103038520 hbcmd.Version = 1 hbcmd.SymbolList = HBSymbolList{ /*LastTimeLine: []HBLastTimeLine{{SymbolId: "btccny", PushType: "pushLong"}}, LastKLine: []HBLastKLine{ {SymbolId: "btccny", PushType: "pushLong", Period: "1min"}, {SymbolId: "btccny", PushType: "pushLong", Period: "5min"}, {SymbolId: "btccny", PushType: "pushLong", Period: "15min"}, {SymbolId: "btccny", PushType: "pushLong", Period: "30min"}, {SymbolId: "btccny", PushType: "pushLong", Period: "60min"}, {SymbolId: "btccny", PushType: "pushLong", Period: "1day"}, {SymbolId: "btccny", PushType: "pushLong", Period: "1week"}, {SymbolId: "btccny", PushType: "pushLong", Period: "1mon"}, {SymbolId: "btccny", PushType: "pushLong", Period: "1year"}, }, MarketDepthDiff: []HBMarketDepthDiff{ {SymbolId: "btccny", PushType: "pushLong", Percent: "10"}, {SymbolId: "btccny", PushType: "pushLong", Percent: "20"}, {SymbolId: "btccny", PushType: "pushLong", Percent: "50"}, {SymbolId: "btccny", PushType: "pushLong", Percent: "80"}, {SymbolId: "btccny", PushType: "pushLong", Percent: "100"}, }, MarketDepthTopDiff: []HBMarketDepthTopDiff{{SymbolId: "btccny", PushType: "pushLong"}}, MarketDetail: []HBMarketDetail{{SymbolId: "btccny", PushType: "pushLong"}}, TradeDetail: []HBTradeDetail{{SymbolId: "btccny", PushType: "pushLong"}},*/ MarketOverview: []HBMarketOverview{{SymbolId: "btccny", PushType: "pushLong"}}, } err = ns.Emit("request", &hbcmd) if err != nil { return err } /*hbcmd.RequestIndex = 1414103038520 hbcmd.SymbolList = HBSymbolList{ MarketOverview: []HBMarketOverview{{SymbolId: "ltccny", PushType: "pushLong"}}, } err = ns.Emit("request", &hbcmd) if err != nil { return err }*/ return nil } func newHuobiDS(conf *DsConf) (DataSource, error) { hds := &HuobiDS{ DSBase: NewDsBase(conf), conf: conf, } hds.insMap = huobiInsMap() return hds, nil } func (hds *HuobiDS) getData() { client, err := hds.connectHuobi(120) if err != nil { return } client.On("connect", func(ns *socketio.NameSpace) { log.Println("connected") err = subscribeHuobi(ns) if err != nil { log.Println("connect failed:", err) } }) client.On("disconnect", func(ns *socketio.NameSpace) { log.Println("disconnect") }) client.On("reconnect", func(ns *socketio.NameSpace) { log.Println("reconnect") }) client.On("message", func(ns *socketio.NameSpace, message interface{}) { //log.Println("message") //log.Println(message) m1, ok1 := message.(map[string]interface{}) if ok1 { m2, ok2 := m1["payload"] if ok2 { m3, ok3 := m2.(map[string]interface{}) if ok3 { symbolId, ok4 := m3["symbolId"] if ok4 { symbol := symbolId.(string) priceNew := m3["priceNew"].(float64) priceHigh := m3["priceHigh"].(float64) totalVolume := m3["totalVolume"].(float64) totalAmount := m3["totalAmount"].(float64) priceOpen := m3["priceOpen"].(float64) priceLow := m3["priceLow"].(float64) priceAsk := m3["priceAsk"].(float64) priceBid := m3["priceBid"].(float64) mk := &Market{} mk.Type = IntHuobi if symbol == "btccny" { mk.InsId = markinfo.BTCCNY } if symbol == "ltccny" { mk.InsId = markinfo.LTCCNY } mk.Open = priceOpen mk.Low = priceLow mk.High = priceHigh mk.LastPrice = priceNew if totalVolume > lastVolume { mk.LastVolume = totalVolume - lastVolume } else { mk.LastVolume = totalVolume } mk.AllAmount = totalAmount mk.AllVolume = totalVolume var ask, bid PP ask[0] = priceAsk ask[1] = mk.LastVolume bid[0] = priceBid bid[1] = mk.LastVolume mk.Asks = append(mk.Asks, ask) mk.Bids = append(mk.Bids, bid) mk.Timestamp = time.Now().UnixNano() / (1000 * 1000) hds.Save(mk) } } } } }) client.On("request", func(ns *socketio.NameSpace, request interface{}) { log.Println("request", request) }) client.Run() } func (hds *HuobiDS) Name() string { return Huobi } func (hds *HuobiDS) Run() { for { log.Println("HuobiDS.Run") hds.getData() time.Sleep(5 * time.Second) log.Println("HuobiDS.End Run") } } func huobiInsMap() map[int64]*Instrument { insMap := make(map[int64]*Instrument) for _, id := range huobiInss { x, _ := markinfo.SymbolName(id) u, _ := markinfo.SymbolUint(x) ins := &Instrument{ Id: int64(id), Name: x, ExId: Huobi, Type: market.Btcs, PriceInc: u, StartTime: time.Now().Unix() * 1000, } insMap[int64(id)] = ins } return insMap }