func Recv(conn net.Conn) { defer func() { sendChan <- nil }() for { nethead := [HeadLen]byte{} if _, e := io.ReadFull(conn, nethead[:]); e != nil { fmt.Println(conn.RemoteAddr().String(), "Error recv head : ", e) break } msglen := *(*uint64)(unsafe.Pointer(&nethead)) msgbuf := make([]byte, HeadLen+msglen) if _, e := io.ReadFull(conn, msgbuf[HeadLen:]); e != nil { fmt.Println(conn.RemoteAddr().String(), "Error recv body : ", e) break } mh := (*MessageHead)(unsafe.Pointer(&msgbuf[0])) mh.Msglen = msglen if uint32(len(msgbuf)) < MsgLen+RecLen { continue } rh := (*RecordHead)(unsafe.Pointer(&msgbuf[MsgLen])) if uint32(len(msgbuf)) < MsgLen+RecLen+rh.Length { continue } bodybuf := msgbuf[MsgLen+RecLen : MsgLen+RecLen+rh.Length] if rh.HashCode != Common.Hash(bodybuf) { continue } switch rh.RecType { case uint32(ConstDefine_E_DepthMarketData): dmd := &DepthMarketData{} proto.Unmarshal(bodybuf, dmd) quoteChan <- dmd case uint32(ConstDefine_E_ReqKLine): rkl := &ReqKLine{} proto.Unmarshal(bodybuf, rkl) klineChan <- &KlineReq{mh.Sender, mh.Copyer, mh.SendTime, rkl} case uint32(ConstDefine_E_ReqTick): rt := &ReqTick{} proto.Unmarshal(bodybuf, rt) tickChan <- &TickReq{mh.Sender, mh.Copyer, mh.SendTime, rt} } } }
func SendTo(conn net.Conn, sender, recver, copyer uint64, tp ConstDefine, buf []byte) { sockbuf := make([]byte, MsgLen+RecLen+uint32(len(buf))) mh := (*MessageHead)(unsafe.Pointer(&sockbuf[0])) rh := (*RecordHead)(unsafe.Pointer(&sockbuf[MsgLen])) bodybuf := sockbuf[MsgLen+RecLen:] mh.Msglen = uint64(len(sockbuf)) - HeadLen mh.Sender = sender mh.Recver = recver mh.Copyer = copyer rh.HashCode = Common.Hash(buf) rh.RecType = uint32(tp) rh.Length = uint32(len(buf)) copy(bodybuf, buf) conn.Write(sockbuf) }
func SendTo(id uint64, copyer uint64, tp ConstDefine, buf []byte) { sockbuf := make([]byte, MsgLen+RecLen+uint32(len(buf))) mh := (*MessageHead)(unsafe.Pointer(&sockbuf[0])) rh := (*RecordHead)(unsafe.Pointer(&sockbuf[MsgLen])) bodybuf := sockbuf[MsgLen+RecLen:] mh.Msglen = uint64(len(sockbuf)) - HeadLen mh.Sender = MakeID(*flgName) mh.Recver = id mh.Copyer = copyer if buf != nil { rh.HashCode = Common.Hash(buf) rh.RecType = uint32(tp) rh.Length = uint32(len(buf)) copy(bodybuf, buf) } sendChan <- sockbuf }
func Recv(conn net.Conn) { for { nethead := [HeadLen]byte{} if _, e := io.ReadFull(conn, nethead[:]); e != nil { fmt.Println(conn.RemoteAddr().String(), "Error recv head : ", e) break } msglen := *(*uint64)(unsafe.Pointer(&nethead)) msgbuf := make([]byte, HeadLen+msglen) if _, e := io.ReadFull(conn, msgbuf[HeadLen:]); e != nil { fmt.Println(conn.RemoteAddr().String(), "Error recv body : ", e) break } mh := (*MessageHead)(unsafe.Pointer(&msgbuf[0])) mh.Msglen = msglen if uint32(len(msgbuf)) < MsgLen+RecLen { fmt.Println("error of message head") continue } rh := (*RecordHead)(unsafe.Pointer(&msgbuf[MsgLen])) if uint32(len(msgbuf)) < MsgLen+RecLen+rh.Length { fmt.Println("error of message length") continue } bodybuf := msgbuf[MsgLen+RecLen : MsgLen+RecLen+rh.Length] if rh.HashCode != Common.Hash(bodybuf) { fmt.Println("error of message hashcode") continue } switch rh.RecType { case uint32(ConstDefine_E_DepthMarketData): dmd := &DepthMarketData{} err := proto.Unmarshal(bodybuf, dmd) if err != nil || dmd.GetTickerName() != *flgTicker { break } fmt.Println(dmd.GetTime(), dmd.GetTickerName(), dmd.GetVolume(), dmd.GetLastPrice()) order := dmd.GetOrder() for i, ord := range order { fmt.Println(i, ord.GetTime(), ord.GetAccount(), ord.GetTickerName(), ord.GetVolume(), ord.GetPrice(), ord.GetLastFilled(), ord.GetTotalFilled(), ord.GetExplain(), ord.GetOrderID(), ord.GetIsForce(), ord.GetIsToday()) } position := dmd.GetPosition() for i, pos := range position { fmt.Println(i, pos.GetAccount(), pos.GetTickerName(), pos.GetMargin(), "longAvgPrice/q/v/c:", pos.GetLongAvgPrice(), pos.GetQueuingLongVolume(), pos.GetValidLongVolume(), pos.GetClosingLongVolume(), "shotAvgPrice/q/v/c:", pos.GetShortAvgPrice(), pos.GetQueuingShortVolume(), pos.GetValidShortVolume(), pos.GetClosingShortVolume()) } case uint32(ConstDefine_E_RspSendOrder): so := &RspSendOrder{} err := proto.Unmarshal(bodybuf, so) if err != nil { fmt.Println("error : unmarshal message RspSendOrder") break } fmt.Println("OnRecvRspSendOrder:") if ord := so.GetLastReport(); ord != nil { fmt.Println(ord.GetTime(), ord.GetAccount(), ord.GetTickerName(), ord.GetVolume(), ord.GetPrice(), ord.GetLastFilled(), ord.GetTotalFilled(), ord.GetExplain(), ord.GetOrderID(), ord.GetIsForce(), ord.GetIsToday()) } case uint32(ConstDefine_E_ReqCancelOrder): co := &ReqCancelOrder{} err := proto.Unmarshal(bodybuf, co) if err != nil { fmt.Println("error : unmarshal message ReqCancelOrder") break } fmt.Println("OnRecvReqCancelOrder:") fmt.Println(co.GetAccount(), co.GetTickerName(), co.GetOrderID()) case uint32(ConstDefine_E_RspCancelOrder): co := &RspCancelOrder{} err := proto.Unmarshal(bodybuf, co) if err != nil { fmt.Println("error : unmarshal message RspCancelOrder") break } fmt.Println("OnRecvRspCancelOrder:") if ord := co.GetLastReport(); ord != nil { fmt.Println(ord.GetTime(), ord.GetAccount(), ord.GetTickerName(), ord.GetVolume(), ord.GetPrice(), ord.GetLastFilled(), ord.GetTotalFilled(), ord.GetExplain(), ord.GetOrderID(), ord.GetIsForce(), ord.GetIsToday()) } case uint32(ConstDefine_E_RspOrdersInfo): oi := &RspOrdersInfo{} err := proto.Unmarshal(bodybuf, oi) if err != nil { fmt.Println("error : unmarshal message RspOrdersInfo") break } fmt.Println("OnRecvRspOrdersInfo") if order := oi.GetOrder(); order != nil { for i, ord := range order { fmt.Println(i, ord.GetTime(), ord.GetAccount(), ord.GetTickerName(), ord.GetVolume(), ord.GetPrice(), ord.GetLastFilled(), ord.GetTotalFilled(), ord.GetExplain(), ord.GetOrderID(), ord.GetIsForce(), ord.GetIsToday()) } } case uint32(ConstDefine_E_RspPosition): p := &RspPosition{} err := proto.Unmarshal(bodybuf, p) if err != nil { fmt.Println("error : unmarshal message RspPosition") break } fmt.Println("OnRecvRspPosition") if position := p.GetPosition(); position != nil { for i, pos := range position { fmt.Println(i, pos.GetAccount(), pos.GetTickerName(), pos.GetMargin(), "longAvgPrice/q/v/c:", pos.GetLongAvgPrice(), pos.GetQueuingLongVolume(), pos.GetValidLongVolume(), pos.GetClosingLongVolume(), "shotAvgPrice/q/v/c:", pos.GetShortAvgPrice(), pos.GetQueuingShortVolume(), pos.GetValidShortVolume(), pos.GetClosingShortVolume()) } } case uint32(ConstDefine_E_ReqPosition): p := &ReqPosition{} err := proto.Unmarshal(bodybuf, p) if err != nil { fmt.Println("error : unmarshal message ReqPosition") break } fmt.Println("OnRecvReqPosition") fmt.Println(p.GetAccount(), p.GetTickerName()) case uint32(ConstDefine_E_RspAccount): a := &RspAccount{} err := proto.Unmarshal(bodybuf, a) if err != nil { fmt.Println("error : unmarshal message RspAccount") break } fmt.Println("OnRecvRspAccount/v/m:", a.GetAccount(), a.GetAvailable(), a.GetMargin()) order := a.GetOrders() for i, ord := range order { fmt.Println(i, ord.GetTime(), ord.GetAccount(), ord.GetTickerName(), ord.GetVolume(), ord.GetPrice(), ord.GetLastFilled(), ord.GetTotalFilled(), ord.GetExplain(), ord.GetOrderID(), ord.GetIsForce(), ord.GetIsToday()) } position := a.GetPositions() for i, pos := range position { fmt.Println(i, pos.GetAccount(), pos.GetTickerName(), pos.GetMargin(), "longAvgPrice/q/v/c:", pos.GetLongAvgPrice(), pos.GetQueuingLongVolume(), pos.GetValidLongVolume(), pos.GetClosingLongVolume(), "shotAvgPrice/q/v/c:", pos.GetShortAvgPrice(), pos.GetQueuingShortVolume(), pos.GetValidShortVolume(), pos.GetClosingShortVolume()) } case uint32(ConstDefine_E_RspAlgoOrder): ao := &RspAlgoOrder{} err := proto.Unmarshal(bodybuf, ao) if err != nil { fmt.Println("error : unmarshal message RspAlgoOrder") break } fmt.Println("OnRecvRspAlgoOrder") case uint32(ConstDefine_E_RspTickerInfo): ti := &RspTickerInfo{} err := proto.Unmarshal(bodybuf, ti) if err != nil { fmt.Println("error : unmarshal message RspTickerInfo") break } fmt.Println("OnRecvRspTickerInfo") for i, ts := range ti.GetTradingSession() { fmt.Println(i, ts.GetStartTime(), ts.GetEndTime()) } } } }
func Recv(conn net.Conn) { defer func() { sendChan <- nil }() for { nethead := [HeadLen]byte{} if _, e := io.ReadFull(conn, nethead[:]); e != nil { fmt.Println(conn.RemoteAddr().String(), "Error recv head : ", e) break } msglen := *(*uint64)(unsafe.Pointer(&nethead)) msgbuf := make([]byte, HeadLen+msglen) if _, e := io.ReadFull(conn, msgbuf[HeadLen:]); e != nil { fmt.Println(conn.RemoteAddr().String(), "Error recv body : ", e) break } mh := (*MessageHead)(unsafe.Pointer(&msgbuf[0])) mh.Msglen = msglen //fmt.Println("msgSender -> Recver:", mh.Sender, mh.Recver) if uint32(len(msgbuf)) < MsgLen+RecLen { continue } rh := (*RecordHead)(unsafe.Pointer(&msgbuf[MsgLen])) if uint32(len(msgbuf)) < MsgLen+RecLen+rh.Length { continue } bodybuf := msgbuf[MsgLen+RecLen : MsgLen+RecLen+rh.Length] if rh.HashCode != Common.Hash(bodybuf) { continue } switch rh.RecType { case uint32(ConstDefine_E_DepthMarketData): dmd := &DepthMarketData{} proto.Unmarshal(bodybuf, dmd) quoteChan <- dmd case uint32(ConstDefine_E_ReqCancelOrder): co := &ReqCancelOrder{} proto.Unmarshal(bodybuf, co) cancelChan <- &CancelReq{mh.Sender, mh.SendTime, co} case uint32(ConstDefine_E_ReqOrdersInfo): buf, _ := proto.Marshal(&RspOrdersInfo{}) SendTo(mh.Sender, 0, ConstDefine_E_RspOrdersInfo, buf) case uint32(ConstDefine_E_ReqPosition): buf, _ := proto.Marshal(&RspPosition{}) SendTo(mh.Sender, 0, ConstDefine_E_RspPosition, buf) case uint32(ConstDefine_E_ReqAccount): buf, _ := proto.Marshal(&RspAccount{}) SendTo(mh.Sender, 0, ConstDefine_E_RspAccount, buf) case uint32(ConstDefine_E_ReqSendOrder): so := &ReqSendOrder{} proto.Unmarshal(bodybuf, so) fmt.Println("order...") orderChan <- &OrderReq{mh.Sender, 0, "", OrderStatus_OrderStatus_NIL, so} case uint32(ConstDefine_E_HeartBeat): if len(reqtickChan) > 0 { quoteChan <- <-reqtickChan } if len(reqklineChan) > 0 { rk := <-reqklineChan buf, _ := proto.Marshal(rk) SendTo(MakeID(*flgQuote), 0, ConstDefine_E_RspKLine, buf) } case uint32(ConstDefine_E_RspKLine): go func() { rk := &RspKLine{} proto.Unmarshal(bodybuf, rk) klines := rk.GetBar_Minute() if nil == klines { return } fmt.Println(time.Now(), " GetKLine:", len(klines)) for _, kl := range klines { rk.Bar_Minute = []*TOHLCV{kl} reqklineChan <- rk } }() case uint32(ConstDefine_E_RspTick): tickBuffer <- bodybuf } } }
func Spliter(key, mode string) { defer delete(algos, key) algo, ok := algos[key] if !ok { log.Println("Can't get algo from key:", key) return } log.Println("start routine by key:", key) ticker := algo.GetTickerName() account := algo.GetAccount() strategy := algo.GetStrategyName() exchange := algo.GetExchangeName() conn, err := net.Dial("tcp", *flgMc) if err != nil { log.Println("error:", err) return } defer conn.Close() Register(conn, algo.GetQuoteName()) if *flgTest { hb := &HeartBeat{} if buf, err := proto.Marshal(hb); err == nil { SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_HeartBeat, buf) } } for { nethead := [HeadLen]byte{} if _, e := io.ReadFull(conn, nethead[:]); e != nil { log.Println(conn.RemoteAddr().String(), "error recv head : ", e) break } msglen := *(*uint64)(unsafe.Pointer(&nethead)) msgbuf := make([]byte, HeadLen+msglen) if _, e := io.ReadFull(conn, msgbuf[HeadLen:]); e != nil { log.Println(conn.RemoteAddr().String(), "error recv body : ", e) break } mh := (*MessageHead)(unsafe.Pointer(&msgbuf[0])) mh.Msglen = msglen if uint32(len(msgbuf)) < MsgLen+RecLen { log.Println(conn.RemoteAddr().String(), "error recv half-head") continue } rh := (*RecordHead)(unsafe.Pointer(&msgbuf[MsgLen])) if uint32(len(msgbuf)) < MsgLen+RecLen+rh.Length { log.Println(conn.RemoteAddr().String(), "error recv half-body") continue } bodybuf := msgbuf[MsgLen+RecLen : MsgLen+RecLen+rh.Length] if rh.HashCode != Common.Hash(bodybuf) { log.Println(conn.RemoteAddr().String(), "error hash") continue } if rh.RecType != uint32(ConstDefine_E_DepthMarketData) { continue } dmd := &DepthMarketData{} err := proto.Unmarshal(bodybuf, dmd) if err != nil || dmd.GetTickerName() != ticker { continue } buyOpen, buyClose, sellOpen, sellClose := GetOrders(ticker, account, dmd) _, longPos, _, _, shortPos, _ := GetPositionNumber(ticker, account, dmd) lastPrice := dmd.GetLastPrice() buyPrice := dmd.GetLastPrice() sellPrice := dmd.GetLastPrice() longVolume := algo.GetLongVolume() shortVolume := algo.GetShortVolume() if longVolume+shortVolume == 0 { return } switch mode { case MODE_FAST: buyPrice = algo.GetMaxLongPrice() sellPrice = algo.GetMinShortPrice() case MODE_MARKET: } if longPos < longVolume { for i, ord := range sellClose { if ord == nil { continue } log.Println("longPos < longVolume:", longPos, longVolume, "cancel sell-close order:", ord.GetOrderID()) co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) longPos += ord.GetVolume() sellClose[i] = nil } } for i, ord := range buyOpen { if ord == nil { continue } if !Equ(ord.GetPrice(), buyPrice) && ord.GetPrice() < buyPrice { log.Println("ord.Price < buyprice, cancel buy-open order:", ord.GetOrderID()) } else if longPos >= longVolume { log.Println("longPos >= longVolume:", longPos, longVolume, "cancel buy-open order:", ord.GetOrderID()) } else if longPos+ord.GetVolume() > longVolume { log.Println("too big order, cancel buy-open order:", ord.GetOrderID()) } else { longPos += ord.GetVolume() log.Println("keep order:", ord.GetOrderID()) continue } co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) buyOpen[i] = nil } if buyPrice < algo.GetMaxLongPrice() || Equ(algo.GetMaxLongPrice(), buyPrice) { for ; longPos < longVolume; longPos++ { so := SendOrder(ticker, account, true, true, buyPrice, lastPrice, 1) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqSendOrder, so) } } if longPos > longVolume { for i, ord := range buyOpen { if ord == nil { continue } log.Println("longPos > longVolume:", longPos, longVolume, "cancel buy-open order:", ord.GetOrderID()) co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) buyOpen[i] = nil } } for i, ord := range sellClose { if ord == nil { continue } if ord.GetPrice() > sellPrice && !Equ(ord.GetPrice(), sellPrice) { log.Println("ord.Price > sellprice, cancel sell-close order:", ord.GetOrderID()) } else if longPos <= longVolume { log.Println("longPos <= longVolume:", longPos, longVolume, "cancel sell-close order:", ord.GetOrderID()) } else if longPos < longVolume+ord.GetVolume() { log.Println("too big order, cancel sell-close order:", ord.GetOrderID()) } else { longVolume += ord.GetVolume() log.Println("keep order:", ord.GetOrderID()) continue } co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) sellClose[i] = nil } for ; longPos > longVolume; longVolume++ { so := SendOrder(ticker, account, false, false, sellPrice, lastPrice, 1) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqSendOrder, so) } if shortPos < shortVolume { for i, ord := range buyClose { if ord == nil { continue } log.Println("shortPos < shortVolume:", shortPos, shortVolume, "cancel buy-close order:", ord.GetOrderID()) co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) shortPos += ord.GetVolume() buyClose[i] = nil } } for i, ord := range sellOpen { if ord == nil { continue } if ord.GetPrice() > sellPrice && !Equ(ord.GetPrice(), sellPrice) { log.Println("ord.Price > sellPrice, cancel sell-open order:", ord.GetOrderID()) } else if shortPos >= shortVolume { log.Println("shortPos >= shortVolume:", shortPos, shortVolume, "cancel sell-open order:", ord.GetOrderID()) } else if shortPos+ord.GetVolume() > shortVolume { log.Println("too big order, cancel sell-open order:", ord.GetOrderID()) } else { shortPos += ord.GetVolume() log.Println("keep order:", ord.GetOrderID()) continue } co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) sellOpen[i] = nil } if sellPrice > algo.GetMinShortPrice() || Equ(sellPrice, algo.GetMinShortPrice()) { for ; shortPos < shortVolume; shortPos++ { so := SendOrder(ticker, account, false, true, sellPrice, lastPrice, 1) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqSendOrder, so) } } if shortPos > shortVolume { for i, ord := range sellOpen { if ord == nil { continue } log.Println("shortPos > shortVolume, cancel sell-open order", ord.GetOrderID()) co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) sellOpen[i] = nil } } for i, ord := range buyClose { if ord == nil { continue } if ord.GetPrice() < buyPrice && !Equ(buyPrice, ord.GetPrice()) { log.Println("ord.Price < buyprice, cancel buy-close order:", ord.GetOrderID()) } else if shortPos <= shortVolume { log.Println("shortPos <= shortVolume:", shortPos, shortVolume, "cancel buy-close order:", ord.GetOrderID()) } else if shortPos < shortVolume+ord.GetVolume() { log.Println("too big order, cancel buy-close order:", ord.GetOrderID()) } else { shortVolume += ord.GetVolume() log.Println("keep order:", ord.GetOrderID()) continue } co := CancelOrder(ticker, account, ord.GetOrderID()) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqCancelOrder, co) buyClose[i] = nil } for ; shortPos > shortVolume; shortVolume++ { so := SendOrder(ticker, account, true, false, buyPrice, lastPrice, 1) SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_ReqSendOrder, so) } if *flgTest { time.Sleep(time.Second) hb := &HeartBeat{} if buf, err := proto.Marshal(hb); err == nil { SendTo(conn, MakeID(strategy), MakeID(exchange), 0, ConstDefine_E_HeartBeat, buf) } } } }
func Recv(conn net.Conn) { for { nethead := [HeadLen]byte{} if _, e := io.ReadFull(conn, nethead[:]); e != nil { log.Println(conn.RemoteAddr().String(), "error recv head : ", e) break } msglen := *(*uint64)(unsafe.Pointer(&nethead)) msgbuf := make([]byte, HeadLen+msglen) if _, e := io.ReadFull(conn, msgbuf[HeadLen:]); e != nil { log.Println(conn.RemoteAddr().String(), "error recv body : ", e) break } mh := (*MessageHead)(unsafe.Pointer(&msgbuf[0])) mh.Msglen = msglen if uint32(len(msgbuf)) < MsgLen+RecLen { log.Println(conn.RemoteAddr().String(), "error recv half-head") continue } rh := (*RecordHead)(unsafe.Pointer(&msgbuf[MsgLen])) if uint32(len(msgbuf)) < MsgLen+RecLen+rh.Length { log.Println(conn.RemoteAddr().String(), "error recv half-body") continue } bodybuf := msgbuf[MsgLen+RecLen : MsgLen+RecLen+rh.Length] if rh.HashCode != Common.Hash(bodybuf) { log.Println(conn.RemoteAddr().String(), "error hash") continue } switch rh.RecType { default: log.Println("recv other msg", mh.Sender) case uint32(ConstDefine_E_DepthMarketData): dmd := &DepthMarketData{} err := proto.Unmarshal(bodybuf, dmd) if err == nil { fmt.Println(dmd.GetTime(), dmd.GetTickerName(), dmd.GetVolume(), dmd.GetLastPrice()) } case uint32(ConstDefine_E_ReqAlgoOrder): ao := &ReqAlgoOrder{} err := proto.Unmarshal(bodybuf, ao) if err != nil { log.Println("error:", err) break } if ai := ao.GetAlgo(); ai != nil { tk := ai.GetTickerName() st := ai.GetStrategyName() ac := ai.GetAccount() ex := ai.GetExchangeName() qt := ai.GetQuoteName() an := ai.GetAlgoName() lv := ai.GetLongVolume() sv := ai.GetShortVolume() log.Println("AlgoOrder:", tk, st, ac, ex, qt, an, lv, sv) if MakeID(st) != mh.Sender { log.Println("error: ", st, "not assign sender ", mh.Sender) break } key := fmt.Sprint(tk, "_", st, "_", ac, "_", ex, "_", qt, "_", an) if v, ok := algos[key]; ok { *v = *ai } else if lv+sv > 0 { algos[key] = ai switch ai.GetAlgoName() { case MODE_FAST: go Spliter(key, MODE_FAST) case MODE_MARKET: go Spliter(key, MODE_MARKET) } } rao := &RspAlgoOrder{Algo: ai} if buf, err := proto.Marshal(rao); err == nil { SendTo(conn, mh.Recver, mh.Sender, mh.Copyer, ConstDefine_E_RspSendOrder, buf) } else { log.Panicln("error:", err) } } } } }