wr 6 lat temu
rodzic
commit
9d89bbc12f

+ 0 - 275
server/tick/ds_btc.go

@@ -1,275 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-/*
-#include <string.h>
-*/
-import "C"
-
-// 本文件实现okcoin数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"encoding/json"
-	"log"
-	"strconv"
-	"time"
-	"tickserver/markinfo"
-	"tickserver/server/market"
-)
-
-const (
-	ClientCount = 3
-)
-
-var btcInss = []int{
-	markinfo.BTCUSD,
-	markinfo.BTCCNY,
-	markinfo.BTCFUSD,
-}
-
-type BTCTickerWS struct {
-	Buy       float64 `json:"buy"`
-	High      float64 `json:"high"`
-	Last      string  `json:"last"`
-	Low       float64 `json:"low"`
-	Sell      float64 `json:"sell"`
-	Timestamp string  `json:"timestamp"`
-	Vol       string  `json:"vol"`
-}
-
-type BTCTickWS struct {
-	Channel string      `json:"channel"`
-	Data    BTCTickerWS `json:"data"`
-}
-
-type BTCTickerWSFirst struct {
-	Buy       string `json:"buy"`
-	High      string `json:"high"`
-	Last      string `json:"last"`
-	Low       string `json:"low"`
-	Sell      string `json:"sell"`
-	Timestamp string `json:"timestamp"`
-	Vol       string `json:"vol"`
-}
-
-type BTCTickWSFirst struct {
-	Channel string           `json:"channel"`
-	Data    BTCTickerWSFirst `json:"data"`
-}
-
-type BTCFTickerWS struct {
-	Buy         float64 `json:"buy"`
-	Contract_id string  `json:"contract_id"`
-	High        float64 `json:"high"`
-	Hold_amount float64 `json:"hold_amount"`
-	Last        string  `json:"last"`
-	Low         float64 `json:"low"`
-	Sell        float64 `json:"sell"`
-	UnitAmount  float64 `json:"unitAmount"`
-	Vol         string  `json:"vol"`
-}
-
-type BTCFTickWS struct {
-	Channel string       `json:"channel"`
-	Data    BTCFTickerWS `json:"data"`
-}
-
-// BtcDS实现了dataSource接口, 并对btc的历史数据和实时数据保存
-type BtcDS struct {
-	*DSBase
-	conf     *DsConf
-	wsclient [ClientCount]*OKClientWrapper
-}
-
-func init() {
-	drivers[Btc] = newBtcDS
-}
-
-func newBtcDS(conf *DsConf) (DataSource, error) {
-	bds := &BtcDS{
-		DSBase: NewDsBase(conf),
-		conf:   conf,
-	}
-	bds.insMap = btcInsMap()
-
-	return bds, nil
-}
-
-func (bds *BtcDS) Name() string {
-	return Btc
-}
-
-func (bds *BtcDS) Run() {
-	log.Println("BtcDS.Run")
-	var err error
-	/*bds.wsclient[0], err = NewOKClientWrapper("http://localhost/", "wss://real.okcoin.com:10440/websocket/okcoinapi", BTC_REAL, markinfo.BTCUSD)
-	if err != nil {
-		log.Println("NewOKClientWrapper", err)
-	}
-	time.Sleep(time.Second * 3)
-	err = bds.wsclient[0].Emit("ok_btcusd_ticker")
-	if err != nil {
-		log.Println("Emit", err)
-	}
-	go bds.ProcessData(0)*/
-	bds.wsclient[0], err = NewOKClientWrapper("http://localhost/", "wss://real.okcoin.cn:10440/websocket/okcoinapi", BTC_REAL, markinfo.BTCCNY)
-	if err != nil {
-		log.Println("NewOKClientWrapper", err)
-	}
-	time.Sleep(time.Second * 3)
-	err = bds.wsclient[0].Emit("ok_btccny_ticker")
-	if err != nil {
-		log.Println("Emit", err)
-	}
-	go bds.ProcessData(0)
-	/*bds.wsclient[2], err = NewOKClientWrapper("http://localhost/", "wss://real.okcoin.com:10440/websocket/okcoinapi", BTC_F_REAL, markinfo.BTCFUSD)
-	if err != nil {
-		log.Println("NewOKClientWrapper", err)
-	}
-	time.Sleep(time.Second * 3)
-	err = bds.wsclient[2].Emit("ok_btcusd_future_ticker_this_week")
-	if err != nil {
-		log.Println("Emit", err)
-	}
-	go bds.ProcessData(2)*/
-}
-
-func (bds *BtcDS) ProcessData(index int) {
-	for {
-		err := bds.wsclient[index].okclient.RevString(&bds.wsclient[index].datastr)
-		if err == nil {
-			if bds.wsclient[index].datastr == "{\"event\":\"pong\"}" {
-				bds.wsclient[index].lastsec = time.Now().Unix()
-				continue
-			}
-
-			switch bds.wsclient[index].datatyp {
-			case BTC_REAL:
-				err = bds.parseBTCReal(index)
-				if err != nil {
-					log.Println("parseBTCReal", bds.wsclient[index].datastr, err)
-				}
-			case BTC_F_REAL:
-				err = bds.parseBTCFReal(index)
-				if err != nil {
-					log.Println("parseBTCFReal", bds.wsclient[index].datastr, err)
-				}
-			default:
-				log.Println("data type not supported:", bds.wsclient[index].datatyp)
-			}
-		} else {
-			log.Println(bds.wsclient[index].symbol, "RevString", err)
-			//bds.wsclient[index].okclient.Close()
-			time.Sleep(time.Second * 2)
-			//bds.wsclient[index].okclient.Connect()
-			//time.Sleep(time.Second * 3)
-			//bds.wsclient[index].ReEmit()
-		}
-	}
-}
-
-func (bds *BtcDS) parseBTCFReal(index int) error {
-	var btcfticks []BTCFTickWS
-	err := json.Unmarshal([]byte(bds.wsclient[index].datastr), &btcfticks)
-	if err != nil {
-		return err
-	}
-	for _, btcftick := range btcfticks {
-		mk := &Market{}
-		mk.Type = IntBtc
-		mk.InsId = markinfo.BTCFUSD
-		mk.Timestamp = time.Now().Unix() * 1000
-		var ask, bid PP
-		ask[0] = btcftick.Data.Sell
-		ask[1] = btcftick.Data.Hold_amount
-		bid[0] = btcftick.Data.Buy
-		bid[1] = btcftick.Data.Hold_amount
-		mk.Asks = append(mk.Asks, ask)
-		mk.Bids = append(mk.Bids, bid)
-		mk.High = btcftick.Data.High
-		mk.LastPrice, _ = strconv.ParseFloat(btcftick.Data.Last, 32)
-		mk.Low = btcftick.Data.Low
-		mk.AllAmount = btcftick.Data.UnitAmount
-		mk.AllVolume, _ = strconv.ParseFloat(btcftick.Data.Vol, 32)
-		bds.Save(mk)
-	}
-
-	return nil
-}
-
-func (bds *BtcDS) parseBTCReal(index int) error {
-	var btctickwss []BTCTickWS
-	err := json.Unmarshal([]byte(bds.wsclient[index].datastr), &btctickwss)
-	if err != nil {
-		var btctickwssfirst []BTCTickWSFirst
-		err = json.Unmarshal([]byte(bds.wsclient[index].datastr), &btctickwssfirst)
-		if err != nil {
-			log.Println(bds.wsclient[index].datastr)
-			return err
-		}
-		for _, btctickws := range btctickwssfirst {
-			mk := &Market{}
-			mk.Type = IntBtc
-			mk.InsId = int64(bds.wsclient[index].symbol)
-			mk.Timestamp, _ = strconv.ParseInt(btctickws.Data.Timestamp, 10, 64)
-			if mk.Timestamp == 0 {
-				return nil //丢弃非行情数据
-			}
-			var ask, bid PP
-			ask[0], _ = strconv.ParseFloat(btctickws.Data.Sell, 32)
-			bid[0], _ = strconv.ParseFloat(btctickws.Data.Buy, 32)
-			mk.Asks = append(mk.Asks, ask)
-			mk.Bids = append(mk.Bids, bid)
-			mk.High, _ = strconv.ParseFloat(btctickws.Data.High, 32)
-			mk.LastPrice, _ = strconv.ParseFloat(btctickws.Data.Last, 32)
-			mk.Low, _ = strconv.ParseFloat(btctickws.Data.Low, 32)
-			mk.LastVolume, _ = strconv.ParseFloat(btctickws.Data.Vol, 32)
-			if mk.LastPrice != 0 {
-				bds.Save(mk)
-			}
-		}
-		return nil
-	}
-	for _, btctickws := range btctickwss {
-		mk := &Market{}
-		mk.Type = IntBtc
-		mk.InsId = int64(bds.wsclient[index].symbol)
-		mk.Timestamp, _ = strconv.ParseInt(btctickws.Data.Timestamp, 10, 64)
-		if mk.Timestamp == 0 {
-			return nil //丢弃非行情数据
-		}
-		var ask, bid PP
-		ask[0] = btctickws.Data.Sell
-		bid[0] = btctickws.Data.Buy
-		mk.Asks = append(mk.Asks, ask)
-		mk.Bids = append(mk.Bids, bid)
-		mk.High = btctickws.Data.High
-		mk.LastPrice, _ = strconv.ParseFloat(btctickws.Data.Last, 32)
-		mk.Low = btctickws.Data.Low
-		mk.LastVolume, _ = strconv.ParseFloat(btctickws.Data.Vol, 32)
-		if mk.LastPrice != 0 {
-			bds.Save(mk)
-		}
-	}
-
-	return nil
-}
-
-func btcInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, id := range btcInss {
-		x, _ := markinfo.SymbolName(id)
-		u, _ := markinfo.SymbolUint(x)
-		ins := &Instrument{
-			Id:        int64(id),
-			Name:      x,
-			ExId:      market.Btc,
-			Type:      market.Btcs,
-			PriceInc:  u,
-			StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}

+ 0 - 26
server/tick/ds_btc_test.go

@@ -1,26 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestBtc(t *testing.T) {
-	conf := &DsConf{
-		Url:     "218.18.103.38:7709",
-		CfgFile: "serverlist.txt",
-	}
-	ds, err := newBtcDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(mk)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 155
server/tick/ds_cfix.go

@@ -1,155 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现cfix数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"fmt"
-	"log"
-	"strings"
-
-	"tickserver/api/fix"
-	"tickserver/markinfo"
-	"tickserver/server/market"
-)
-
-// CFixDS实现了dataSource接口, 并对cfix的历史数据和实时数据保存
-type CFixDS struct {
-	*DSBase
-	conf *DsConf
-}
-
-var cfixInss = []int{
-	markinfo.AUDCAD,
-	markinfo.AUDCHF,
-	markinfo.AUDJPY,
-	markinfo.AUDNZD,
-	markinfo.AUDUSD,
-	markinfo.CADJPY,
-	markinfo.CHFJPY,
-	markinfo.EURAUD,
-	markinfo.EURCAD,
-	markinfo.EURCHF,
-	markinfo.EURGBP,
-	markinfo.EURJPY,
-	markinfo.EURNZD,
-	markinfo.EURUSD,
-	markinfo.GBPAUD,
-	markinfo.GBPCAD,
-	markinfo.GBPCHF,
-	markinfo.GBPJPY,
-	markinfo.GBPUSD,
-	markinfo.NZDJPY,
-	markinfo.NZDUSD,
-	markinfo.OILUSD,
-	markinfo.SGDJPY,
-	markinfo.USDCAD,
-	markinfo.USDCHF,
-	markinfo.USDJPY,
-	markinfo.USDPLN,
-	markinfo.XAGUSD,
-	markinfo.XAGEUR,
-	markinfo.XAUUSD,
-	markinfo.XAUEUR,
-	markinfo.ZARJPY,
-}
-
-func init() {
-	drivers[CFix] = newCFixDS
-}
-
-func newCFixDS(conf *DsConf) (DataSource, error) {
-	cfixds := &CFixDS{
-		DSBase: NewDsBase(conf),
-		conf:   conf,
-	}
-	cfixds.insMap = cfixInsMap()
-
-	return cfixds, nil
-}
-
-func (cfixds *CFixDS) Name() string {
-	return CFix
-}
-
-func (cfixds *CFixDS) Run() {
-	log.Println("CFixDS.Run")
-	ss, err := fix.NewSessionSettings(cfixds.conf.CfgFile)
-	if err != nil {
-		panic(err)
-	}
-	sourdatach := make(chan *fix.TickFull, 1024)
-	go cfixds.onMarket(sourdatach)
-	app := fix.NewMarketInfoApp(sourdatach)
-	//fmt.Println(app, ss, cfixds.conf.CfgFile)
-	trade, err := fix.NewAppTradeClient(app, ss)
-	if err != nil {
-		panic(err)
-	}
-	fmt.Println("cfix run start")
-	trade.Start()
-	trade.Run()
-	fmt.Println("cfix run end")
-	trade.Stop()
-	trade.Free()
-	fmt.Println("cfix stop")
-}
-
-func (cfixds *CFixDS) onMarket(sourdatach chan *fix.TickFull) {
-	for {
-		tf := <-sourdatach
-
-		mk := &Market{}
-		mk.Type = IntCFix
-		symbol := string(tf.Symbol[:7])
-		ss := strings.Split(symbol, "/")
-		if len(ss) != 2 {
-			continue
-		}
-		symbol = ss[0] + ss[1]
-		symbolId, err := markinfo.SymbolId(symbol)
-		if err != nil {
-			continue
-		}
-		mk.InsId = int64(symbolId)
-		mk.Asks = make([]PP, tf.AskCount)
-		mk.Bids = make([]PP, tf.BidCount)
-		for i := 0; i < int(tf.AskCount); i++ {
-			mk.Asks[i][0] = tf.AskPrice[i]
-			mk.Asks[i][1] = tf.AskVolume[i]
-		}
-		for i := 0; i < int(tf.BidCount); i++ {
-			mk.Bids[i][0] = tf.BidPrice[i]
-			mk.Bids[i][1] = tf.BidVolume[i]
-		}
-		mk.Timestamp = int64(tf.Time)*1000 + int64(tf.Millisecond)
-		mk.Close = tf.BidPrice[0]
-		mk.High = tf.BidPrice[0]
-		mk.Low = tf.BidPrice[0]
-		mk.Open = tf.BidPrice[0]
-		mk.AllAmount = tf.BidVolume[0]
-		mk.AllVolume = tf.BidVolume[0]
-		mk.LastPrice = tf.BidPrice[0]
-		mk.LastVolume = tf.BidVolume[0]
-		cfixds.Save(mk)
-	}
-}
-
-func cfixInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, id := range cfixInss {
-		x, _ := markinfo.SymbolName(id)
-		u, _ := markinfo.SymbolUint(x)
-		ins := &Instrument{
-			Id:       int64(id),
-			Name:     x,
-			ExId:     CFix,
-			Type:     market.Forex,
-			PriceInc: u,
-			//StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}

+ 0 - 25
server/tick/ds_cfix_test.go

@@ -1,25 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestCFix(t *testing.T) {
-	conf := &DsConf{
-		CfgFile: "SessionCfgMk.cfg",
-	}
-	ds, err := newCFixDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(mk)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 113
server/tick/ds_chbtc.go

@@ -1,113 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现chbtc数据源的tick数据获取下载和保存
-
-import (
-	"log"
-	"net/http"
-	"time"
-
-	"tickserver/markinfo"
-	"tickserver/server/market"
-	coinapi "github.com/nntaoli/crypto_coin_api"
-	"github.com/nntaoli/crypto_coin_api/chbtc"
-)
-
-var chbtcInss = []int{
-	markinfo.BTCCNY,
-	markinfo.ETCCNY,
-	markinfo.ETHCNY,
-}
-
-// ChbtcDS 实现数据源dataSource接口的定义
-type ChbtcDS struct {
-	*DSBase
-	conf       *DsConf
-	chbtc      *chbtc.Chbtc
-	lastprice  []float64
-	lastvolume []float64
-}
-
-func init() {
-	drivers[Chbtc] = newChbtcDS
-}
-
-func newChbtcDS(conf *DsConf) (DataSource, error) {
-	log.Println("newChbtcDS")
-	cds := &ChbtcDS{
-		DSBase:     NewDsBase(conf),
-		conf:       conf,
-		lastprice:  make([]float64, len(chbtcInss)),
-		lastvolume: make([]float64, len(chbtcInss)),
-	}
-	cds.insMap = chbtcInsMap()
-	cds.chbtc = chbtc.New(&http.Client{}, "", "")
-	return cds, nil
-}
-
-func (cds *ChbtcDS) Name() string {
-	return Chbtc
-}
-
-func (cds *ChbtcDS) Run() {
-	log.Println("ChbtcDS.run")
-	for {
-		for k, _ := range chbtcInss {
-			cds.getChbtcData(k)
-			time.Sleep(time.Second)
-		}
-	}
-}
-
-func chbtcInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, id := range chbtcInss {
-		x, _ := markinfo.SymbolName(id)
-		u, _ := markinfo.SymbolUint(x)
-		ins := &Instrument{
-			Id:        int64(id),
-			Name:      x,
-			ExId:      Btc,
-			Type:      market.Btcs,
-			PriceInc:  u,
-			StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}
-
-func (cds *ChbtcDS) getChbtcData(index int) {
-	var currency coinapi.CurrencyPair
-	if chbtcInss[index] == markinfo.BTCCNY {
-		currency = coinapi.BTC_CNY
-	}
-	if chbtcInss[index] == markinfo.ETCCNY {
-		currency = coinapi.ETC_CNY
-	}
-	if chbtcInss[index] == markinfo.ETHCNY {
-		currency = coinapi.ETH_CNY
-	}
-	ticker, _ := cds.chbtc.GetTicker(currency)
-	if ticker != nil && (ticker.Last != cds.lastprice[index] || ticker.Vol != cds.lastvolume[index]) {
-		cds.lastprice[index] = ticker.Last
-		cds.lastvolume[index] = ticker.Vol
-
-		mk := &Market{}
-		mk.Type = IntChbtc
-		mk.InsId = int64(chbtcInss[index])
-		mk.Timestamp = int64(ticker.Date)
-		var ask, bid PP
-		ask[0] = ticker.Sell
-		bid[0] = ticker.Buy
-		mk.Asks = append(mk.Asks, ask)
-		mk.Bids = append(mk.Bids, bid)
-		mk.High = ticker.High
-		mk.LastPrice = ticker.Last
-		mk.Low = ticker.Low
-		mk.LastVolume = ticker.Vol
-		cds.Save(mk)
-	}
-}

+ 0 - 23
server/tick/ds_chbtc_test.go

@@ -1,23 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestChbtc(t *testing.T) {
-	conf := &DsConf{}
-	ds, _ := newChbtcDS(conf) //, err
-	//if err != nil {
-	//t.Fatal(err)
-	//}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(mk)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 455
server/tick/ds_ctp.go

@@ -1,455 +0,0 @@
-// +build linux windows,386
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现ctp(期货)数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"errors"
-	"log"
-	"os"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-
-	"tickserver/api/gocctp"
-	"tickserver/server/market"
-	"golang.org/x/text/encoding/simplifiedchinese"
-)
-
-type myMdSpi struct {
-	gocctp.SpiBase
-	ds *CtpDS
-}
-
-func (spi *myMdSpi) OnRspUserLogin(errMsg string) {
-	spi.ds.OnMdRspUserLogin(errMsg)
-}
-
-func (spi *myMdSpi) OnRtnDepthMarketData(field *gocctp.CThostFtdcDepthMarketDataField) {
-	spi.ds.OnRtnDepthMarketData(field)
-}
-
-// CtpDS实现了dataSource接口, 并对ctp的历史数据和实时数据保存
-type CtpDS struct {
-	gocctp.SpiBase
-	mdApi *gocctp.MdApi
-	tdApi *gocctp.TdApi
-	conf  *DsConf // 配置
-	*DSBase
-
-	mu sync.Mutex
-	//insMap        map[string]*market.Instrument // lmax产品列表
-	insMappingMap map[string]int64
-	insMappings   map[int64]string
-	mdLogined     bool
-	dmkdfCh       chan *gocctp.CThostFtdcDepthMarketDataField
-}
-
-func init() {
-	drivers[Ctp] = newCtpDS
-}
-
-func newCtpDS(conf *DsConf) (DataSource, error) {
-	log.Println("newCtpDS")
-	mdspi := &myMdSpi{}
-	mdDir := conf.SaveDir + "/MD/"
-	os.MkdirAll(mdDir, 0777)
-	mdApi := gocctp.NewMdApi(mdspi, mdDir)
-	cds := &CtpDS{
-		DSBase: NewDsBase(conf),
-		mdApi:  mdApi,
-		conf:   conf,
-		//insMap:        make(map[string]*market.Instrument),
-		insMappingMap: make(map[string]int64),
-		insMappings:   make(map[int64]string),
-		dmkdfCh:       make(chan *gocctp.CThostFtdcDepthMarketDataField, 1),
-	}
-	tdDir := conf.SaveDir + "/TD/"
-	os.MkdirAll(tdDir, 0777)
-	tdApi := gocctp.NewTdApi(cds, tdDir)
-	cds.tdApi = tdApi
-	mdspi.ds = cds
-	ctpTypMap = make(map[string]int)
-	for k, v := range ctpTyps {
-		ctpTypMap[v] = k
-	}
-	return cds, nil
-}
-
-//func (cds *CtpDS) SubIns() *event.Event {
-//return cds.insPublisher.Event()
-//}
-
-func (cds *CtpDS) onMarketData(pDepthMarketData *gocctp.CThostFtdcDepthMarketDataField) {
-	insId := getInsId(pDepthMarketData.InstrumentID.String())
-	intInsId := cds.insIdMapping(insId)
-	cds.mu.Lock()
-	ins, ok := cds.insMap[intInsId]
-	cds.mu.Unlock()
-	if !ok {
-		log.Println("insId NOT in cds:", insId)
-		return
-	}
-	t, its := cds.convTime(pDepthMarketData.TradingDay.String(), pDepthMarketData.UpdateTime.String())
-	h := t.Hour()
-	if h > 20 || h < 6 { // 夜盘
-		w := t.Weekday()
-		if w == time.Monday { // 交易日是周一
-			if h > 20 {
-				its -= 3600 * 24 * 3 // 时间应该是周五晚上
-			} else { // h < 6
-				its -= 3600 * 24 * 2 // 时间应该是周六凌晨
-			}
-		} else if h > 20 {
-			its -= 3600 * 24 // 时间减去24小时
-		}
-	}
-
-	ts := its*1000 + int64(pDepthMarketData.UpdateMillisec)
-
-	if !checkTime(ins.ExId, ts) {
-		//log.Println("checkTime false:", insId, ins.ExId, market.GetTime(ts))
-		return
-	}
-
-	bids := make([]PP, 5)
-	bids[0][0] = float64(pDepthMarketData.BidPrice1)
-	bids[1][0] = float64(pDepthMarketData.BidPrice2)
-	bids[2][0] = float64(pDepthMarketData.BidPrice3)
-	bids[3][0] = float64(pDepthMarketData.BidPrice4)
-	bids[4][0] = float64(pDepthMarketData.BidPrice5)
-	bids[0][1] = float64(pDepthMarketData.BidVolume1)
-	bids[1][1] = float64(pDepthMarketData.BidVolume2)
-	bids[2][1] = float64(pDepthMarketData.BidVolume3)
-	bids[3][1] = float64(pDepthMarketData.BidVolume4)
-	bids[4][1] = float64(pDepthMarketData.BidVolume5)
-
-	asks := make([]PP, 5)
-	asks[0][0] = float64(pDepthMarketData.AskPrice1)
-	asks[1][0] = float64(pDepthMarketData.AskPrice2)
-	asks[2][0] = float64(pDepthMarketData.AskPrice3)
-	asks[3][0] = float64(pDepthMarketData.AskPrice4)
-	asks[4][0] = float64(pDepthMarketData.AskPrice5)
-	asks[0][1] = float64(pDepthMarketData.AskVolume1)
-	asks[1][1] = float64(pDepthMarketData.AskVolume2)
-	asks[2][1] = float64(pDepthMarketData.AskVolume3)
-	asks[3][1] = float64(pDepthMarketData.AskVolume4)
-	asks[4][1] = float64(pDepthMarketData.AskVolume5)
-
-	//mk := ins.GetMk()
-	mk := &Market{}
-	mk.Type = IntCtp
-	mk.Timestamp = ts
-	mk.LastPrice = float64(pDepthMarketData.LastPrice)
-	mk.Bids = bids
-	mk.Asks = asks
-	mk.High = float64(pDepthMarketData.HighestPrice)
-	mk.Open = float64(pDepthMarketData.OpenPrice)
-	mk.Low = float64(pDepthMarketData.LowestPrice)
-	mk.Close = float64(pDepthMarketData.PreClosePrice)
-	mk.AllAmount = float64(pDepthMarketData.Turnover)
-	// 计算交易量 从总交易量AllVolume - 上一次的 == 本次交易量
-	oldVol := mk.AllVolume
-	mk.AllVolume = float64(pDepthMarketData.Volume)
-	if oldVol == 0 {
-		oldVol = mk.AllVolume
-	}
-	mk.LastVolume = mk.AllVolume - oldVol
-	if mk.LastVolume < 0 {
-		mk.LastVolume = mk.AllVolume
-	}
-	mk.InsId = intInsId
-
-	if intInsId == 0 {
-		log.Println("error insid", insId)
-	}
-	//ins.SetMk(mk)
-	//if pDepthMarketData.InstrumentID.String() == "IC1507" ||
-	//pDepthMarketData.InstrumentID.String() == "IF1507" ||
-	//pDepthMarketData.InstrumentID.String() == "IH1507" {
-	//tt := time.Unix(mk.Timestamp/1000, (mk.Timestamp%1000)*(1e6))
-	//log.Println("debug checktime", tt, ins.ExId, pDepthMarketData.InstrumentID.String())
-	//}
-
-	cds.Save(mk)
-}
-
-func (cds *CtpDS) convTime(sd, st string) (time.Time, int64) {
-	t, n := cds.convDate(sd)
-	if n == -1 {
-		t = time.Now()
-	}
-	ss := strings.Split(st, ":")
-	h, _ := strconv.Atoi(ss[0])
-	m, _ := strconv.Atoi(ss[1])
-	s, _ := strconv.Atoi(ss[2])
-	t = time.Date(t.Year(), t.Month(), t.Day(), h, m, s, 0, time.Local)
-	return t, t.Unix()
-}
-
-func (cds *CtpDS) convDate(st string) (time.Time, int64) {
-	if len(st) < 6 {
-		return time.Time{}, -1
-	}
-	sy := st[:4]
-	sm := st[4:6]
-	sd := st[6:]
-	y, _ := strconv.ParseInt(string(sy), 10, 64)
-	m, _ := strconv.ParseInt(string(sm), 10, 64)
-	d, _ := strconv.ParseInt(string(sd), 10, 64)
-
-	t := time.Date(int(y), time.Month(m), int(d), 0, 0, 0, 0, time.Local)
-	return t, t.Unix() * 1000
-}
-
-// 大商所
-var kindsOfDS = []string{"a", "b", "bb", "c", "fb", "i", "j", "jd", "jm", "l", "m", "p", "pp", "v", "y"}
-
-// 上期所
-var kindsOfSQ = []string{"ag", "al", "au", "bu", "cu", "fu", "hc", "pb", "rb", "ru", "wr", "zn"}
-
-// 郑商所
-var kindsOfZS = []string{"CF", "FG", "JR", "LR", "MA", "OL", "PM", "RI", "RM", "RS", "SF", "SM", "SR", "TA", "TC", "WH"}
-
-// 中金所
-var kindsOfZJ = []string{"TF", "IF", "IH", "IC"}
-
-var pids = []string{}
-
-func init() {
-	pids = append(pids, kindsOfDS...)
-	pids = append(pids, kindsOfSQ...)
-	pids = append(pids, kindsOfZS...)
-	pids = append(pids, kindsOfZJ...)
-}
-
-func convInsId(iid, pid string) string {
-	return market.CtpPrefix + iid //pid + iid[len(iid)-2:]
-}
-
-func getInsId(sid string) string {
-	return market.CtpPrefix + sid
-}
-
-func (cds *CtpDS) onInstrument(pInstrument *gocctp.CThostFtdcInstrumentField) {
-	pid := pInstrument.ProductID.String()
-	trans := simplifiedchinese.GBK.NewDecoder()
-	dst := make([]byte, 1024)
-	for _, x := range pids {
-		if pid == x {
-			sname := pInstrument.InstrumentName.String()
-			nDst, _, err := trans.Transform(dst, []byte(sname), true)
-			if err == nil {
-				sname = string(dst[0:nDst])
-			}
-			sid := pInstrument.InstrumentID.String()
-			_, ist := cds.convDate(pInstrument.OpenDate.String())
-			_, iet := cds.convDate(pInstrument.ExpireDate.String())
-			ins := &Instrument{
-				Id:        cds.insIdMapping(convInsId(sid, x)),
-				Name:      sname,
-				ExId:      pInstrument.ExchangeID.String(),
-				Type:      Futures,
-				PriceInc:  float64(pInstrument.PriceTick),
-				Margin:    float64((pInstrument.LongMarginRatio + pInstrument.ShortMarginRatio) / 2),
-				StartTime: ist,
-				EndTime:   iet + (3600 * 24 * 1000), // 加当天时间
-			}
-			cds.insMap[ins.Id] = ins
-			//bGoods := 1
-			//if ins.ExId == CFFEX {
-			//bGoods = 0
-			//}
-			//ctpHisName := fmt.Sprintf("%s:%d", sid, bGoods)
-			//ctpHisNames = append(ctpHisNames, ctpHisName)
-			break
-		}
-	}
-}
-
-func (cds *CtpDS) OnRtnDepthMarketData(pDepthMarketData *gocctp.CThostFtdcDepthMarketDataField) {
-	select {
-	case cds.dmkdfCh <- pDepthMarketData:
-	default:
-	}
-}
-
-func (cds *CtpDS) OnRspQryExchange(field *gocctp.CThostFtdcExchangeField, errMsg string, isLast bool) {
-	if errMsg != "" {
-		log.Println(errMsg)
-		return
-	}
-}
-
-func (cds *CtpDS) OnRspQryInstrument(field *gocctp.CThostFtdcInstrumentField, errMsg string, isLast bool) {
-	if errMsg != "" {
-		log.Println(errMsg)
-		return
-	}
-	cds.onInstrument(field)
-	//saveCtpHisNames()
-	if isLast {
-		if !cds.mdLogined {
-			cds.mdApi.Login(cds.conf.Url2, cds.conf.BrokerId, cds.conf.User, cds.conf.PassWord)
-			log.Println("Md login:", cds.conf.Url2)
-		} else {
-			cds.mdLogined = false
-		}
-	}
-}
-
-func (cds *CtpDS) OnRspUserLogin(errMsg string) {
-	trans := simplifiedchinese.GBK.NewDecoder()
-	dst := make([]byte, len(errMsg)*2)
-	nDst, _, err := trans.Transform(dst, []byte(errMsg), true)
-	if err == nil {
-		errMsg = string(dst[0:nDst])
-	}
-	if errMsg != "" {
-		log.Println(errMsg)
-		return
-	}
-	log.Println("OnRspUserLogin OK")
-	cds.tdApi.QryInstrument("")
-}
-
-func (cds *CtpDS) OnMdRspUserLogin(errMsg string) {
-	if errMsg != "" {
-		log.Println(errMsg)
-		return
-	}
-	cds.mdLogined = true
-	log.Println("OnMdRspUserLogin OK")
-	insIds := []string{}
-	cds.mu.Lock()
-	for id, v := range cds.insMap {
-		idstr, ok := cds.insMappings[id]
-		if ok {
-			insIds = append(insIds, market.RealInsId(idstr))
-		} else {
-			log.Println("error ins:", v)
-		}
-	}
-	cds.mu.Unlock()
-	//conf
-	if cds.conf.Symbols != "" {
-		insIds = getSymbols(insIds, cds.conf.Symbols)
-	}
-	cds.mdApi.SubscribeMarketData(insIds)
-	log.Println("SubscribeMarketData", insIds)
-}
-
-func getSymbols(insIds []string, symbols string) []string {
-	insmap := make(map[string]bool)
-	for i := 0; i < len(insIds); i++ {
-		insmap[insIds[i]] = true
-	}
-	symarr := strings.Split(symbols, ",")
-	var ret []string
-	for i := 0; i < len(symarr); i++ {
-		item1 := strings.ToLower(symarr[i])
-		item2 := strings.ToUpper(symarr[i])
-		if insmap[item1] {
-			ret = append(ret, item1)
-		}
-		if insmap[item2] {
-			ret = append(ret, item2)
-		}
-	}
-	return ret
-}
-
-func (cds *CtpDS) Name() string {
-	return Ctp
-}
-
-func (cds *CtpDS) Run() {
-	log.Println("CtpDS.Run")
-
-	cds.tdApi.Login(cds.conf.Url, cds.conf.BrokerId, cds.conf.User, cds.conf.PassWord, "", "")
-	log.Println("Td login:", cds.conf.Url)
-
-	go func() {
-		for dmkd := range cds.dmkdfCh {
-			cds.onMarketData(dmkd)
-		}
-	}()
-
-	//cds.RunSave(32)
-}
-
-/*func (cds *CtpDS) runHour() {
-	ht := time.Tick(time.Hour)
-	for t := range ht {
-		cds.mu.Lock()
-		for k, ins := range cds.insMap {
-			if t.Hour() == 6 {
-				mk := ins.GetMk()
-				mk.Volume = 0
-				cds.Save(mk)
-			}
-
-			if time.Now().Unix()*1000 > ins.EndTime {
-				log.Println("ins expired:", ins.Name, ins.Id, market.GetTime(ins.EndTime))
-				delete(cds.insMap, k)
-				cds.Del(k) // 指示保存
-			}
-		}
-		cds.mu.Unlock()
-	}
-}*/
-
-// 上海期货交易所:
-//上午 09:00 -- 10:15 10:30 -- 11:30
-//下午 13:30 -- 14:10 14:20 -- 15:00
-//夜盘 21:00 -- 02:30
-
-//大连、郑州商品交易所:
-//上午09:00 -- 10:15 10:30 -- 11:30
-//下午 13:30 -- 15:00
-
-//中国金融期货交易所:(沪深300期货标准合约)
-//平时交易时间9:15--11:30 13:00---15:15
-//交割日交易时间为 9:15--11:30 13:00---15:00
-
-func (cds *CtpDS) getInsId(insId string) (int64, error) {
-	for k, v := range insId {
-		if v >= '0' && v <= '9' {
-			insTyp := strings.ToUpper(insId[4:k])
-			insSuffix := insId[k:]
-			intTyp, ok := ctpTypMap[insTyp]
-			if !ok {
-				log.Println("ins type error:", insTyp, insSuffix, insId)
-				return 0, errors.New("ins type err.")
-			}
-			intSuffix, err := strconv.Atoi(insSuffix)
-			if err != nil {
-				log.Println("ins type error:", insTyp, insSuffix, insId)
-				return 0, errors.New("ins type err.")
-			}
-			var id int64
-			id = int64(intTyp)*10000 + int64(intSuffix)
-			return id, nil
-		}
-	}
-
-	log.Println("ins type error:", insId)
-	return 0, errors.New("ins type err.")
-}
-
-func (cds *CtpDS) insIdMapping(insId string) int64 {
-	id, ok := cds.insMappingMap[insId]
-	if !ok {
-		var err error
-		id, err = cds.getInsId(insId)
-		if err != nil {
-			return 0
-		}
-		cds.insMappingMap[insId] = id
-		cds.insMappings[id] = insId
-	}
-	return id
-}

+ 0 - 34
server/tick/ds_ctp_test.go

@@ -1,34 +0,0 @@
-// +build linux windows,386
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-/*
-#cgo LDFLAGS: -L./lib
-*/
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestCtp(t *testing.T) {
-	conf := &DsConf{
-		BrokerId: "66666",
-		User:     "1011000",
-		PassWord: "317496",
-		Url:      "tcp://ctp1-front5.citicsf.com:41205",
-		Url2:     "tcp://ctp1-md5.citicsf.com:41213",
-		Symbols:  "AG1512,IF1509",
-	}
-	ds := NewDataSource("ctp", conf)
-	if ds == nil {
-		t.Fatal("NewDataSource ctp error")
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 310
server/tick/ds_dzh.go

@@ -1,310 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现大智慧数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"encoding/binary"
-	"errors"
-	"io"
-	"log"
-	"net"
-	"strconv"
-	"strings"
-	"time"
-
-	"tickserver/server/market"
-	"golang.org/x/text/encoding/simplifiedchinese"
-)
-
-// DzhDS实现了dataSource接口, 并对dzh的历史数据和实时数据保存
-type DzhDS struct {
-	*DSBase
-	conf *DsConf
-	//insMap map[string]*market.Instrument
-	tcp net.Conn
-}
-
-func init() {
-	drivers[Dzh] = newDzhDS
-}
-
-func newDzhDS(conf *DsConf) (DataSource, error) {
-	tcp, err := net.DialTimeout("tcp", conf.Url, 2*time.Second)
-	if err != nil {
-		return nil, err
-	}
-	return &DzhDS{
-		DSBase: NewDsBase(conf),
-		conf:   conf,
-		tcp:    tcp,
-		//insMap: make(map[string]*market.Instrument),
-	}, nil
-}
-
-func (dds *DzhDS) Name() string {
-	return Dzh
-}
-
-//func (dds *DzhDS) SubIns() *event.Event {
-//return dds.insPublisher.Event()
-//}
-
-func (dds *DzhDS) Run() {
-	log.Println("DzhDS.Run")
-	//go dds.RunSave(64)
-	for {
-		err := dds.read(dds.tcp)
-		if err != nil {
-			log.Println(err)
-			dds.tcp, err = net.Dial("tcp", dds.conf.Url)
-			if err != nil {
-				log.Fatal(err)
-			}
-			continue
-		}
-	}
-}
-
-func (dds *DzhDS) read(r io.Reader) error {
-	var t int32
-	err := binary.Read(r, binary.LittleEndian, &t)
-	if err != nil {
-		return errors.New("read data TYPE error:" + err.Error())
-	}
-	var count, size uint32
-	err = binary.Read(r, binary.LittleEndian, &count)
-	if err != nil {
-		return errors.New("read data COUNT error:" + err.Error())
-	}
-	err = binary.Read(r, binary.LittleEndian, &size)
-	if err != nil {
-		return errors.New("read data SIZE error:" + err.Error())
-	}
-
-	switch t {
-	case 0:
-		return dds.resoleL1(r, int(count))
-	case 1:
-		return dds.resoleL2(r, int(count))
-	case 2:
-		for i := 0; i < int(count); i++ {
-			mbi := MarketBoardInfo{}
-			err = binary.Read(r, binary.LittleEndian, &mbi)
-			if err != nil {
-				log.Println("read MarketBoardInfo error:", err)
-			}
-		}
-	default:
-		log.Fatal("can't go here")
-	}
-	return nil
-}
-
-type Ext struct {
-	Code      [16]byte
-	Name      [16]byte
-	PrevClose uint32
-	TopLtd    uint32
-	BotLtd    uint32
-}
-
-// 五档行情数据结构
-type QuoteL1 struct {
-	Ext
-	Number      int16
-	Tim32       int32
-	Open        int32
-	High        int32
-	Low         int32
-	New         int32
-	AllVol      int32
-	AllAmount   int32
-	MarketVal   int32
-	Reserver2   int32
-	PricesOfBid [5]int32
-	VolumeOfBid [5]int32
-	PricesOfAsk [5]int32
-	VolumeOfAsk [5]int32
-	Zero        [2]int32
-}
-
-func QuoteL1ToMD(ql1 *QuoteL1, ins *Instrument, insIdStr string) *Market {
-	mk := &Market{}
-	mk.InsId = ins.Id
-	mk.Type = IntDzh
-	factor := 100.0
-	sid := market.RealInsId(insIdStr)
-	if strings.HasPrefix(sid, "SH510") || strings.HasPrefix(sid, "SZ160") {
-		factor = 1000.0
-	}
-	mk.Asks = make([]PP, 10)
-	mk.Bids = make([]PP, 10)
-	for i := 0; i < 5; i++ {
-		mk.Asks[i][0] = float64(ql1.PricesOfAsk[i]) / factor
-		mk.Asks[i][1] = float64(ql1.VolumeOfAsk[i]) * 100.
-		mk.Bids[i][0] = float64(ql1.PricesOfBid[i]) / factor
-		mk.Bids[i][1] = float64(ql1.VolumeOfBid[i]) * 100.
-	}
-	mk.Close = float64(ql1.PrevClose) / factor
-	mk.Open = float64(ql1.Open) / factor
-	mk.LastPrice = float64(ql1.New) / factor
-	mk.Timestamp = int64(ql1.Tim32) * 1000
-	oldVol := mk.AllVolume
-	mk.AllVolume = float64(ql1.AllVol) * 100.
-	mk.LastVolume = mk.AllVolume - oldVol
-	if mk.LastVolume < 0 {
-		mk.LastVolume = mk.AllVolume
-	}
-	mk.AllAmount = float64(ql1.AllAmount)
-	return mk
-}
-
-// 十档行情数据结构
-type QuoteL2 struct {
-	Ext
-	Market      [2]byte
-	Number      int16
-	BuyEven     float32
-	BuyVol      float32
-	SellEven    float32
-	SellVol     float32
-	PricesOfBid [5]float32
-	VolumeOfBid [5]float32
-	PricesOfAsk [5]float32
-	VolumeOfAsk [5]float32
-}
-
-func QuoteL2ToMD(ql2 *QuoteL2, ins *Instrument) *Market {
-	//mk := ins.GetMk()
-	mk := &Market{}
-	mk.Type = IntDzh
-	mk.InsId = ins.Id
-	if len(mk.Asks) == 0 {
-		mk.Asks = make([]PP, 10)
-	}
-	if len(mk.Bids) == 0 {
-		mk.Bids = make([]PP, 10)
-	}
-	for i := 0; i < 5; i++ {
-		mk.Asks[i+5][0] = float64(ql2.PricesOfAsk[i])
-		mk.Asks[i+5][1] = float64(ql2.VolumeOfAsk[i]) * 100
-		mk.Bids[i+5][0] = float64(ql2.PricesOfBid[i])
-		mk.Bids[i+5][1] = float64(ql2.VolumeOfBid[i]) * 100
-	}
-	//ins.SetMk(mk)
-	// log.Printf("@@@@@@@:%+v\n", mk)
-	return mk
-}
-
-type MarketBoardInfo struct {
-	Code [16]byte
-	Info [48]byte
-}
-
-func (dds *DzhDS) resole(r io.Reader, count int, isL1 bool) ([]*QuoteL1, []*QuoteL2, error) {
-	ql1s := make([]*QuoteL1, count)
-	ql2s := make([]*QuoteL2, count)
-	for i := 0; i < int(count); i++ {
-		if isL1 {
-			ql1 := &QuoteL1{}
-			err := binary.Read(r, binary.LittleEndian, ql1)
-			if err != nil {
-				return nil, nil, errors.New("read QuoteL1 error:" + err.Error())
-			}
-			ql1s[i] = ql1
-		} else {
-			ql2 := &QuoteL2{}
-			err := binary.Read(r, binary.LittleEndian, ql2)
-			if err != nil {
-				return nil, nil, errors.New("read QuoteL2 error:" + err.Error())
-			}
-			ql2s[i] = ql2
-		}
-	}
-	return ql1s, ql2s, nil
-}
-
-func (dds *DzhDS) addIns(ext Ext) (*Instrument, string) {
-	sid := b2s(ext.Code[:])
-	exid := market.SHEX
-	if strings.Contains(sid, market.SZEX) {
-		exid = market.SZEX
-	}
-	sname := b2s(ext.Name[:])
-	trans := simplifiedchinese.GBK.NewDecoder()
-	dst := make([]byte, 1024)
-	insIdStr := market.DzhPrefix + sid
-	if len(sid) != 8 {
-		log.Println("wrong sid", sid)
-		return nil, ""
-	}
-	insId, _ := strconv.ParseInt(sid[2:], 10, 64)
-	ins, ok := dds.insMap[insId]
-	if !ok {
-		nDst, _, err := trans.Transform(dst, []byte(sname), true)
-		if err == nil {
-			sname = string(dst[0:nDst])
-		}
-		ins = &Instrument{
-			Id:       insId,
-			Name:     sname,
-			Type:     market.Securities,
-			ExId:     exid,
-			PriceInc: 0.01,
-		}
-		dds.insMap[insId] = ins
-		//log.Println(ins)
-		//dds.insPublisher.Publish(ins)
-	}
-	return ins, insIdStr
-}
-
-func (dds *DzhDS) resoleL1(r io.Reader, count int) error {
-	ql1s, _, err := dds.resole(r, count, true)
-	if err != nil {
-		log.Println(err)
-		return err
-	}
-	for _, q := range ql1s {
-		ins, insIdStr := dds.addIns(q.Ext)
-		if ins == nil {
-			//log.Fatal("@@@: DzhDS.resoleL1 ins == nil")
-			continue
-		}
-		mk := QuoteL1ToMD(q, ins, insIdStr)
-		//ins.SetMk(mk)
-		if mk.LastVolume == 0 {
-			continue // 交易量为0, 不存储
-		}
-		dds.Save(mk)
-	}
-	return nil
-}
-
-func b2s(b []byte) string {
-	for i, c := range b {
-		if c == 0 {
-			return string(b[:i])
-		}
-	}
-	return string(b[:])
-}
-
-func (dds *DzhDS) resoleL2(r io.Reader, count int) error {
-	_, ql2s, err := dds.resole(r, count, false)
-	if err != nil {
-		log.Println(err)
-		return err
-	}
-	for _, q := range ql2s {
-		ins, _ := dds.addIns(q.Ext)
-		if ins == nil {
-			continue
-		}
-		mk := QuoteL2ToMD(q, ins)
-		dds.Save(mk)
-	}
-	return nil
-}

+ 0 - 25
server/tick/ds_dzh_test.go

@@ -1,25 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestDzh(t *testing.T) {
-	conf := &DsConf{
-		Url: "115.29.238.128:19526",
-	}
-	ds, err := newDzhDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 291
server/tick/ds_easyforex.go

@@ -1,291 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现easyforex数据源的tick数据获取下载和保存
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io"
-	"log"
-	"net/http"
-	"strconv"
-	"strings"
-	"time"
-
-	"tickserver/markinfo"
-	"tickserver/server/market"
-	"github.com/ble/cookiejar"
-)
-
-var pair = []string{
-	"EURUSD",
-	"EURGBP",
-	"GBPUSD",
-	"USDJPY",
-	"USDCHF",
-	"AUDUSD",
-	"USDCAD",
-	"NZDUSD",
-	"CHFJPY",
-	"EURJPY",
-	"EURCHF",
-	"EURAUD",
-	"EURCAD",
-	"GBPCHF",
-	"GBPJPY",
-	"CADJPY",
-	"AUDJPY",
-	"AUDCAD",
-	"AUDNZD",
-	"XAGUSD",
-	"XAUUSD",
-	"OILUSD",
-}
-
-var easyforex_base = int(100)
-
-func logOn(client *http.Client, username, password string) error {
-	loginUrl := "https://secure.easy-forex.com/ntp/myaccount/services/loginservice.ashx?action=AuthenticateUser"
-	loginUrl = loginUrl + "&username=%s&password=%s&pid=42&culture=Int-en&simulator=false"
-	login := fmt.Sprintf(loginUrl, username, password)
-	resp, err := client.Get(login)
-	if err != nil {
-		return err
-	}
-	defer resp.Body.Close()
-	dec := json.NewDecoder(resp.Body)
-	data := make(map[string]interface{})
-	err = dec.Decode(&data)
-	if err != nil {
-		return err
-	}
-	if data["encData"] == nil {
-		return fmt.Errorf("error login format.")
-	}
-	doLoginUrl := "https://secure.easy-forex.com/ntp/myaccount/services/loginservice.ashx?action=DoLogin&pid=42&encData=%s&culture=Int-en&isSimulator=&service=0"
-	doLogin := fmt.Sprintf(doLoginUrl, data["encData"].(string))
-	resp2, err := client.Get(doLogin)
-	if err != nil {
-		return err
-	}
-	defer resp2.Body.Close()
-	dec = json.NewDecoder(resp2.Body)
-	data2 := make(map[string]interface{})
-	err = dec.Decode(&data2)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-type PairStatistics struct {
-	Date       time.Time
-	BuyPercent float64
-	Rates      float64
-	Symbol     string
-}
-
-func getStatistics(client *http.Client, symbol string) (stat *PairStatistics, err error) {
-	defer func() {
-		if err2 := recover(); err2 != nil {
-			err = fmt.Errorf("%v", err2)
-		}
-	}()
-	r := []rune(symbol)
-	s1 := string(r[:3])
-	s2 := string(r[3:])
-	url := "https://secure.easy-forex.com/ntp/Machine/TradingZone/tz.ashx?RQ=[{%22action%22%3A%22GetCurrencyPairStatistics%22%2C%22args%22%3A"
-	url += "{%22buy%22%3A%22" + s1 + "%22%2C%22sell%22%3A%22" + s2 + "%22}}"
-	url += "%2C{%22action%22%3A%22GetTableMids%22%2C%22args%22%3A{%22isExpanded%22%3A0%2C%22productId%22%3A3}}"
-	url += "%2C{%22action%22%3A%22GetDtrProposal%22%2C%22args%22%3A[null%2C%22USD%22%2C%22AUD%22%2C4%2C100%2C3]}"
-	url += "%2C{%22action%22%3A%22GetFreeBalance%22}]&MODE=isCurrencies&Heartbeat=0"
-	resp, err := client.Get(url)
-	if err != nil {
-		return nil, err
-	}
-	defer resp.Body.Close()
-	buf := bytes.NewBufferString("")
-	_, err = io.Copy(buf, resp.Body)
-	if err != nil {
-		return nil, err
-	}
-	var data []map[string]interface{}
-	s := buf.String()
-	s = strings.Replace(s, "GetCurrencyPairStatistics", `"GetCurrencyPairStatistics"`, 1)
-	s = strings.Replace(s, "GetTableMids", `"GetTableMids"`, 1)
-	s = strings.Replace(s, "GetDtrProposal", `"GetDtrProposal"`, 1)
-	s = strings.Replace(s, "GetFreeBalance", `"GetFreeBalance"`, 1)
-	err = json.Unmarshal([]byte(s), &data)
-	if err != nil {
-		return nil, err
-	}
-	pstat := data[0]["GetCurrencyPairStatistics"].(map[string]interface{})
-	if _, ok := pstat["error"]; ok {
-		// log.Println("GetCurrencyPairStatistics code = ", pstat["error"], symbol)
-		return nil, nil
-	}
-	currentRate := pstat["currentRate"].(string)
-	buyPercent := pstat["BuyPercent"].(float64)
-	curRateDate := data[0]["GetDtrProposal"].([]interface{})[3].(map[string]interface{})["curRateDate"].(string)
-	gotime, err := parseTime(curRateDate)
-	if err != nil {
-		return nil, err
-	}
-	_, err = markinfo.SymbolId(symbol)
-	if err != nil {
-		return nil, err
-	}
-	stat = &PairStatistics{}
-	stat.Date = gotime
-	stat.BuyPercent = buyPercent
-	stat.Rates, err = strconv.ParseFloat(currentRate, 64)
-	if err != nil {
-		return nil, err
-	}
-	stat.Symbol = symbol
-	return stat, err
-}
-
-func parseTime(curRateDate string) (time.Time, error) {
-	//curRateDate to time
-	//23/01/13 10:48:25.140
-	curRateDate = strings.Replace(curRateDate, "/", " ", -1)
-	curRateDate = strings.Replace(curRateDate, ":", " ", -1)
-	curRateDate = strings.Replace(curRateDate, ".", " ", -1)
-	parts := strings.Split(curRateDate, " ")
-	dates := make([]int, len(parts))
-	for i := 0; i < len(dates); i++ {
-		value, err := strconv.Atoi(parts[i])
-		if err != nil {
-			return time.Time{}, err
-		}
-		dates[i] = value
-	}
-	godate := time.Date(2000+dates[2], time.Month(dates[1]), dates[0], dates[3], dates[4], dates[5], dates[6]*int(time.Millisecond), time.UTC)
-	return godate, nil
-}
-
-// EasyForexDS 实现数据源dataSource接口的定义
-type EasyForexDS struct {
-	*DSBase
-	conf *DsConf
-	//insMap map[string]*market.Instrument
-}
-
-func init() {
-	drivers[EasyForex] = newEasyForexDS
-}
-
-func newEasyForexDS(conf *DsConf) (DataSource, error) {
-	eds := &EasyForexDS{
-		DSBase: NewDsBase(conf),
-		conf:   conf,
-		//insMap: edsInsMap(),
-	}
-	eds.insMap = edsInsMap()
-	return eds, nil
-}
-
-func (eds *EasyForexDS) onMarket(ps *PairStatistics) {
-	//insId := market.EasyForexPrefix + ps.Symbol
-	insId, _ := markinfo.SymbolId(ps.Symbol)
-	_, ok := eds.insMap[int64(insId)]
-	if !ok {
-		log.Fatal("EasyForexDS.onMarket error: insId is NOT in insMap:", insId)
-	}
-	//mk := ins.GetMk()
-	mk := &Market{}
-	mk.InsId = int64(insId)
-	mk.Type = IntEasyForex
-	mk.Timestamp = ps.Date.Unix() * 1000
-	mk.LastPrice = 100 - ps.BuyPercent
-	mk.LastVolume = 1
-	//ins.SetMk(mk)
-	eds.Save(mk)
-}
-
-/*func (eds *EasyForexDS) runHour() {
-	ht := time.Tick(time.Hour)
-	for _ = range ht {
-		for _, ins := range eds.insMap {
-			eds.Save(ins.GetMk())
-		}
-	}
-}*/
-
-func (eds *EasyForexDS) Name() string {
-	return EasyForex
-}
-
-func (eds *EasyForexDS) Run() {
-	log.Println("EasyForexDS.run")
-	//for _, ins := range eds.insMap {
-	//eds.insPublisher.Publish(ins)
-	//}
-	// go eds.runHour()
-	//go eds.RunSave(4)
-	ch := make(chan *PairStatistics, 1024)
-	go func() {
-		for {
-			ps := <-ch
-			eds.onMarket(ps)
-		}
-	}()
-	for {
-		client := &http.Client{Jar: cookiejar.NewJar(false)}
-		err := logOn(client, "Ty2388", "4536888")
-		var stat *PairStatistics
-		var laststat = make(map[string]*PairStatistics)
-		if err != nil {
-			log.Println(err)
-			goto END
-		}
-		for {
-			for i := 0; i < len(pair); i++ {
-				stat, err = getStatistics(client, pair[i])
-				if err != nil {
-					goto END
-				}
-				if stat != nil {
-					if _, ok := laststat[stat.Symbol]; !ok {
-						ch <- stat
-						laststat[stat.Symbol] = stat
-					} else if *laststat[stat.Symbol] != *stat && laststat[stat.Symbol].Date.Sub(stat.Date) < 0 {
-						ch <- stat
-						laststat[stat.Symbol] = stat
-					}
-				}
-			}
-		}
-	END:
-		log.Println(err)
-		time.Sleep(time.Second)
-	}
-}
-
-//func (eds *EasyForexDS) SubIns() *event.Event {
-//return eds.insPublisher.Event()
-//}
-
-func edsInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, x := range pair {
-		//id := market.EasyForexPrefix + x
-		id, _ := markinfo.SymbolId(x)
-		u, _ := markinfo.SymbolUint(x)
-
-		ins := &Instrument{
-			Id:        int64(id),
-			Name:      x,
-			ExId:      market.EasyForex,
-			Type:      market.Forex,
-			PriceInc:  u,
-			StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}

+ 0 - 23
server/tick/ds_easyforex_test.go

@@ -1,23 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestEasyForex(t *testing.T) {
-	conf := &DsConf{}
-	ds , _ := newEasyForexDS(conf) //, err
-	//if err != nil {
-	//t.Fatal(err)
-	//}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 173
server/tick/ds_fix.go

@@ -1,173 +0,0 @@
-// +build linux
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现方正FIX数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"encoding/json"
-	"errors"
-	"io/ioutil"
-	"log"
-	"os"
-	"strconv"
-	"strings"
-
-	"tickserver/api/gofix"
-)
-
-type StockInfo struct {
-	Id        string
-	Name      string
-	ExId      string
-	PriceInc  float64
-	Margin    float64
-	StartTime string
-}
-
-// FixDS实现了dataSource接口, 并对fix的历史数据和实时数据保存
-type FixDS struct {
-	*DSBase
-	conf       *DsConf
-	fixCfgFile string
-	symbolMap  map[string]string
-	insMap     map[int64]*StockInfo
-}
-
-func init() {
-    drivers[Fix] = newFixDS
-}
-
-func newFixDS(conf *DsConf) (DataSource, error) {
-	m := make(map[string]*StockInfo)
-	f, err := os.Open(conf.SymbolsFile)
-	if err != nil {
-		si := &StockInfo{
-			Id:        "600000",
-			ExId:      "XSHG",
-			Name:      "浦发银行",
-			PriceInc:  0.01,
-			StartTime: "1999-11-10",
-		}
-		m[si.Id] = si
-		b, _ := json.MarshalIndent(&m, "", "   ")
-		ioutil.WriteFile(conf.SymbolsFile, b, os.ModePerm)
-		return nil, err
-	}
-	dec := json.NewDecoder(f)
-	err = dec.Decode(&m)
-	if err != nil {
-		return nil, err
-	}
-	symbolMap := make(map[string]string)
-	insMap := make(map[int64]*StockInfo)
-	for k, v := range m {
-		symbolMap[k] = v.ExId
-		insId, _ := strconv.ParseInt(k, 10, 64)
-		//insId := market.FixPrefix + k
-		ss := strings.Split(v.StartTime, "-")
-		if len(ss) != 3 {
-			return nil, errors.New("StartTime format is Illegal. MUST yyyy-mm-dd format")
-		}
-		_, err := strconv.Atoi(ss[0])
-		if err != nil {
-			return nil, errors.New("StartTime format error:" + err.Error())
-		}
-		_, err = strconv.Atoi(ss[1])
-		if err != nil {
-			return nil, errors.New("StartTime format error:" + err.Error())
-		}
-		_, err = strconv.Atoi(ss[2])
-		if err != nil {
-			return nil, errors.New("StartTime format error:" + err.Error())
-		}
-		//t := time.Date(y, time.Month(m), d, 0, 0, 0, 0, time.Local)
-		/*ins := &market.Instrument{
-			Id:        insId,
-			Name:      v.Name,
-			Typ:       market.Securities,
-			ExId:      v.ExId,
-			PriceInc:  v.PriceInc,
-			Margin:    v.Margin,
-			StartTime: t.Unix() * 1000,
-		}*/
-		//insMap[insId] = ins
-		insMap[insId] = v
-	}
-
-	return &FixDS{
-		DSBase:    NewDsBase(conf),
-		conf:      conf,
-		symbolMap: symbolMap,
-		insMap:    insMap,
-	}, nil
-}
-
-//func (fds *FixDS) SubIns() *event.Event {
-//return fds.insPublisher.Event()
-//}
-
-// func (fds *FixDS) GetInsMap() map[string]*market.Instrument {
-// 	return fds.insMap
-// }
-
-// func (fds *FixDS) GetInsName(insId string) string {
-// 	return fds.insMap[insId].Name
-// }
-
-func (fds *FixDS) Name() string {
-	return Fix
-}
-
-func (fds *FixDS) Run() {
-	log.Println("FixDS.Run")
-	//for _, ins := range fds.insMap {
-	//fds.insPublisher.Publish(ins)
-	//}
-	fixApp := gofix.NewApp(fds.symbolMap, fds.conf.User, fds.conf.PassWord)
-	go fixApp.Run(fds.conf.CfgFile)
-	//go fds.RunSave(16)
-	log.Printf("%+v\n", fds.insMap)
-	for fixTick := range fixApp.Ch {
-		m := convMarket(fixTick)
-		_, ok := fds.insMap[m.InsId]
-		if !ok {
-			for k, _ := range fds.insMap {
-				log.Println(k, m.InsId, k == m.InsId) //, []byte(k), []byte(m.InsId)
-			}
-			log.Println("error: the market data NOT in insMap:", m.InsId, fds.insMap)
-			continue
-		}
-		//if m.Timestamp < ins.StartTime {
-		//log.Println("error: m.Timestamp < ins.StartTime:", m.Timestamp, ins.StartTime)
-		//continue
-		//}
-		// log.Println(market.GetTime(m.Timestamp))
-		// fds.marketPublisher.Publish(m)
-		//ins.SetMk(m)
-		fds.Save(m)
-	}
-}
-
-func convMarket(tick *gofix.FixTick) *Market {
-	//insId := market.FixPrefix + gofix.Symbol(tick.Symbol)
-	insId, _ := strconv.ParseInt(string(tick.Symbol[:]), 10, 64)
-	asks := make([]PP, tick.AskCount)
-	bids := make([]PP, tick.BidCount)
-	for i := 0; i < int(tick.AskCount); i++ {
-		asks[i][0] = tick.AskPrice[i]
-		asks[i][1] = float64(tick.AskVolume[i])
-	}
-	for i := 0; i < int(tick.AskCount); i++ {
-		bids[i][0] = tick.BidPrice[i]
-		bids[i][1] = float64(tick.BidVolume[i])
-	}
-	return &Market{
-		InsId:     insId,
-		Type:      IntFix,
-		Timestamp: int64(tick.Time)*1000 + int64(tick.Millisecond),
-		Bids:      bids,
-		Asks:      asks,
-	}
-}

+ 0 - 29
server/tick/ds_fix_test.go

@@ -1,29 +0,0 @@
-// +build linux
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestFix(t *testing.T) {
-	conf := &DsConf{
-		User:        "20410767",
-		PassWord:    "491823",
-		CfgFile:     "fix-mk.cfg",
-		SymbolsFile: "fix-symbols.json",
-	}
-	ds, err := newFixDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 273
server/tick/ds_huobi.go

@@ -1,273 +0,0 @@
-// 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
-}

+ 0 - 24
server/tick/ds_huobi_test.go

@@ -1,24 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-
-	"testing"
-)
-
-func TestHuobi(t *testing.T) {
-	conf := &DsConf{}
-	ds, err := newHuobiDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(mk)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 208
server/tick/ds_lmax.go

@@ -1,208 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-package tick
-
-// 本文件实现lmax数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"fmt"
-	"log"
-	"time"
-
-	"tickserver/api/lmaxapi"
-	"tickserver/api/lmaxapi/request"
-	"tickserver/api/lmaxapi/response"
-)
-
-// lmaxDS实现了dataSource接口, 并对lmax的历史数据和实时数据保存
-type LmaxDS struct {
-	*DSBase
-	errcount int64
-}
-
-func init() {
-	drivers[Lmax] = newLmaxDS
-}
-
-func newLmaxDS(conf *DsConf) (DataSource, error) {
-	return &LmaxDS{
-		DSBase: NewDsBase(conf), // lmax 自己下载历史数据, 所以参数db==nil
-	}, nil
-}
-
-func (lds *LmaxDS) Name() string {
-	return Lmax
-}
-
-func (lds *LmaxDS) Run() {
-	if !lds.conf.Run {
-		log.Println("LmaxDS.run config NOT run")
-		return
-	}
-	log.Println("LmaxDS.run")
-	// 此goroutine用来处理实时行情数据, 避免lmaxapi回调阻塞
-	eventCh := make(chan *response.OrderBookEvent, 4096)
-	go func() {
-		for {
-			ev := <-eventCh
-			lds.onMarket(ev)
-		}
-	}()
-	fn := func() {
-		for {
-			// 登录产生新的Session
-			ss, err := lds.login(lds.conf.User, lds.conf.PassWord, request.ProductType.CFD_LIVE, lds.conf.Url)
-			if err != nil {
-				time.Sleep(time.Second * 10)
-				continue
-			}
-			ss.RegisterSessionDisconnected(func(s *lmaxapi.Session) {
-				log.Println("session disconnected. STOP session!")
-				s.Stop()
-			})
-			lds.regStreamError(ss)
-			lds.marketdata(ss, eventCh) // 实时行情
-			ss.LoadAllInstruments(func(value *response.Instrument) {
-				lds.onInstrument(value)
-				log.Println("subcribe", value.Id)
-				ss.Subscribe(request.NewOrderBookSubscriptionRequest(value.Id), DefaultSubscribeCB)
-			})
-			ss.Wait()
-			ss.HeartbeatTimeout(5 * time.Second)
-			ss.Start()
-			// 有错误时跳出Start重启
-			log.Println("lmax session RESTART !!!")
-		}
-	}
-	fn()
-}
-
-func (lds *LmaxDS) doErrCode(s *lmaxapi.Session, err error) {
-	//1. 处理下面的事件
-	//1.1 网络中断:如果是交易,可能需要重新登录,以获取最新订单状态,如果是行情,可能不需要重启
-	//1.2 session 过期,发生403错误,必须重新登录
-	//1.3 heartbeat 心跳无响应:  Op=stream err=heart beart timeout, Code=-1
-	//    这个时候调用 session.StreamClose() 重新启动stream
-	operr, ok := err.(*lmaxapi.OpError)
-	log.Println("operr:", operr)
-	if !ok {
-		return
-	}
-	//1.2
-	if operr.Code == 403 {
-		log.Println("stop session")
-		s.Stop()
-		return
-	}
-	//1.1 and 1.3
-	//stream 中发生错误,重启stream, 如果是交易,可能要选择重启session
-	if operr.Op == "Stream" {
-		lds.errcount++
-		log.Println("stop stream")
-		if operr.Code == 0 {
-			time.Sleep(1 * time.Second)
-		}
-		if lds.errcount == 3 {
-			lds.errcount = 0
-			s.Stop()
-			return
-		}
-		s.StopStream()
-		// ss.Stop()
-		return
-	}
-}
-
-func (lds *LmaxDS) regStreamError(ss *lmaxapi.Session) {
-	// 注册数据流失败处理函数
-	ss.RegisterStreamFailureEvent(func(s *lmaxapi.Session, err error) {
-		lds.doErrCode(s, err)
-	})
-}
-
-
-func (lds *LmaxDS) login(name, password, typ, url string) (*lmaxapi.Session, error) {
-	log.Println("LmaxDS.login:", name)
-	lmaxapi.SetBaseUrl(url)
-	req := request.NewLoginRequest(name, password, typ)
-	ss, err := lmaxapi.Login(req)
-	if err != nil {
-		s := err.Error()
-		if len(s) > 32 {
-			s = s[:32]
-		}
-		log.Println("lmaxapi.Login error:", s)
-		return nil, err
-	}
-	log.Println(name, "login OK!")
-	return ss, nil
-}
-
-func (lds *LmaxDS) marketdata(session *lmaxapi.Session, eventCh chan *response.OrderBookEvent) {
-	log.Println("@@@:marketdata")
-	// 注册请求实时行情数据
-	session.RegisterOrderBookEvent(func(s *lmaxapi.Session, ev *response.OrderBookEvent) {
-		debugDelay("###:", fmt.Sprintf("lmax_%d", ev.InstrumentId), ev.Timestamp)
-		lds.errcount = 0
-		select {
-		case eventCh <- ev:
-		default:
-		}
-	})
-}
-
-func (lds *LmaxDS) onMarket(event *response.OrderBookEvent) {
-	insId := event.InstrumentId
-	mk := &Market{}
-	mk.InsId = insId
-	mk.Timestamp = event.Timestamp
-	mk.Type = IntLmax
-	if event.HasMarketClosePrice {
-		mk.Close = event.MktClosePrice
-		mk.Open = mk.Close
-	}
-	if event.HasLastTradedPrice {
-		mk.LastPrice = event.LastTradedPrice
-	}
-	if event.HasDailyHighestTradedPrice {
-		mk.High = event.DailyHighestTradedPrice
-	}
-	if event.HasDailyLowestTradedPrice {
-		mk.Low = event.DailyLowestTradedPrice
-	}
-	if len(event.AskPrices) > 0 {
-		asks := make([]PP, len(event.AskPrices))
-		for i, b := range event.AskPrices {
-			asks[i][0] = b.Price
-			asks[i][1] = b.Quantity
-		}
-		mk.Asks = asks
-	}
-	if len(event.BidPrices) > 0 {
-		bids := make([]PP, len(event.BidPrices))
-		for i, b := range event.BidPrices {
-			bids[i][0] = b.Price
-			bids[i][1] = b.Quantity
-		}
-		mk.Bids = bids
-	}
-	lds.Save(mk)
-}
-
-func (lds *LmaxDS) onInstrument(value *response.Instrument) {
-	ins := &Instrument{
-		Id:        value.Id,
-		Name:      value.Name,
-		ExId:      Lmax,
-		Type:      Forex,
-		PriceInc:  value.PriceIncrement,
-		Margin:    value.MarginRate,
-		StartTime: value.StartTime.Unix() * 1000, // ms
-	}
-	lds.insMap[ins.Id] = ins
-}
-
-func DefaultSubscribeCB(err error) {
-	if err != nil {
-		fmt.Println("Failed:", err)
-	}
-}

+ 0 - 27
server/tick/ds_lmax_test.go

@@ -1,27 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件测试lmax数据源接口
-
-import (
-	"log"
-	"testing"
-)
-
-func TestLmaxSubMarket(t *testing.T) {
-	lmaxConf := &DsConf{
-		User:     "wave3366",
-		PassWord: "Tg417395",
-		Url:      "https://trade.lmaxtrader.com",
-		SaveDir:  "./",
-		Run:      true,
-	}
-	ds , _  := newLmaxDS(lmaxConf)
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 240
server/tick/ds_oanda.go

@@ -1,240 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现oanda数据源的tick数据获取下载和保存
-
-import (
-	"errors"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"regexp"
-	"strconv"
-	"strings"
-	"time"
-
-	"tickserver/markinfo"
-	"tickserver/server/market"
-)
-
-type oandaPairStatistics struct {
-	Date       time.Time
-	BuyPercent float64
-	Rates      float64
-	Symbol     string
-}
-
-var oanda_base = int(200)
-
-var oanda_prev = make(map[string]*oandaPairStatistics)
-var fetchoandaurl = "http://fxtrade.oanda.com/lang/cns/analysis/open-position-ratios"
-
-func getOandaStatistics(ch chan<- *oandaPairStatistics) (err error) {
-	html, err := httpDownload(fetchoandaurl)
-	if err != nil {
-		return err
-	}
-	regex := regexp.MustCompile("(?is)<ol[\\s]+class=\"position-ratio-list\"[^>]*>(.*?)<\\/ol>")
-	matches := regex.FindAllStringSubmatch(html, -1)
-	if len(matches) != 2 {
-		return errors.New("regex matche error.")
-	}
-	//货币对--BuyPercent--SellPercent
-	ratio_graph := get_span(matches[0][0])
-	//货币对--Rates
-	rates := get_span(matches[1][0])
-	//精确到微妙
-	t := match_time(html)
-	if len(ratio_graph)%3 == 0 && len(rates)%2 == 0 && len(ratio_graph)/3 == len(rates)/2 {
-		for i := 0; i < len(ratio_graph)/3; i++ {
-			ops := &oandaPairStatistics{}
-			ops.Symbol = strings.Replace(ratio_graph[3*i], "/", "", -1)
-			ops.BuyPercent, _ = strconv.ParseFloat(ratio_graph[3*i+1], 64)
-			ops.Rates, _ = strconv.ParseFloat(rates[2*i+1], 64)
-			ops.Date = time.Unix(t/1000, (t%1000)*(1e6))
-			sendOanda(ch, ops)
-		}
-	} else {
-		return errors.New("invalid data.")
-	}
-	return
-}
-
-func sendOanda(ch chan<- *oandaPairStatistics, data *oandaPairStatistics) {
-	if prev_data, ok := oanda_prev[data.Symbol]; ok {
-		if *prev_data == *data {
-			return
-		}
-	}
-	// log.Println("oa client", data)
-	oanda_prev[data.Symbol] = data
-	select {
-	case ch <- data:
-	default:
-	}
-}
-
-func httpDownload(url string) (string, error) {
-	body, err := http.Get(url)
-	if err != nil {
-		fmt.Println(err)
-		return "", err
-	}
-	defer body.Body.Close()
-	b, err := ioutil.ReadAll(body.Body)
-	if err != nil {
-		fmt.Println(err)
-		return "", err
-	}
-	return string(b), nil
-}
-
-var timeregex = regexp.MustCompile("(?is)<input.*?id=\"generation-timestamp\".*?value=\"(\\d+)\".*?>")
-
-func match_time(html string) int64 {
-	result := timeregex.FindAllStringSubmatch(html, -1)
-	var time int64
-	if len(result) == 1 && len(result[0]) == 2 {
-		time, _ = strconv.ParseInt(result[0][1], 10, 64)
-	}
-	return time
-}
-
-var spanregex = regexp.MustCompile("(?is)<span[^>]+>.*?</span>")
-
-func get_span(text string) []string {
-	result := spanregex.FindAllString(text, -1)
-	for i := 0; i < len(result); i++ {
-		result[i] = strings.Trim(strip_tags(result[i]), " \t\r\n%")
-	}
-	return result
-}
-
-var stripregex = regexp.MustCompile("(?is)<[^>]+>")
-
-func strip_tags(text string) string {
-	return stripregex.ReplaceAllString(text, "")
-}
-
-var oandaInss = []string{
-	"EURCHF",
-	"XAGUSD",
-	"EURGBP",
-	"USDJPY",
-	"USDCAD",
-	"AUDJPY",
-	"USDCHF",
-	"XAUUSD",
-	"EURJPY",
-	"EURUSD",
-	"GBPCHF",
-	"AUDUSD",
-	"EURAUD",
-	"NZDUSD",
-	"GBPJPY",
-	"GBPUSD",
-}
-
-// OandaDS 实现数据源dataSource接口的定义
-type OandaDS struct {
-	*DSBase
-	conf *DsConf
-	//insMap map[string]*market.Instrument
-}
-
-func init() {
-	drivers[Oanda] = newOandaDS
-}
-
-func newOandaDS(conf *DsConf) (DataSource, error) {
-	log.Println("newOandaDS")
-	ods := &OandaDS{
-		DSBase: NewDsBase(conf),
-		conf:   conf,
-		//insMap: oandaInsMap(),
-	}
-	ods.insMap = oandaInsMap()
-	return ods, nil
-}
-
-func (ods *OandaDS) Name() string {
-	return Oanda
-}
-
-//func (ods *OandaDS) SubIns() *event.Event {
-//return ods.insPublisher.Event()
-//}
-
-func (ods *OandaDS) onMarket(ps *oandaPairStatistics) {
-	//insId := market.OandaPrefix + ps.Symbol
-	insId, _ := markinfo.SymbolId(ps.Symbol)
-	_, ok := ods.insMap[int64(insId)]
-	if !ok {
-		log.Fatal("OandaDS.onMarket error: insId is NOT in insMap:", insId)
-	}
-	//mk := ins.GetMk()
-	mk := &Market{}
-	mk.Type = IntOanda
-	mk.InsId = int64(insId)
-	mk.Timestamp = ps.Date.Unix() * 1000
-	mk.LastPrice = 100 - ps.BuyPercent
-	mk.LastVolume = 1
-	//ins.SetMk(mk)
-	ods.Save(mk)
-}
-
-/*func (ods *OandaDS) runHour() {
-	ht := time.Tick(time.Hour)
-	for _ = range ht {
-		for _, ins := range ods.insMap {
-			ods.Save(ins.GetMk())
-		}
-	}
-}*/
-
-func (ods *OandaDS) Run() {
-	log.Println("OandaDS.run")
-	//for _, ins := range ods.insMap {
-	//ods.insPublisher.Publish(ins)
-	//}
-	// go ods.runHour()
-	//go ods.RunSave(4)
-	ch := make(chan *oandaPairStatistics, 1024)
-	go func() {
-		for {
-			ps := <-ch
-			ods.onMarket(ps)
-		}
-	}()
-	for {
-		var err error
-		for {
-			err = getOandaStatistics(ch)
-			if err != nil {
-				log.Println(err)
-			}
-			time.Sleep(3 * time.Second)
-		}
-	}
-}
-
-func oandaInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, x := range oandaInss {
-		//id := market.OandaPrefix + x
-		id, _ := markinfo.SymbolId(x)
-		u, _ := markinfo.SymbolUint(x)
-		ins := &Instrument{
-			Id:        int64(id),
-			Name:      x,
-			ExId:      market.Oanda,
-			Type:      market.Forex,
-			PriceInc:  u,
-			StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}

+ 0 - 23
server/tick/ds_oanda_test.go

@@ -1,23 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestOanda(t *testing.T) {
-	conf := &DsConf{}
-	ds, _ := newOandaDS(conf) //, err
-	//if err != nil {
-	//t.Fatal(err)
-	//}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 244
server/tick/ds_polo.go

@@ -1,244 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-/*
-#include <string.h>
-*/
-import "C"
-
-// 本文件实现polo数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"errors"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"strconv"
-	"strings"
-	"time"
-	"tickserver/markinfo"
-	"tickserver/server/market"
-	"github.com/jcelliott/turnpike"
-)
-
-var poloInss = []int{
-	markinfo.BTCCNY,
-	markinfo.ETHCNY,
-	markinfo.ETCCNY,
-}
-
-// PoloDS实现了dataSource接口, 并对polo的历史数据和实时数据保存
-type PoloDS struct {
-	*DSBase
-	conf     *DsConf
-	client   *turnpike.Client
-	lastTime time.Time
-	usdcny   float64
-}
-
-func init() {
-	drivers[Polo] = newPoloDS
-}
-
-func newPoloDS(conf *DsConf) (DataSource, error) {
-	pds := &PoloDS{
-		DSBase: NewDsBase(conf),
-		conf:   conf,
-	}
-	pds.insMap = poloInsMap()
-
-	var err error
-	pds.usdcny, err = getUsdCny()
-	if err != nil || pds.usdcny < 1 || pds.usdcny > 100 {
-		return nil, err
-	} else {
-		log.Println("usdcny:", pds.usdcny)
-	}
-
-	return pds, nil
-}
-
-func (pds *PoloDS) Name() string {
-	return Polo
-}
-
-func (pds *PoloDS) Run() {
-	log.Println("PoloDS.Run")
-	go func() {
-		var err error
-		for {
-			time.Sleep(time.Second * 10)
-			pds.usdcny, err = getUsdCny()
-			if err != nil {
-				log.Println(err)
-			} else {
-				log.Println("usdcny:", pds.usdcny)
-			}
-		}
-	}()
-	err := pds.connect()
-	if err != nil {
-		log.Println("polods run:", err)
-	} else {
-		pds.lastTime = time.Now()
-	}
-	go pds.checkConnection()
-}
-
-func (pds *PoloDS) checkConnection() {
-	for {
-		time.Sleep(1 * time.Minute)
-		if time.Now().Sub(pds.lastTime) >= 2*time.Minute {
-			err := pds.connect()
-			if err != nil {
-				log.Println(err)
-			} else {
-				pds.lastTime = time.Now()
-			}
-		}
-	}
-}
-
-func (pds *PoloDS) process(args []interface{}, kwargs map[string]interface{}) {
-	pds.lastTime = time.Now()
-	var hrLowStr, hrHighStr, lastStr, currencyPairStr, lowestAskStr, highestBidStr, baseVolumeStr, quoteVolumeStr string
-	for i, v := range args {
-		s, ok := v.([]byte)
-		if ok {
-			switch i {
-			case 0:
-				currencyPairStr = string(s)
-			case 1:
-				lastStr = string(s)
-			case 2:
-				lowestAskStr = string(s)
-			case 3:
-				highestBidStr = string(s)
-			//case 4:
-			//percentChangeStr = string(s)
-			case 5:
-				baseVolumeStr = string(s)
-			case 6:
-				quoteVolumeStr = string(s)
-			//case 7:
-			//isFrozenStr = string(s)
-			case 8:
-				hrHighStr = string(s)
-			case 9:
-				hrLowStr = string(s)
-			}
-			if (currencyPairStr == "USDT_BTC" || currencyPairStr == "USDT_ETH" || currencyPairStr == "USDT_ETC") && len(lowestAskStr) > 0 && len(highestBidStr) > 0 {
-				mk := &Market{}
-				mk.Type = IntPolo
-				if currencyPairStr == "USDT_BTC" {
-					mk.InsId = markinfo.BTCCNY
-				}
-				if currencyPairStr == "USDT_ETH" {
-					mk.InsId = markinfo.ETHCNY
-				}
-				if currencyPairStr == "USDT_ETC" {
-					mk.InsId = markinfo.ETCCNY
-				}
-				now := time.Now()
-				mk.Timestamp = now.Unix()*int64(1000) + int64(now.Nanosecond()/1000000)
-				ask64, _ := strconv.ParseFloat(lowestAskStr, 64)
-				ask64 *= pds.usdcny
-				bid64, _ := strconv.ParseFloat(highestBidStr, 64)
-				bid64 *= pds.usdcny
-				basev, _ := strconv.ParseFloat(baseVolumeStr, 64)
-				quotev, _ := strconv.ParseFloat(quoteVolumeStr, 64)
-				last, _ := strconv.ParseFloat(lastStr, 64)
-				last *= pds.usdcny
-				high, _ := strconv.ParseFloat(hrHighStr, 64)
-				high *= pds.usdcny
-				low, _ := strconv.ParseFloat(hrLowStr, 64)
-				low *= pds.usdcny
-				var ask, bid PP
-				ask[0] = ask64
-				ask[1] = basev
-				bid[0] = bid64
-				bid[1] = basev
-				mk.Asks = append(mk.Asks, ask)
-				mk.Bids = append(mk.Bids, bid)
-				mk.High = high
-				mk.LastPrice = last
-				mk.Low = low
-				mk.AllVolume = quotev
-				pds.Save(mk)
-			}
-		}
-	}
-}
-
-func (pds *PoloDS) connect() (err error) {
-	if pds.client != nil {
-		pds.client.Close()
-	}
-	for i := 0; i < 10; i++ {
-		//pds.client, err = turnpike.NewWebsocketClient(turnpike.MSGPACK, "wss://api.poloniex.com", nil)
-		pds.client, err = turnpike.NewWebsocketClient(turnpike.MSGPACK, "wss://api.poloniex.com")
-		if err == nil {
-			break
-		}
-		time.Sleep(1 * time.Minute)
-	}
-	if err != nil {
-		log.Println("NewWebsocketClient", err)
-		return err
-	}
-	_, err = pds.client.JoinRealm("realm1", nil)
-	if err != nil {
-		log.Println("JoinRealm", err)
-		return err
-	}
-	err = pds.client.Subscribe("ticker", pds.process)
-	if err != nil {
-		log.Println("Subscribe", err)
-		return err
-	}
-
-	return nil
-}
-
-func poloInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, id := range poloInss {
-		x, _ := markinfo.SymbolName(id)
-		u, _ := markinfo.SymbolUint(x)
-		ins := &Instrument{
-			Id:        int64(id),
-			Name:      x,
-			ExId:      market.Polo,
-			Type:      market.Btcs,
-			PriceInc:  u,
-			StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}
-
-func getUsdCny() (float64, error) {
-	var price float64
-	url := "http://hq.sinajs.cn/rn=1488788247745list=fx_susdcny"
-	response, err := http.Get(url)
-	if err != nil {
-		return price, err
-	}
-	defer response.Body.Close()
-	body, err := ioutil.ReadAll(response.Body)
-	if err != nil {
-		return price, err
-	}
-	strs := strings.Split(string(body), ",")
-	if len(strs) > 1 {
-		price, err = strconv.ParseFloat(strs[1], 32)
-		if err != nil {
-			return price, err
-		}
-	} else {
-		return price, errors.New("invalid data")
-	}
-	return price, nil
-}

+ 0 - 26
server/tick/ds_polo_test.go

@@ -1,26 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestPolo(t *testing.T) {
-	conf := &DsConf{
-		Url:     "218.18.103.38:7709",
-		CfgFile: "serverlist.txt",
-	}
-	ds, err := newPoloDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(mk.InsId, mk.LastPrice)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 209
server/tick/ds_saxo.go

@@ -1,209 +0,0 @@
-// +build linux
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现盛宝saxo数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"encoding/csv"
-	"errors"
-	"log"
-	"os"
-	"strconv"
-	"strings"
-	"time"
-
-	"tickserver/api/saxocgo"
-	"tickserver/markinfo"
-	"tickserver/server/market"
-)
-
-type InsInfo struct {
-	Id        string
-	Name      string
-	ExId      string
-	PriceInc  float64
-	Margin    float64
-	StartTime string
-}
-
-// SaxoFixDS实现了dataSource接口, 并对fix的历史数据和实时数据保存
-type SaxoFixDS struct {
-	*DSBase
-	conf      *DsConf
-	symbolMap map[string]string
-	//insMap    map[int64]*market.Instrument
-}
-
-func init() {
-	drivers[Saxo] = newSaxoDS
-}
-
-func newSaxoDS(conf *DsConf) (DataSource, error) {
-	insMap, symbolMap, err := parseCSV(conf.SymbolsFile)
-	if err != nil {
-		return nil, err
-	}
-	sds := &SaxoFixDS{
-		DSBase:    NewDsBase(conf),
-		conf:      conf,
-		symbolMap: symbolMap,
-		//insMap:    insMap,
-	}
-	sds.insMap = insMap
-	return sds, nil
-}
-
-func parseCSV(name string) (map[int64]*Instrument, map[string]string, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, nil, err
-	}
-	r := csv.NewReader(f)
-	insMap := make(map[int64]*Instrument)
-	symbolMap := make(map[string]string)
-
-	first := true
-	for {
-		ss, err := r.Read()
-		if err != nil {
-			break
-		}
-		if len(ss) != 1 {
-			continue
-		}
-		if first {
-			first = false
-			continue
-		}
-		s := strings.Trim(ss[0], " ")
-		symbol := strings.Replace(s, "/", "", 1) // EUR/USD ==> EURUSD
-		id, err := markinfo.SymbolId(symbol)
-		if err != nil {
-			log.Println(err)
-			continue
-		}
-		unit, err := markinfo.SymbolUint(symbol)
-		if err != nil {
-			log.Println(err)
-			continue
-		}
-		symbolMap[strconv.Itoa(id)] = s
-		ins := &Instrument{
-			Id:        int64(id), //market.SaxoPrefix + symbol,
-			Name:      s,
-			ExId:      market.Saxo,
-			PriceInc:  unit,
-			Type:      market.Forex,
-			StartTime: time.Date(2014, 12, 31, 0, 0, 0, 0, time.Local).Unix() * 1000,
-		}
-		id64 := int64(id)
-		insMap[id64] = ins
-	}
-	return insMap, symbolMap, nil
-}
-
-//func (fds *SaxoFixDS) SubIns() *event.Event {
-//return fds.insPublisher.Event()
-//}
-
-func (fds *SaxoFixDS) Name() string {
-	return Saxo
-}
-
-func (fds *SaxoFixDS) Run() {
-	log.Println("SaxoFixDS.Run")
-
-	//for _, ins := range fds.insMap {
-	//log.Println("SaxoFixDS:", ins.Id, ins.Name)
-	//fds.insPublisher.Publish(ins)
-	//}
-
-	//go fds.RunSave(16)
-
-	fixApp := saxocgo.NewApp(fds.symbolMap, fds.conf.User, fds.conf.PassWord)
-	cfgFile := fds.conf.CfgFile
-	go fixApp.Run(cfgFile)
-
-	for fixTick := range fixApp.Ch {
-		m, err := fds.convMarket(fixTick)
-		if err != nil {
-			continue
-		}
-
-		ins, ok := fds.insMap[m.InsId]
-		if !ok {
-			log.Fatal("InsId is NOT in fds.insMap", m.InsId)
-		}
-		if m.Timestamp < ins.StartTime {
-			log.Println("error: m.Timestamp < ins.StartTime:", m.Timestamp, ins.StartTime)
-			continue
-		}
-
-		//ins.SetMk(m)
-		fds.Save(m)
-	}
-}
-
-func (fds *SaxoFixDS) convMarket(tick *saxocgo.FixTick) (*Market, error) {
-	if tick.AskCount == 0 && tick.BidCount == 0 {
-		return nil, errors.New("tick.AskCount==0 && tick.BidCount==0")
-	}
-	id := saxocgo.Symbol(tick.Symbol)
-	symbol, ok := fds.symbolMap[id]
-	if !ok {
-		return nil, errors.New("tick.Symbol NOT in symbolMap: " + id)
-	}
-	symbol = strings.Replace(symbol, "/", "", 1) // EUR/USD ==> EURUSD
-	//insId := market.SaxoPrefix + symbol
-	insId, _ := markinfo.SymbolId(symbol)
-	insId64 := int64(insId)
-	_, ok = fds.insMap[insId64]
-	if !ok {
-		log.Fatal("InsId is NOT in fds.insMap", insId)
-	}
-	//mk := ins.GetMk()
-	mk := &Market{}
-	mk.InsId = insId64
-	mk.Type = IntSaxo
-	for len(mk.Asks) < int(tick.AskCount) {
-		mk.Asks = append(mk.Asks, PP{})
-	}
-	for len(mk.Bids) < int(tick.BidCount) {
-		mk.Bids = append(mk.Bids, PP{})
-	}
-
-	for i := 0; i < int(tick.AskCount); i++ {
-		if tick.AskPrice[i] == 0 {
-			mk.Asks[i][0] = mk.Asks[i][0]
-		} else {
-			mk.Asks[i][0] = tick.AskPrice[i]
-		}
-		mk.Asks[i][1] = float64(tick.AskVolume[i])
-	}
-	for i := 0; i < int(tick.BidCount); i++ {
-		if tick.BidPrice[i] == 0 {
-			mk.Bids[i][0] = mk.Bids[i][0]
-		} else {
-			mk.Bids[i][0] = tick.BidPrice[i]
-		}
-		mk.Bids[i][1] = float64(tick.BidVolume[i])
-	}
-	lastPrice := 0.
-	vol := 0.
-	if len(mk.Bids) > 0 {
-		lastPrice = mk.Bids[0][0]
-		vol = mk.Bids[0][1]
-	}
-	if lastPrice == 0. {
-		if len(mk.Asks) > 0 {
-			lastPrice = mk.Asks[0][0]
-			vol = mk.Asks[0][1]
-		}
-	}
-	mk.LastPrice = lastPrice
-	mk.LastVolume = vol
-	mk.Timestamp = int64(tick.Time)*1000 + int64(tick.Millisecond)
-	return mk, nil
-}

+ 0 - 27
server/tick/ds_saxo_test.go

@@ -1,27 +0,0 @@
-// +build linux
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestSaxo(t *testing.T) {
-	conf := &DsConf{
-		CfgFile:     "saxo-mk.cfg",
-		SymbolsFile: "saxo-symbols.csv",
-	}
-	ds, err := newSaxoDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 442
server/tick/ds_sina.go

@@ -1,442 +0,0 @@
-package tick
-
-import "net/http"
-import "io/ioutil"
-import "regexp"
-import "strings"
-import "bytes"
-import "errors"
-import "fmt"
-import "strconv"
-import "time"
-import "log"
-import "golang.org/x/text/encoding/simplifiedchinese"
-
-var symbolurl = "http://quote.eastmoney.com/stock_list.html"
-var lastMarket map[string]string
-
-func GetInstrument() ([]string, []string, error) {
-	return getInstrument()
-}
-
-func getInstrument() ([]string, []string, error) {
-	resp, err := http.Get(symbolurl)
-	if err != nil {
-		return nil, nil, err
-	}
-	defer resp.Body.Close()
-	data, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, nil, err
-	}
-	symbolcontent := bytes.SplitN(data, []byte(`<div id="quotesearch">`), 2)
-	if len(symbolcontent) != 2 {
-		return nil, nil, errors.New("no symbolcontent-0")
-	}
-	symbolcontent = bytes.SplitN(symbolcontent[1], []byte("</ul>"), 3)
-	if len(symbolcontent) != 3 {
-		return nil, nil, errors.New("no symbolcontent-1")
-	}
-	//sh symbol list
-	shlist, err := getli(symbolcontent[0])
-	if err != nil {
-		return nil, nil, err
-	}
-	//sz
-	szlist, err := getli(symbolcontent[1])
-	if err != nil {
-		return nil, nil, err
-	}
-	var sh []string
-	for i := 0; i < len(shlist); i++ {
-		sym , _ := getsymbol(string(shlist[i]))
-		sh = append(sh, sym)
-	}
-	var sz []string
-	for i := 0; i < len(szlist); i++ {
-		sym, _ := getsymbol(string(szlist[i]))
-		sz = append(sz, sym)
-	}
-	return sh, sz, nil
-}
-
-func GetInstrument2() ([]string, []string, []string, []string, error) {
-	resp, err := http.Get(symbolurl)
-	if err != nil {
-		return nil, nil,nil, nil, err
-	}
-	defer resp.Body.Close()
-	data, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		return nil, nil, nil, nil, err
-	}
-	symbolcontent := bytes.SplitN(data, []byte(`<div id="quotesearch">`), 2)
-	if len(symbolcontent) != 2 {
-		return nil, nil, nil, nil, errors.New("no symbolcontent-0")
-	}
-	symbolcontent = bytes.SplitN(symbolcontent[1], []byte("</ul>"), 3)
-	if len(symbolcontent) != 3 {
-		return nil, nil, nil, nil, errors.New("no symbolcontent-1")
-	}
-	//sh symbol list
-	shlist, err := getli(symbolcontent[0])
-	if err != nil {
-		return nil, nil, nil, nil, err
-	}
-	//sz
-	szlist, err := getli(symbolcontent[1])
-	if err != nil {
-		return nil, nil, nil ,nil, err
-	}
-	var sh []string
-	var shname []string
-    trans := simplifiedchinese.GBK.NewDecoder()
-	dst := make([]byte, 1024)
-	
-	for i := 0; i < len(shlist); i++ {
-		symbol, name := getsymbol(string(shlist[i]))
-		sh = append(sh, symbol)
-		nDst, _, err := trans.Transform(dst, []byte(name), true)
-		if err == nil {
-			name = string(dst[0:nDst])
-		}
-		shname = append(shname, name)
-	}
-	var sz []string
-	var szname []string
-	for i := 0; i < len(szlist); i++ {
-		symbol, name := getsymbol(string(szlist[i]))
-		sz = append(sz, symbol)
-		nDst, _, err := trans.Transform(dst, []byte(name), true)
-		if err == nil {
-			name = string(dst[0:nDst])
-		}
-		szname = append(szname, name)
-	}
-	return sh, sz, shname, szname, nil
-}
-
-func getli(data []byte) ([][]byte, error) {
-	return matchTag(data, "li")
-}
-
-func getsymbol(data string) (string, string) {
-	data = stripTags(data)
-	o, _, err := strRange(data, "(", ")", 0)
-	if err != nil {
-		return "", ""
-	}
-	name := strings.Replace(data, "("+o+")", "", -1)
-	return o, name
-}
-
-func strRange(html string, start string, end string, offset int) (string, int, error) {
-	istart := strings.SplitN(html, start, 2)
-	if len(istart) != 2 {
-		return "", 0, errors.New("start string not found")
-	}
-	if offset > 0 {
-		istart[1] = istart[1][offset:]
-	}
-	iend := strings.SplitN(istart[1], end, 2)
-	if len(iend) != 2 {
-		return "", 0, errors.New("end string not found")
-	}
-	return iend[0], len(istart[0]) + len(iend[0]), nil
-}
-
-func matchTag(html []byte, tagname string) ([][]byte, error) {
-	exp, err := regexp.Compile("(?i)<" + tagname + "[^>]*>(.*?)</" + tagname + ">")
-	if err != nil {
-		return nil, err
-	}
-	matched := exp.FindAllSubmatch(html, -1)
-	if len(matched) == 0 {
-		return nil, fmt.Errorf("tagname=%s not matched", tagname)
-	}
-	ret := make([][]byte, len(matched))
-	for i := 0; i < len(ret); i++ {
-		ret[i] = matched[i][1]
-	}
-	return ret, nil
-}
-
-var tagsRegexp = regexp.MustCompile("<[^>]+>")
-
-func stripTags(html string) string {
-	return tagsRegexp.ReplaceAllString(html, "")
-}
-
-type SinaDS struct {
-	*DSBase
-}
-
-func init() {
-	drivers[Sina] = newSinaDS
-}
-
-func newSinaDS(conf *DsConf) (DataSource, error) {
-	return &SinaDS{
-		DSBase: NewDsBase(conf), // lmax 自己下载历史数据, 所以参数db==nil
-	}, nil
-}
-
-func (lds *SinaDS) Name() string {
-	return Sina
-}
-
-func (lds *SinaDS) Run() {
-	if !lds.conf.Run {
-		log.Println("SinaDS.run config NOT run")
-		return
-	}
-	log.Println("SinaDS.run")
-	fn := func() {
-		var urls []string
-		for {
-			sh, sz, err := getInstrument()
-			if err != nil {
-				time.Sleep(time.Second)
-				continue
-			}
-			urls = getfetchurls(sh, sz)
-			break
-		}
-		lastMarket = make(map[string]string)
-		datach := make(chan []string, 20)
-		// 登录产生新的Session
-		for i := 0; i < len(urls); i++ {
-			go func(n int) {
-				for {
-					fetchurl(IntSina, urls[n], datach)
-					time.Sleep(time.Millisecond * 200)
-				}
-			}(i)
-		}
-		for {
-			item := <-datach
-			newdata := getnewdata(IntSina, item)
-			for i := 0; i < len(newdata); i++ {
-				lds.Save(newdata[i])
-			}
-		}
-	}
-	fn()
-}
-
-func getfetchurls(sh []string, sz []string) []string {
-	baseurl := "http://hq.sinajs.cn/list="
-	for i := 0; i < len(sh); i++ {
-		sh[i] = "sh" + sh[i]
-	}
-	for i := 0; i < len(sz); i++ {
-		sz[i] = "sz" + sz[i]
-	}
-	sh = append(sh, sz...)
-	var ret []string
-	for i := 0; i < len(sh); i = i + 200 {
-		end := 200
-		if i+200 > len(sh) {
-			end = len(sh) - i
-		}
-		data := sh[i : i+end]
-		query := strings.Join(data, ",")
-		ret = append(ret, baseurl+query)
-	}
-	return ret
-}
-
-func fetchurl(typ int, url string, ch chan []string) {
-	if typ == IntSinaFuture {
-		//log.Println("sinafuture fetchurl begin")
-	}
-	resp, err := http.Get(url)
-	if err != nil {
-		ch <- nil
-		log.Println("fetchurl get", err)
-		return
-	}
-	defer resp.Body.Close()
-	data, err := ioutil.ReadAll(resp.Body)
-	if err != nil {
-		ch <- nil
-		log.Println("fetchurl readall", err)
-		return
-	}
-	tickdatas := parsetick(string(data))
-	ch <- tickdatas
-	if typ == IntSinaFuture {
-		//log.Println("sinafuture fetchurl end")
-	}
-}
-
-func parsetick(data string) []string {
-	return strings.Split(data, "\n")
-}
-
-func getnewdata(typ int, datas []string) []*Market {
-	var ret []*Market
-	for i := 0; i < len(datas); i++ {
-		datas[i] = strings.Replace(datas[i], "var hq_str_", "", -1)
-		marketdata := strings.SplitN(datas[i], "=", 2)
-		if len(marketdata) != 2 {
-			continue
-		}
-		if lastdata, ok := lastMarket[marketdata[0]]; ok {
-			if lastdata == marketdata[1] {
-				if typ == IntSinaFuture {
-					//log.Println("sinafuture same")
-				}
-				continue
-			}
-		}
-		lastMarket[marketdata[0]] = marketdata[1]
-		var market *Market
-		var err error
-		if typ == IntSina {
-			market, err = parsemarket(marketdata[0], marketdata[1])
-		} else {
-			market, err = parsemarketfuture(marketdata[0], marketdata[1])
-		}
-		if err != nil {
-			log.Println(datas[i], err)
-			continue
-		}
-		ret = append(ret, market)
-	}
-	return ret
-}
-
-func parsemarket(name string, data string) (*Market, error) {
-	data = strings.Trim(data, "\";\r\n")
-	datas := strings.Split(data, ",")
-	if len(datas) < 32 {
-		return nil, errors.New("makret data error")
-	}
-	var market Market
-	var err error
-	market.Open, err = strconv.ParseFloat(datas[1], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.LastPrice, err = strconv.ParseFloat(datas[2], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Close, err = strconv.ParseFloat(datas[3], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.High, err = strconv.ParseFloat(datas[4], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Low, err = strconv.ParseFloat(datas[5], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.AllVolume, err = strconv.ParseFloat(datas[8], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.AllAmount, err = strconv.ParseFloat(datas[9], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids := make([]PP, 5)
-	bids[0][1], err = strconv.ParseFloat(datas[10], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[0][0], err = strconv.ParseFloat(datas[11], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[1][1], err = strconv.ParseFloat(datas[12], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[1][0], err = strconv.ParseFloat(datas[13], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[2][1], err = strconv.ParseFloat(datas[14], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[2][0], err = strconv.ParseFloat(datas[15], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[3][1], err = strconv.ParseFloat(datas[16], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[3][0], err = strconv.ParseFloat(datas[17], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[4][1], err = strconv.ParseFloat(datas[18], 64)
-	if err != nil {
-		return nil, err
-	}
-	bids[4][0], err = strconv.ParseFloat(datas[19], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Bids = bids
-	asks := make([]PP, 5)
-	asks[0][1], err = strconv.ParseFloat(datas[20], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[0][0], err = strconv.ParseFloat(datas[21], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[1][1], err = strconv.ParseFloat(datas[22], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[1][0], err = strconv.ParseFloat(datas[23], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[2][1], err = strconv.ParseFloat(datas[24], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[2][0], err = strconv.ParseFloat(datas[25], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[3][1], err = strconv.ParseFloat(datas[26], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[3][0], err = strconv.ParseFloat(datas[27], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[4][1], err = strconv.ParseFloat(datas[28], 64)
-	if err != nil {
-		return nil, err
-	}
-	asks[4][0], err = strconv.ParseFloat(datas[29], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Asks = asks
-	t, err := time.Parse(time.RFC3339, datas[30]+"T"+datas[31]+"+08:00")
-	if err != nil {
-		return nil, err
-	}
-	market.Timestamp = t.Unix() * 1000
-	name = name[2:]
-	market.InsId, err = strconv.ParseInt(name, 10, 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Type = IntSina
-	return &market, nil
-}

+ 0 - 208
server/tick/ds_sina_future.go

@@ -1,208 +0,0 @@
-package tick
-
-import "strings"
-import "errors"
-import "strconv"
-
-import "time"
-import "log"
-
-type SinaFutureDS struct {
-	*DSBase
-}
-
-var sinaFutureSymbols []string
-
-func init() {
-	drivers[SinaFuture] = newSinaFutureDS
-}
-
-func newSinaFutureDS(conf *DsConf) (DataSource, error) {
-	return &SinaFutureDS{
-		DSBase: NewDsBase(conf), // lmax 自己下载历史数据, 所以参数db==nil
-	}, nil
-}
-
-func (lds *SinaFutureDS) Name() string {
-	return SinaFuture
-}
-
-func (lds *SinaFutureDS) Run() {
-	if !lds.conf.Run {
-		log.Println("SinaFutureDS.run config NOT run")
-		return
-	}
-	log.Println("SinaFutureDS.run")
-	for i, _ := range SinaFutureSymbols {
-		sinaFutureSymbols = append(sinaFutureSymbols, i)
-	}
-	fn := func() {
-		url := getfetchurl()
-		lastMarket = make(map[string]string)
-		datach := make(chan []string, 20)
-		// 登录产生新的Session
-		go func() {
-			for {
-				fetchurl(IntSinaFuture, url, datach)
-				time.Sleep(time.Millisecond * 200)
-			}
-		}()
-		for {
-			item := <-datach
-			//log.Println("sinafuture parse begin")
-			newdata := getnewdata(IntSinaFuture, item)
-			for i := 0; i < len(newdata); i++ {
-				//log.Println("sinafuture save begin")
-				lds.Save(newdata[i])
-			}
-		}
-	}
-	fn()
-}
-
-func getfetchurl() string {
-	baseurl := "http://hq.sinajs.cn/list="
-	query := strings.Join(sinaFutureSymbols, ",")
-	return baseurl + query
-}
-
-func parsemarketfuture(name string, data string) (*Market, error) {
-	data = strings.Trim(data, "\";\r\n")
-	datas := strings.Split(data, ",")
-	if len(datas) < 27 {
-		return nil, errors.New("makret data error")
-	}
-	var market Market
-	var err error
-	market.Open, err = strconv.ParseFloat(datas[2], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.LastPrice, err = strconv.ParseFloat(datas[8], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Close, err = strconv.ParseFloat(datas[5], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.High, err = strconv.ParseFloat(datas[3], 64)
-	if err != nil {
-		return nil, err
-	}
-	market.Low, err = strconv.ParseFloat(datas[4], 64)
-	if err != nil {
-		return nil, err
-	}
-	//market.AllVolume, err = strconv.ParseFloat(datas[8], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//market.AllAmount, err = strconv.ParseFloat(datas[9], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	bids := make([]PP, 5)
-	//bids[0][1], err = strconv.ParseFloat(datas[10], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	bids[0][0], err = strconv.ParseFloat(datas[7], 64)
-	if err != nil {
-		return nil, err
-	}
-	//bids[1][1], err = strconv.ParseFloat(datas[12], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[1][0], err = strconv.ParseFloat(datas[13], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[2][1], err = strconv.ParseFloat(datas[14], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[2][0], err = strconv.ParseFloat(datas[15], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[3][1], err = strconv.ParseFloat(datas[16], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[3][0], err = strconv.ParseFloat(datas[17], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[4][1], err = strconv.ParseFloat(datas[18], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//bids[4][0], err = strconv.ParseFloat(datas[19], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	market.Bids = bids
-	asks := make([]PP, 5)
-	//asks[0][1], err = strconv.ParseFloat(datas[6], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	asks[0][0], err = strconv.ParseFloat(datas[6], 64)
-	if err != nil {
-		return nil, err
-	}
-	//asks[1][1], err = strconv.ParseFloat(datas[22], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[1][0], err = strconv.ParseFloat(datas[23], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[2][1], err = strconv.ParseFloat(datas[24], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[2][0], err = strconv.ParseFloat(datas[25], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[3][1], err = strconv.ParseFloat(datas[26], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[3][0], err = strconv.ParseFloat(datas[27], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[4][1], err = strconv.ParseFloat(datas[28], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	//asks[4][0], err = strconv.ParseFloat(datas[29], 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	market.Asks = asks
-	//t, err := time.Parse(time.RFC3339, datas[30]+"T"+datas[31]+"+08:00")
-	//if err != nil {
-	//return nil, err
-	//}
-	//market.Timestamp = t.Unix() * 1000
-	market.Timestamp = time.Now().Unix() * 1000
-	//name = name[2:]
-	//market.InsId, err = strconv.ParseInt(name, 10, 64)
-	//if err != nil {
-	//return nil, err
-	//}
-	var id int
-	var ok bool
-	if id, ok = SinaFutureSymbols[name]; !ok {
-		return nil, err
-	}
-	market.InsId = 1000000 + int64(id)
-	market.Type = IntSinaFuture
-	return &market, nil
-}

+ 0 - 29
server/tick/ds_sina_future_test.go

@@ -1,29 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestSinFuture(t *testing.T) {
-	sinaConf := &DsConf{
-		User:     "",
-		PassWord: "",
-		Url:      "http://hq.sinajs.cn/list",
-		SaveDir:  "./",
-		Run:      true,
-	}
-	ds, _ := newSinaFutureDS(sinaConf) //, err
-	//if err != nil {
-	//t.Fatal(err)
-	//}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 32
server/tick/ds_sina_test.go

@@ -1,32 +0,0 @@
-package tick
-
-import (
-	"log"
-	"testing"
-)
-
-func TestGetInstrument(t *testing.T)  {
-    sh, sz, err := getInstrument()
-    if err != nil {
-        t.Error(err)
-        return
-    }
-    log.Println(sh, sz)
-}
-
-func TestSina(t *testing.T) {
-	sinaConf := &DsConf{
-		User:     "",
-		PassWord: "",
-		Url:      "http://hq.sinajs.cn/list",
-		SaveDir:  "./",
-		Run:      true,
-	}
-	ds , _:= newSinaDS(sinaConf)
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 880
server/tick/ds_tdx.go

@@ -1,880 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-/*
-#include <string.h>
-*/
-import "C"
-
-// 本文件实现大智慧数据源接口, 实时数据和历史数据的获取和保存
-
-import (
-	"bytes"
-	"compress/zlib"
-	"container/list"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"log"
-	"net"
-	"os"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-	"unsafe"
-	"tickserver/server/market"
-
-	"golang.org/x/text/encoding/simplifiedchinese"
-)
-
-const (
-	STOCK_PER_SERVER      = 50
-	FETCH_PER_MILLISECOND = 100
-)
-
-type RecvDataHeader struct {
-	CheckSum   int32
-	EncodeMode byte
-	Tmp        [5]byte
-	Msgid      int16
-	Size       int16
-	DePackSize int16
-}
-
-// 公司资料原始数据
-type TdxStockInfo struct { // 初始化数据 29字节
-	Code     [6]byte //代码
-	Rate     int16   // 实时盘口中的成交量除去的除数?1手=n股?
-	Name     [8]byte //名称
-	W1       int16   //w1 为5日平均量(用于量比计算)
-	W2       int16
-	PriceMag byte    //小数点位数
-	YClose   float32 //昨收
-	W3       int16
-	W4       int16
-}
-
-//权息
-type QuanInfo struct {
-	style byte
-	day   int32
-	q1    float32
-	q2    float32
-	q3    float32
-	q4    float32
-	//style=1  (除权除息)   (送现金,配股价,送股数,配股比例);
-	//style=2  (送配股上市)
-	//style=9  (转配股上市) (股本变化) Q1=前流通盘 Q2=前总股本 Q3=后流通盘  Q4=后总股本
-	//style=3  (非流通股上市) 前流通盘 前总股本 后流通盘 后总股本
-	//	 3 送现金:3499.00 配股价:17468.00 送股数:4368.00 配股比例:17468.00
-	// 权息日  类别      送转股 分红 配股 配股价   前流通盘   后流通盘   前总股本   后总股本
-	//20120618 非流通股上市                           3499.0     4368.0    17468.0    17468.0
-	//style=5  (股本变化)前流通盘 前总股本 后流通盘 后总股本
-	// 权息日  类别      送转股 分红 配股 配股价   前流通盘   后流通盘   前总股本   后总股本
-	//20120316 股本变化                                 0.0     3499.0        0.0    17468.0
-	//0 002663 Date:20120316  5 送现金: 0.00 配股价: 0.00 送股数:3499.00 配股比例:17468.00
-}
-
-type CaiWu struct {
-	Mark byte
-	code [6]byte
-	LTG  float32 //流通股数量
-	t1   int16
-	t2   int16
-	day1 int32
-	day2 int32
-	zl   [30]float32
-}
-
-type Stock struct {
-	no      int32 //no=mark*1000000+code;
-	szOrsh  byte
-	quanlen int //权息长度
-	gp      TdxStockInfo
-	quan    [80]QuanInfo
-	cw      CaiWu
-}
-
-// TdxDS实现了dataSource接口, 并对tdx的历史数据和实时数据保存
-type TdxDS struct {
-	*DSBase
-	conf              *DsConf
-	datetime          uint32
-	stocks            map[string]*Stock
-	servers           []string
-	serverlist        *list.List
-	symbolsGroup      [][STOCK_PER_SERVER]string
-	exsGroup          [][STOCK_PER_SERVER]byte
-	conn              net.Conn
-	instrumentUpdated bool
-	goroutineNum      int
-	statusCh          chan int
-	mu                sync.Mutex
-}
-
-func init() {
-	drivers[Tdx] = newTdxDS
-}
-
-func newTdxDS(conf *DsConf) (DataSource, error) {
-	tds := &TdxDS{
-		DSBase:            NewDsBase(conf),
-		conf:              conf,
-		stocks:            make(map[string]*Stock),
-		serverlist:        list.New(),
-		instrumentUpdated: false,
-		statusCh:          make(chan int, 1),
-	}
-	var err error
-	tds.servers, err = loadServers(conf.CfgFile)
-	if err != nil {
-		return nil, err
-	}
-	for _, v := range tds.servers {
-		tds.serverlist.PushBack(v)
-	}
-	err = tds.getConn()
-	if err != nil {
-		return nil, err
-	}
-	err = tds.getInstrument(0)
-	if err != nil {
-		return nil, err
-	}
-	err = tds.getInstrument(1)
-	if err != nil {
-		return nil, err
-	}
-	tds.conn.Close()
-	i := 0
-	var symbols [STOCK_PER_SERVER]string
-	var exs [STOCK_PER_SERVER]byte
-	for k, v := range tds.stocks {
-		symbols[i] = k
-		exs[i] = v.szOrsh
-		i++
-		if i >= STOCK_PER_SERVER {
-			i = 0
-			tds.symbolsGroup = append(tds.symbolsGroup, symbols)
-			tds.exsGroup = append(tds.exsGroup, exs)
-		}
-	}
-	if i > 0 {
-		for j := i; j < STOCK_PER_SERVER; j++ {
-			symbols[j] = ""
-		}
-		tds.symbolsGroup = append(tds.symbolsGroup, symbols)
-		tds.exsGroup = append(tds.exsGroup, exs)
-	}
-
-	return tds, nil
-}
-
-func (tds *TdxDS) Name() string {
-	return Tdx
-}
-
-func (tds *TdxDS) Run() {
-	log.Println("TdxDS.Run")
-	//tds.stocks["000001"] = &Stock{}
-	//tds.readTick(tds.conn, 0, "000001")
-	//var symbols = [STOCK_PER_SERVER]string{"000716", "002216", "002329", "002481", "002495", "002507", "002570", "002626", "002650", "002661", "002719", "002732", "300146", "300149", "300381", "300401", "600073", "600186", "600298", "600305", "600419", "600429", "600597", "600866", "600872", "600873", "600887", "603020", "603288", "000019", "000557", "000568", "000596", "000729", "000752", "000799", "000848", "000858", "000869", "000929", "000995", "002304", "002387", "002461", "002646", "600059", "600084", "600090", "600132", "600197"}
-	//var exs = [STOCK_PER_SERVER]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
-	//tds.readTicks(symbols, exs)
-	go tds.updateInstruments()
-	tds.fetchMarket()
-}
-
-func (tds *TdxDS) fetchMarket() {
-	for i, v := range tds.symbolsGroup {
-		go tds.readTicks(v, tds.exsGroup[i])
-		tds.goroutineNum++
-	}
-
-}
-
-func (tds *TdxDS) updateInstruments() {
-	var err error
-	ticker := time.Tick(time.Second * 30)
-	for t := range ticker {
-		if t.Hour() == 7 && t.Minute() == 0 { // 7:00重新连接服务器和获得股票信息
-			tds.getConn()
-			err = tds.getInstrument(0)
-			if err != nil {
-				log.Println(err)
-			}
-			err = tds.getInstrument(1)
-			if err != nil {
-				log.Println(err)
-			}
-			tds.conn.Close()
-			i := 0
-			tds.symbolsGroup = nil
-			tds.exsGroup = nil
-			var symbols [STOCK_PER_SERVER]string
-			var exs [STOCK_PER_SERVER]byte
-			for k, v := range tds.stocks {
-				symbols[i] = k
-				exs[i] = v.szOrsh
-				i++
-				if i >= STOCK_PER_SERVER {
-					i = 0
-					tds.symbolsGroup = append(tds.symbolsGroup, symbols)
-					tds.exsGroup = append(tds.exsGroup, exs)
-				}
-			}
-			if i > 0 {
-				for j := i; j < STOCK_PER_SERVER; j++ {
-					symbols[j] = ""
-				}
-				tds.symbolsGroup = append(tds.symbolsGroup, symbols)
-				tds.exsGroup = append(tds.exsGroup, exs)
-			}
-			log.Println("updateInstruments begin")
-			tds.instrumentUpdated = true
-			for m := 0; m < tds.goroutineNum; m++ { //等待readTicks结束
-				<-tds.statusCh
-			}
-			log.Println("updateInstruments end")
-			tds.goroutineNum = 0
-			tds.instrumentUpdated = false
-			tds.fetchMarket()
-		}
-	}
-}
-
-func (tds *TdxDS) getTickConn() net.Conn {
-	servernum := len(tds.servers)
-	count := 0
-	for {
-		tds.mu.Lock()
-		e := tds.serverlist.Front()
-		server := tds.serverlist.Remove(e)
-		tds.serverlist.PushBack(server)
-		tds.mu.Unlock()
-		count++
-		if count > servernum {
-			return nil
-		}
-		conn, err := net.DialTimeout("tcp", server.(string), 5*time.Second)
-		if err != nil {
-			log.Println(server.(string), err)
-			continue
-		}
-		conn.(*net.TCPConn).SetDeadline(time.Now().Add(5 * time.Second))
-
-		_, err = conn.Write([]byte("\x0C\x02\x18\x93\x00\x01\x03\x00\x03\x00\x0D\x00\x01"))
-		if err != nil {
-			log.Println(server.(string), err)
-			continue
-		}
-		_, err = readBuf(conn)
-		if err != nil {
-			log.Println(server.(string), err)
-			continue
-		}
-		//tds.datetime = binary.LittleEndian.Uint32(debuf[42:46])
-		//log.Println("最后交易日:", tds.datetime)
-		//log.Println("服务器名称:", decodeString(debuf[68:]))
-
-		return conn
-	}
-	return nil
-}
-
-func (tds *TdxDS) getConn() error {
-	for _, v := range tds.servers {
-		conn, err := net.DialTimeout("tcp", v, 5*time.Second)
-		if err != nil {
-			log.Println(v, err)
-			continue
-		}
-		conn.(*net.TCPConn).SetDeadline(time.Now().Add(5 * time.Second))
-
-		_, err = conn.Write([]byte("\x0C\x02\x18\x93\x00\x01\x03\x00\x03\x00\x0D\x00\x01"))
-		if err != nil {
-			log.Println(v, err)
-			continue
-		}
-		debuf, err := readBuf(conn)
-		if err != nil {
-			log.Println(v, err)
-			continue
-		}
-		tds.datetime = binary.LittleEndian.Uint32(debuf[42:46])
-		log.Println("最后交易日:", tds.datetime)
-		log.Println("服务器名称:", decodeString(debuf[68:]))
-
-		tds.conn = conn
-		return nil
-	}
-	return errors.New("no conn available")
-}
-
-func decodeString(debuf []byte) string {
-	var name []byte
-	for i := 0; i < len(debuf); i++ {
-		if int(debuf[i]) == 0 {
-			name = debuf[0:i]
-			break
-		}
-	}
-	trans := simplifiedchinese.GBK.NewDecoder()
-	dst := make([]byte, 1024)
-	nDst, _, err := trans.Transform(dst, name, true)
-	if err != nil {
-		panic(err)
-	}
-	return string(dst[0:nDst])
-}
-
-func (tds *TdxDS) getInstrument(szOrsh byte) error {
-	log.Println("getInstrument", szOrsh)
-	bb := []byte("\x0C\x0C\x18\x6C\x00\x01\x08\x00\x08\x00\x4E\x04\xFF\x00\x01\x02\x03\x04") //取得股票数量
-	bb[12] = szOrsh                                                                          //0深圳 1上海
-	wlen := len(bb)
-	buf := bytes.NewBuffer(bb[14:])
-	buf.Reset()
-	binary.Write(buf, binary.LittleEndian, &tds.datetime)
-	wlen, err := tds.conn.Write(bb[:wlen])
-	if err != nil {
-		return err
-	}
-	debuf, err := readBuf(tds.conn)
-	if err != nil {
-		return err
-	}
-	szcount := binary.LittleEndian.Uint16(debuf[:])
-	//log.Println(wlen, szcount)
-	trans := simplifiedchinese.GBK.NewDecoder()
-	dst := make([]byte, 1024)
-
-	var count uint16
-	for count < szcount {
-		bb11 := []byte("\x0C\x01\x18\x64\x01\x01\x06\x00\x06\x00\x50\x04\xFF\x00\xF2\xF3")
-		bb11[12] = szOrsh
-		wlen := len(bb11)
-		buf := bytes.NewBuffer(bb11[14:])
-		buf.Reset()
-		binary.Write(buf, binary.LittleEndian, &count)
-		wlen, err := tds.conn.Write(bb11[:wlen])
-		if err != nil {
-			continue
-		}
-		debuf, err := readBuf(tds.conn)
-		if err != nil {
-			return err
-		}
-		n := binary.LittleEndian.Uint16(debuf[:])
-		stockInfoSize := int(unsafe.Sizeof(TdxStockInfo{}))
-		stockInfoSize = 29
-		var stock Stock
-		for j := 0; j < int(n); j++ {
-			buf := bytes.NewBuffer(debuf[2+j*stockInfoSize:])
-			binary.Read(buf, binary.LittleEndian, &stock.gp)
-			codeStr := string(stock.gp.Code[:])
-			no, _ := strconv.Atoi(codeStr)
-			stock.no = int32(no)
-			stock.szOrsh = szOrsh
-			_, ok := tds.stocks[codeStr]
-			if !ok {
-				tds.stocks[codeStr] = &stock
-				ins, ok1 := tds.insMap[int64(stock.no)]
-				if !ok1 {
-					exid := SHEX
-					if szOrsh == 0 {
-						exid = SZEX
-					}
-					priceInc := float64(1.0)
-					for i := 0; i < int(stock.gp.PriceMag); i++ {
-						priceInc /= 10
-					}
-					nDst, _, _ := trans.Transform(dst, stock.gp.Name[:], true)
-					ins = &Instrument{
-						Id:       int64(stock.no),
-						Name:     string(dst[0:nDst]),
-						Type:     market.Securities,
-						ExId:     exid,
-						PriceInc: priceInc,
-					}
-					tds.insMap[ins.Id] = ins
-					//log.Println(ins)
-				}
-			}
-
-			count++
-		}
-	}
-	return nil
-}
-
-func (tds *TdxDS) readTicks(symbols [STOCK_PER_SERVER]string, exs [STOCK_PER_SERVER]byte) {
-	conn := tds.getTickConn()
-	if conn == nil {
-		log.Println("no conn available")
-		return
-	}
-	defer conn.Close()
-
-	lastDataMap := make(map[string]string)
-	for {
-		if tds.instrumentUpdated {
-			tds.statusCh <- 1
-			return
-		}
-		if !inTime() {
-			time.Sleep(time.Second * 1)
-			continue
-		}
-		//start := time.Now().UnixNano()
-		var bb [800]byte
-		bb2 := []byte("\x0C\x01\x20\x63\x00\x02\x13\x00\x13\x00\x3E\x05\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00")
-		C.memcpy(unsafe.Pointer(&bb[0]), unsafe.Pointer(&bb2[0]), C.size_t(len(bb2)))
-		i := len(bb2)
-		for index := 0; index < STOCK_PER_SERVER; index++ {
-			if "" == symbols[index] {
-				continue
-			}
-			bb[i] = exs[index]
-			i++
-			tmpsymbol := []byte(symbols[index])
-			C.memcpy(unsafe.Pointer(&bb[i]), unsafe.Pointer(&tmpsymbol[0]), 6)
-			i += 6
-		}
-		bb[20] = byte((i - 22) / 7) //数量
-		len := uint16(i) - 10
-		binary.LittleEndian.PutUint16(bb[6:], len)
-		binary.LittleEndian.PutUint16(bb[8:], len)
-
-		_, err := conn.Write(bb[:i])
-		if err != nil {
-			log.Println("readTicks.Write", err)
-			conn.Close()
-			conn = nil
-			for {
-				conn = tds.getTickConn()
-				if conn != nil {
-					break
-				} else {
-					time.Sleep(5 * time.Second)
-				}
-			}
-			continue
-		}
-		debuf, err := readBuf(conn)
-		if err != nil {
-			log.Println("readTicks.Read", err)
-			conn.Close()
-			conn = nil
-			for {
-				conn = tds.getTickConn()
-				if conn != nil {
-					break
-				} else {
-					time.Sleep(5 * time.Second)
-				}
-			}
-			continue
-		}
-		n := binary.LittleEndian.Uint16(debuf[2:])
-		if n < 1 {
-			log.Println("readTicks.n no data fetched")
-			continue
-		}
-		buf := debuf[4:]
-		i = 0
-		var mks []*Market
-		for j := 0; j < int(n); j++ {
-			//m := buf[i]
-			var code [8]byte
-			C.memcpy(unsafe.Pointer(&code[0]), unsafe.Pointer(&buf[i+1]), 6)
-			symbol := string(code[:6])
-
-			mk := &Market{}
-			mk.Type = IntTdx
-			mk.InsId, _ = strconv.ParseInt(string(code[:6]), 10, 64)
-			dd := float64(100.0)
-			i += 9
-			startPos := i
-			mk.Close = float64(TDXDecode(buf, i, &i)) / dd
-			mk.LastPrice = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			mk.Open = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			mk.High = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			mk.Low = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			TDXDecode(buf, i, &i)                   //Time := TDXDecode(buf, i, &i)
-			mk.Timestamp = time.Now().Unix() * 1000 //tds.ParseTime(Time)
-			TDXDecode(buf, i, &i)
-			mk.LastVolume = float64(TDXDecode(buf, i, &i))
-			TDXDecode(buf, i, &i) //现量
-			mk.AllAmount = float64(TDXGetDouble(buf, i, &i))
-			TDXDecode(buf, i, &i)
-			TDXDecode(buf, i, &i)
-
-			TDXDecode(buf, i, &i)
-			TDXDecode(buf, i, &i)
-
-			var bid, ask PP
-			bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			bid[1] = float64(TDXDecode(buf, i, &i))
-			ask[1] = float64(TDXDecode(buf, i, &i))
-			mk.Bids = append(mk.Bids, bid)
-			mk.Asks = append(mk.Asks, ask)
-			bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			bid[1] = float64(TDXDecode(buf, i, &i))
-			ask[1] = float64(TDXDecode(buf, i, &i))
-			mk.Bids = append(mk.Bids, bid)
-			mk.Asks = append(mk.Asks, ask)
-
-			bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			bid[1] = float64(TDXDecode(buf, i, &i))
-			ask[1] = float64(TDXDecode(buf, i, &i))
-			mk.Bids = append(mk.Bids, bid)
-			mk.Asks = append(mk.Asks, ask)
-
-			bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			bid[1] = float64(TDXDecode(buf, i, &i))
-			ask[1] = float64(TDXDecode(buf, i, &i))
-			mk.Bids = append(mk.Bids, bid)
-			mk.Asks = append(mk.Asks, ask)
-
-			bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-			bid[1] = float64(TDXDecode(buf, i, &i))
-			ask[1] = float64(TDXDecode(buf, i, &i))
-			mk.Bids = append(mk.Bids, bid)
-			mk.Asks = append(mk.Asks, ask)
-			i += 3
-			TDXDecode(buf, i, &i)
-			TDXDecode(buf, i, &i)
-			TDXDecode(buf, i, &i)
-			TDXGetInt16(buf, i, &i)
-			//float speed=(float)(t/100.0);
-			TDXGetInt16(buf, i, &i)
-			endPos := i
-			dataStr := string(buf[startPos:endPos])
-			bsame := false
-			lastData, ok := lastDataMap[symbol]
-			if ok {
-				if lastData == dataStr {
-					bsame = true
-				}
-			}
-			if !bsame {
-				mks = append(mks, mk)
-			}
-			lastDataMap[symbol] = dataStr
-		}
-		for _, v := range mks {
-			//if v.InsId == 1 {
-			//log.Println("[readTicks]data trace")
-			//}
-			tds.Save(v)
-		}
-		//end := time.Now().UnixNano()
-		//log.Println("time used:", end-start)
-
-		time.Sleep(time.Millisecond * FETCH_PER_MILLISECOND)
-	}
-}
-
-/*
-func (tds *TdxDS) readTick(conn net.Conn, szOrsh byte, symbol string) ([]*Market, error) {
-	bb1 := []byte("\x0C\x01\x20\x63\x00\x02\x13\x00\x13\x00\x3E\x05\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x30\x30\x30\x30\x30\x31")
-	bb1[22] = szOrsh //市场0深圳 1上海
-	bBuf := bytes.NewBuffer(bb1[23:])
-	bBuf.Reset()
-	binary.Write(bBuf, binary.LittleEndian, symbol[:6])
-	_, err := conn.Write(bb1)
-	if err != nil {
-		return nil, err
-	}
-	debuf, err := readBuf(conn)
-	if err != nil {
-		return nil, err
-	}
-	n := binary.LittleEndian.Uint16(debuf[2:])
-	if n < 1 {
-		return nil, errors.New("no data")
-	}
-	var i int
-	buf := debuf[4:]
-	var mks []*Market
-	for j := 0; j < int(n); j++ {
-		//m := buf[i]
-		var code [8]byte
-		C.memcpy(unsafe.Pointer(&code[0]), unsafe.Pointer(&buf[i+1]), 6)
-		//codeStr := string(code[:6])
-		//_, ok := tds.stocks[codeStr]
-		//if !ok {
-		//log.Println("invalid code:", codeStr)
-		//continue
-		//}
-		mk := &Market{}
-		mk.Type = IntTdx
-		mk.InsId, _ = strconv.ParseInt(symbol, 10, 64)
-		dd := float64(100.0)
-		i += 9
-		mk.Close = float64(TDXDecode(buf, i, &i)) / dd
-		mk.LastPrice = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		mk.Open = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		mk.High = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		mk.Low = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		mk.Timestamp = tds.ParseTime(TDXDecode(buf, i, &i))
-		TDXDecode(buf, i, &i)
-		mk.LastVolume = float64(TDXDecode(buf, i, &i))
-		TDXDecode(buf, i, &i) //现量
-		mk.AllAmount = float64(TDXGetDouble(buf, i, &i))
-		TDXDecode(buf, i, &i)
-		TDXDecode(buf, i, &i)
-		TDXDecode(buf, i, &i)
-		TDXDecode(buf, i, &i)
-		var bid, ask PP
-		bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		bid[1] = float64(TDXDecode(buf, i, &i))
-		ask[1] = float64(TDXDecode(buf, i, &i))
-		mk.Bids = append(mk.Bids, bid)
-		mk.Asks = append(mk.Asks, ask)
-		bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		bid[1] = float64(TDXDecode(buf, i, &i))
-		ask[1] = float64(TDXDecode(buf, i, &i))
-		mk.Bids = append(mk.Bids, bid)
-		mk.Asks = append(mk.Asks, ask)
-		bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		bid[1] = float64(TDXDecode(buf, i, &i))
-		ask[1] = float64(TDXDecode(buf, i, &i))
-		mk.Bids = append(mk.Bids, bid)
-		mk.Asks = append(mk.Asks, ask)
-		bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		bid[1] = float64(TDXDecode(buf, i, &i))
-		ask[1] = float64(TDXDecode(buf, i, &i))
-		mk.Bids = append(mk.Bids, bid)
-		mk.Asks = append(mk.Asks, ask)
-		bid[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		ask[0] = mk.Close + float64(TDXDecode(buf, i, &i))/dd
-		bid[1] = float64(TDXDecode(buf, i, &i))
-		ask[1] = float64(TDXDecode(buf, i, &i))
-		mk.Bids = append(mk.Bids, bid)
-		mk.Asks = append(mk.Asks, ask)
-		i += 3
-		TDXDecode(buf, i, &i)
-		TDXDecode(buf, i, &i)
-		TDXDecode(buf, i, &i)
-		TDXGetInt16(buf, i, &i)
-		//speed := float32(t) / 100.0
-		TDXGetInt16(buf, i, &i)
-		mks = append(mks, mk)
-		//log.Println(mk)
-	}
-	return mks, nil
-}*/
-
-func (tds *TdxDS) ParseTime(tdxTime int32) int64 {
-	tdxTimeStr := fmt.Sprintf("%d", tdxTime)
-	tdxTimeBytes := []byte(tdxTimeStr)
-	if tdxTimeBytes[0] != '1' && tdxTimeBytes[0] != '2' {
-		tdxTimeStr = "0" + tdxTimeStr
-	}
-
-	datetimeStr := strconv.Itoa(int(tds.datetime)) + tdxTimeStr
-	var year, month, day, hour, minute, second, millisecond int
-	fmt.Sscanf(datetimeStr, "%04d%02d%02d%02d%02d%02d%d", &year, &month, &day, &hour, &minute, &second, &millisecond)
-	if second > 59 {
-		second -= 60
-		minute++
-	}
-	//log.Println(datetimeStr, tdxTimeStr, tdxTimeBytes, tdxTime, year, month, day, hour, minute, second, millisecond)
-	t := time.Date(year, time.Month(month), day, hour, minute, second, 0, time.Local)
-	//t, _ := time.Parse("2015090909090909", datetimeStr)
-	return t.Unix() * 1000
-}
-
-//解包数据
-func TDXDecode(buf []byte, start int, next *int) int32 {
-	var num uint32
-	var num3, num2, num4, num5, num6, num7, num8 int32
-	var cc byte
-
-	for num2 < 0x20 {
-		cc = buf[int32(start)+num2]
-		num4 = int32(cc)
-		num5 = (num4 & 0x80) / 0x80
-		if num2 == 0 {
-			num3 = 1 - (((num4 & 0x40) / 0x40) * 2)
-			num6 = num4 & 0x3F
-			num = uint32(int64(num) + int64(num6))
-		} else if num2 == 1 {
-			num7 = (num4 & 0x7F) * (2 << (uint64(num2)*6 - 1)) //  power(2, num2 * 6));
-			num = uint32(int64(num) + int64(num7))
-		} else {
-			num8 = (num4 & 0x7F) * (2 << (uint64(num2)*7 - 2)) // Power(2, (num2 * 7) - 1);
-			num = uint32(int64(num) + int64(num8))
-		}
-		if num5 == 0 {
-			num = uint32(int64(num) * int64(num3))
-			break
-		}
-		num2++
-	}
-	*next = start + int(num2) + 1
-	return int32(num)
-}
-
-//读取16位数据
-func TDXGetInt16(buf []byte, start int, next *int) int16 {
-	Num := binary.LittleEndian.Uint16(buf[start:])
-	*next = start + 2
-	return int16(Num)
-}
-
-//读取32位数据
-func TDXGetInt32(buf []byte, start int, next *int) int32 {
-	Num := binary.LittleEndian.Uint32(buf[start:])
-	*next = start + 4
-	return int32(Num)
-}
-
-//读取浮点数据float
-func TDXGetDouble(buf []byte, start int, next *int) float32 {
-	var Num float32
-	bBuf := bytes.NewBuffer(buf[start:])
-	binary.Read(bBuf, binary.LittleEndian, &Num)
-	*next = start + 4
-	return Num
-}
-
-//读取时间:HHMM
-func TDXGetTime(buf []byte, start int, next *int) int {
-	i := TDXGetInt16(buf, start, next)
-	mm := (i / 60)
-	ss := (i % 60)
-	if ss > 59 {
-		ss = ss - 60
-		mm++
-	}
-	ri := mm*100 + ss
-	return int(ri)
-}
-
-func TDXGetDate(v int32, yy *int, mm *int, dd *int, hhh *int, mmm *int) {
-	*yy = 2012
-	*mm = 1
-	*dd = 1
-	*hhh = 9
-	*mmm = 30
-	if v > 21000000 {
-		*yy = int(2004 + ((v & 0xF800) >> 11))
-		d1 := v & 0x7FF
-		*mm = int(d1 / 100)
-		*dd = int(d1 % 100)
-		d2 := v >> 16
-		*hhh = int(d2 / 60)
-		*mmm = int(d2 % 60)
-	} else {
-		*yy = int(v / 10000)
-		*mm = (int(v) - *yy*10000) / 100
-		*dd = int(v % 100)
-		*hhh = 9
-		*mmm = 30
-	}
-} //解包数据
-
-func inTime() bool {
-	t := time.Now()
-	if t.Weekday() == time.Saturday || t.Weekday() == time.Sunday {
-		return false
-	}
-	mm := t.Hour()*60 + t.Minute()
-	for _, ti := range cffexTi {
-		m1 := ti.st.hour*60 + ti.st.minute
-		m2 := ti.et.hour*60 + ti.et.minute
-		if mm >= m1 && mm <= m2 {
-			return true
-		}
-	}
-	return false
-}
-
-func readBuf(conn net.Conn) ([]byte, error) {
-	var head RecvDataHeader
-	err := binary.Read(conn, binary.LittleEndian, &head)
-	if err != nil {
-		return nil, err
-	}
-	if head.CheckSum != 7654321 {
-		return nil, errors.New("error checksum")
-	}
-	buf := make([]byte, int(head.Size))
-	n, err := io.ReadFull(conn, buf)
-	if err != nil {
-		return nil, err
-	}
-	if int(head.Size) != n {
-		return nil, errors.New("read size error")
-	}
-	//log.Println(head)
-	var debuf []byte
-	if (head.EncodeMode & 0x10) == 0x10 { //gzip compress
-		reader, err := zlib.NewReader(bytes.NewBuffer(buf))
-		defer reader.Close()
-		if err != nil {
-			return nil, err
-		}
-		debuf = make([]byte, int(head.DePackSize))
-		n, err := io.ReadFull(reader, debuf)
-		if err != nil {
-			return nil, err
-		}
-		if n != int(head.DePackSize) {
-			return nil, errors.New("depack size error")
-		}
-	} else {
-		debuf = buf
-	}
-	return debuf, nil
-}
-
-func loadServers(fname string) ([]string, error) {
-	fp, err := os.Open(fname)
-	if err != nil {
-		return nil, err
-	}
-	defer fp.Close()
-	fi, err := fp.Stat()
-	if err != nil {
-		return nil, err
-	}
-	buf := make([]byte, fi.Size())
-	n, err := io.ReadFull(fp, buf)
-	if err != nil {
-		return nil, err
-	}
-	if n != len(buf) {
-		return nil, errors.New("can't read all data")
-	}
-	var realservers []string
-	servers := strings.Split(string(buf), "\n")
-	//去重
-	serversMap := make(map[string]int)
-	for _, server := range servers {
-		_, ok := serversMap[server]
-		if !ok {
-			realservers = append(realservers, server)
-			serversMap[server] = 0
-		} else {
-			log.Println("duplicate server:", server)
-		}
-	}
-	log.Println("servers:", len(servers), "realservers:", len(realservers))
-	return realservers, nil
-}

+ 0 - 26
server/tick/ds_tdx_test.go

@@ -1,26 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestTdx(t *testing.T) {
-	conf := &DsConf{
-		Url:     "218.18.103.38:7709",
-		CfgFile: "serverlist.txt",
-	}
-	ds, err := newTdxDS(conf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(getTime(mk.Timestamp), mk.InsId)
-	}
-	log.Println("@@@@@@@:go here")
-}

+ 0 - 113
server/tick/ds_yunbi.go

@@ -1,113 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-// 本文件实现yunbi数据源的tick数据获取下载和保存
-
-import (
-	"log"
-	"net/http"
-	"time"
-
-	"tickserver/markinfo"
-	"tickserver/server/market"
-	coinapi "github.com/nntaoli/crypto_coin_api"
-	"github.com/nntaoli/crypto_coin_api/yunbi"
-)
-
-var yunbiInss = []int{
-	markinfo.BTCCNY,
-	markinfo.ETCCNY,
-	markinfo.ETHCNY,
-}
-
-// YunbiDS 实现数据源dataSource接口的定义
-type YunbiDS struct {
-	*DSBase
-	conf       *DsConf
-	yunbi      *yunbi.YunBi
-	lastprice  []float64
-	lastvolume []float64
-}
-
-func init() {
-	drivers[Yunbi] = newYunbiDS
-}
-
-func newYunbiDS(conf *DsConf) (DataSource, error) {
-	log.Println("newYunbiDS")
-	yds := &YunbiDS{
-		DSBase:     NewDsBase(conf),
-		conf:       conf,
-		lastprice:  make([]float64, len(yunbiInss)),
-		lastvolume: make([]float64, len(yunbiInss)),
-	}
-	yds.insMap = yunbiInsMap()
-	yds.yunbi = yunbi.New(&http.Client{}, "", "")
-	return yds, nil
-}
-
-func (yds *YunbiDS) Name() string {
-	return Yunbi
-}
-
-func (yds *YunbiDS) Run() {
-	log.Println("YunbiDS.run")
-	for {
-		for k, _ := range yunbiInss {
-			yds.getYunbiData(k)
-			time.Sleep(time.Second)
-		}
-	}
-}
-
-func yunbiInsMap() map[int64]*Instrument {
-	insMap := make(map[int64]*Instrument)
-	for _, id := range yunbiInss {
-		x, _ := markinfo.SymbolName(id)
-		u, _ := markinfo.SymbolUint(x)
-		ins := &Instrument{
-			Id:        int64(id),
-			Name:      x,
-			ExId:      Btc,
-			Type:      market.Btcs,
-			PriceInc:  u,
-			StartTime: time.Now().Unix() * 1000,
-		}
-		insMap[int64(id)] = ins
-	}
-	return insMap
-}
-
-func (yds *YunbiDS) getYunbiData(index int) {
-	var currency coinapi.CurrencyPair
-	if yunbiInss[index] == markinfo.BTCCNY {
-		currency = coinapi.BTC_CNY
-	}
-	if yunbiInss[index] == markinfo.ETCCNY {
-		currency = coinapi.ETC_CNY
-	}
-	if yunbiInss[index] == markinfo.ETHCNY {
-		currency = coinapi.ETH_CNY
-	}
-	ticker, _ := yds.yunbi.GetTicker(currency)
-	if ticker != nil && (ticker.Last != yds.lastprice[index] || ticker.Vol != yds.lastvolume[index]) {
-		yds.lastprice[index] = ticker.Last
-		yds.lastvolume[index] = ticker.Vol
-
-		mk := &Market{}
-		mk.Type = IntYunbi
-		mk.InsId = int64(yunbiInss[index])
-		mk.Timestamp = int64(ticker.Date) * 1000
-		var ask, bid PP
-		ask[0] = ticker.Sell
-		bid[0] = ticker.Buy
-		mk.Asks = append(mk.Asks, ask)
-		mk.Bids = append(mk.Bids, bid)
-		mk.High = ticker.High
-		mk.LastPrice = ticker.Last
-		mk.Low = ticker.Low
-		mk.LastVolume = ticker.Vol
-		yds.Save(mk)
-	}
-}

+ 0 - 23
server/tick/ds_yunbi_test.go

@@ -1,23 +0,0 @@
-// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved.
-
-package tick
-
-import (
-	"log"
-	//"market"
-	"testing"
-)
-
-func TestYunbi(t *testing.T) {
-	conf := &DsConf{}
-	ds, _ := newYunbiDS(conf) //, err
-	//if err != nil {
-	//t.Fatal(err)
-	//}
-	go ds.Run()
-	chmk := ds.GetMarket()
-	for mk := range chmk {
-		log.Println(mk)
-	}
-	log.Println("@@@@@@@:go here")
-}