/***************************************************************************** * Copyright [2019] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *****************************************************************************/ #include #include #include using namespace std; namespace StarQuant { // unique order id on server side defined in ordermanager.cpp, // Every broker has its own id; int64_t m_serverOrderId = 0; // mutex for increasing order id std::mutex oid_mtx; // mutex for changing order status std::mutex orderStatus_mtx; MSG_TYPE MsgType(const string& msg) { string header; stringstream ss(msg); getline(ss, header, SERIALIZATION_SEPARATOR); getline(ss, header, SERIALIZATION_SEPARATOR); getline(ss, header, SERIALIZATION_SEPARATOR); MSG_TYPE msgtype_ = MSG_TYPE(atoi(header.c_str())); return msgtype_; } string MsgFrame::serialize() { string tmp = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_); if (dataPtr != nullptr) { tmp = tmp + SERIALIZATION_SEPARATOR + dataPtr->serialize(); } return tmp; } void MsgFrame::deserialize(const string& msgin) { string des; string src; string stype; string datas; stringstream ss(msgin); getline(ss, des, SERIALIZATION_SEPARATOR); getline(ss, src, SERIALIZATION_SEPARATOR); getline(ss, stype, SERIALIZATION_SEPARATOR); getline(ss, datas); MSG_TYPE mtype = MSG_TYPE(stoi(stype)); destination_ = des; source_ = src; msgtype_ = mtype; if (!datas.empty()) dataPtr->deserialize(datas); } string accAddress(const string& msg) { string acc; stringstream ss(msg); getline(ss, acc, DESTINATION_SEPARATOR); getline(ss, acc, DESTINATION_SEPARATOR); getline(ss, acc, DESTINATION_SEPARATOR); return acc; } string TickMsg::serialize() { string ba; // bid ask price and size for (int32_t i = 0; i < data_.depth_; i++) { ba = ba + SERIALIZATION_SEPARATOR + to_string(data_.bidPrice_[i]) + SERIALIZATION_SEPARATOR + to_string(data_.bidSize_[i]) + SERIALIZATION_SEPARATOR + to_string(data_.askPrice_[i]) + SERIALIZATION_SEPARATOR + to_string(data_.askSize_[i]); } string s; s = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_.fullSymbol_ + SERIALIZATION_SEPARATOR + data_.time_ + SERIALIZATION_SEPARATOR + to_string(data_.price_) + SERIALIZATION_SEPARATOR + to_string(data_.size_) + ba + SERIALIZATION_SEPARATOR + to_string(data_.openInterest_) + SERIALIZATION_SEPARATOR + to_string(data_.open_) + SERIALIZATION_SEPARATOR + to_string(data_.high_) + SERIALIZATION_SEPARATOR + to_string(data_.low_) + SERIALIZATION_SEPARATOR + to_string(data_.preClose_) + SERIALIZATION_SEPARATOR + to_string(data_.upperLimitPrice_) + SERIALIZATION_SEPARATOR + to_string(data_.lowerLimitPrice_); return s; } string SecurityMsg::serialize() { string s; s = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_.symbol_ + SERIALIZATION_SEPARATOR + data_.exchange_ + SERIALIZATION_SEPARATOR + data_.localName_ + SERIALIZATION_SEPARATOR + data_.securityType_ + SERIALIZATION_SEPARATOR + to_string(data_.multiplier_) + SERIALIZATION_SEPARATOR + to_string(data_.ticksize_) + SERIALIZATION_SEPARATOR + data_.postype_ + SERIALIZATION_SEPARATOR + to_string(data_.longMarginRatio_) + SERIALIZATION_SEPARATOR + to_string(data_.shortMarginRatio_) + SERIALIZATION_SEPARATOR + data_.underlyingSymbol_ + SERIALIZATION_SEPARATOR + data_.optionType_ + SERIALIZATION_SEPARATOR + to_string(data_.strikePrice_) + SERIALIZATION_SEPARATOR + data_.expiryDate_; return s; } string AccMsg::serialize() { string s; s = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_.accountID_ + SERIALIZATION_SEPARATOR + to_string(data_.previousDayEquityWithLoanValue_) + SERIALIZATION_SEPARATOR + to_string(data_.netLiquidation_) + SERIALIZATION_SEPARATOR + to_string(data_.availableFunds_) + SERIALIZATION_SEPARATOR + to_string(data_.commission_) + SERIALIZATION_SEPARATOR + to_string(data_.fullMaintainanceMargin_) + SERIALIZATION_SEPARATOR + to_string(data_.realizedPnL_) + SERIALIZATION_SEPARATOR + to_string(data_.unrealizedPnL_) + SERIALIZATION_SEPARATOR + to_string(data_.balance_) + SERIALIZATION_SEPARATOR + to_string(data_.frozen_) + SERIALIZATION_SEPARATOR + ymdhmsf(); return s; } string FillMsg::serialize() { string str = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + std::to_string(data_.serverOrderID_) + SERIALIZATION_SEPARATOR + std::to_string(data_.clientOrderID_) + SERIALIZATION_SEPARATOR + std::to_string(data_.clientID_) + SERIALIZATION_SEPARATOR + data_.localNo_ + SERIALIZATION_SEPARATOR + data_.orderNo_ + SERIALIZATION_SEPARATOR + data_.tradeNo_ + SERIALIZATION_SEPARATOR + data_.tradeTime_ + SERIALIZATION_SEPARATOR + data_.fullSymbol_ + SERIALIZATION_SEPARATOR + std::to_string(data_.tradePrice_) + SERIALIZATION_SEPARATOR + std::to_string(data_.tradeSize_) + SERIALIZATION_SEPARATOR + std::to_string(static_cast(data_.fillFlag_)) + SERIALIZATION_SEPARATOR + std::to_string(data_.commission_) + SERIALIZATION_SEPARATOR + data_.account_ + SERIALIZATION_SEPARATOR + data_.api_ + SERIALIZATION_SEPARATOR + ymdhms(); return str; } bool isActiveOrder(const Order& o) { if (o.orderStatus_ == OrderStatus::OS_Filled) return false; if (o.orderStatus_ == OrderStatus::OS_Error) return false; if (o.orderStatus_ == OrderStatus::OS_Canceled) return false; return true; } bool isActiveOS(const OrderStatus& os) { if (os == OrderStatus::OS_Filled) return false; if (os == OrderStatus::OS_Error) return false; if (os == OrderStatus::OS_Canceled) return false; return true; } void OrderMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 8) throw std::out_of_range("OutofRange in Order deserialize"); destination_ = v[0]; source_ = v[1]; data_.api_ = v[3]; data_.account_ = v[4]; data_.clientID_ = stoi(v[5]); data_.clientOrderID_ = stol(v[6]); data_.tag_ = v[7]; // data_.clientID_ = stoi(v[1]); // data_.clientOrderID_ = stol(v[4]); // data_.orderType_ = static_cast(stoi(v[5])); // data_.fullSymbol_ = v[6]; // data_.orderSize_ = stoi(v[7]); // if (data_.orderType_ == OrderType::OT_Limit){ // data_.limitPrice_ = stof(v[8]); // }else if (data_.orderType_ == OrderType::OT_StopLimit){ // data_.stopPrice_ = stof(v[8]); // } // data_.orderFlag_ = static_cast(stoi(v[9])); // data_.tag_ = v[10]; } std::shared_ptr OrderMsg::toPOrder() { std::shared_ptr o = make_shared(); o->api_ = data_.api_; o->account_ = data_.account_; o->clientID_ = data_.clientID_; o->clientOrderID_ = data_.clientOrderID_; o->tag_ = data_.tag_; o->orderType_ = data_.orderType_; o->fullSymbol_ = data_.fullSymbol_; o->price_ = data_.price_; o->quantity_ = data_.quantity_; o->tradedvol_ = data_.tradedvol_; o->flag_ = data_.flag_; o->serverOrderID_ = data_.serverOrderID_; o->brokerOrderID_ = data_.brokerOrderID_; o->orderNo_ = data_.orderNo_; o->localNo_ = data_.localNo_; o->createTime_ = data_.createTime_; o->updateTime_ = data_.updateTime_; o->orderStatus_ = data_.orderStatus_; return o; } void PaperOrderMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 14) throw std::out_of_range("OutofRange in PaperOrder deserialize."); destination_ = v[0]; source_ = v[1]; data_.api_ = v[3]; data_.account_ = v[4]; data_.clientID_ = stoi(v[5]); data_.clientOrderID_ = stol(v[6]); data_.tag_ = v[7]; data_.orderType_ = static_cast(stoi(v[8])); data_.fullSymbol_ = v[9]; data_.orderFlag_ = static_cast(stoi(v[10])); data_.orderSize_ = stoi(v[11]); data_.limitPrice_ = stof(v[12]); data_.stopPrice_ = stof(v[13]); } std::shared_ptr PaperOrderMsg::toPOrder() { auto o = make_shared(); o->api_ = data_.api_; o->account_ = data_.account_; o->clientID_ = data_.clientID_; o->clientOrderID_ = data_.clientOrderID_; o->tag_ = data_.tag_; o->fullSymbol_ = data_.fullSymbol_; o->price_ = data_.price_; o->quantity_ = data_.quantity_; o->tradedvol_ = data_.tradedvol_; o->flag_ = data_.flag_; o->serverOrderID_ = data_.serverOrderID_; o->brokerOrderID_ = data_.brokerOrderID_; o->orderNo_ = data_.orderNo_; o->localNo_ = data_.localNo_; o->createTime_ = data_.createTime_; o->updateTime_ = data_.updateTime_; o->orderStatus_ = data_.orderStatus_; o->orderType_ = data_.orderType_; o->orderSize_ = data_.orderSize_; o->limitPrice_ = data_.limitPrice_; o->stopPrice_ = data_.stopPrice_; o->orderFlag_ = data_.orderFlag_; return o; } void CtpOrderMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 27) throw std::out_of_range("OutofRange in CtpOrder deserialize."); destination_ = v[0]; source_ = v[1]; data_.api_ = v[3]; data_.account_ = v[4]; data_.clientID_ = stoi(v[5]); data_.clientOrderID_ = stol(v[6]); data_.tag_ = v[7]; data_.orderType_ = OrderType(stoi(v[7])); data_.orderField_ = {}; strcpy(data_.orderField_.InstrumentID, v[8].c_str()); data_.orderField_.OrderPriceType = v[9][0]; data_.orderField_.Direction = v[10][0]; strcpy(data_.orderField_.CombOffsetFlag, v[11].c_str()); strcpy(data_.orderField_.CombHedgeFlag, v[12].c_str()); data_.orderField_.LimitPrice = stof(v[13]); data_.orderField_.VolumeTotalOriginal = stoi(v[14]); data_.orderField_.TimeCondition = v[15][0]; strcpy(data_.orderField_.GTDDate, v[16].c_str()); data_.orderField_.VolumeCondition = v[17][0]; data_.orderField_.MinVolume = stoi(v[18]); data_.orderField_.ContingentCondition = v[19][0]; data_.orderField_.StopPrice = stof(v[20]); data_.orderField_.ForceCloseReason = v[21][0]; data_.orderField_.IsAutoSuspend = stoi(v[22]); data_.orderField_.UserForceClose = stoi(v[23]); data_.orderField_.IsSwapOrder = stoi(v[24]); strcpy(data_.orderField_.BusinessUnit, v[25].c_str()); strcpy(data_.orderField_.CurrencyID, v[26].c_str()); } std::shared_ptr CtpOrderMsg::toPOrder() { std::shared_ptr o = make_shared(); o->api_ = data_.api_; o->account_ = data_.account_; o->clientID_ = data_.clientID_; o->clientOrderID_ = data_.clientOrderID_; o->tag_ = data_.tag_; o->orderType_ = data_.orderType_; o->fullSymbol_ = data_.fullSymbol_; o->price_ = data_.price_; o->quantity_ = data_.quantity_; o->tradedvol_ = data_.tradedvol_; o->flag_ = data_.flag_; o->serverOrderID_ = data_.serverOrderID_; o->brokerOrderID_ = data_.brokerOrderID_; o->orderNo_ = data_.orderNo_; o->localNo_ = data_.localNo_; o->createTime_ = data_.createTime_; o->updateTime_ = data_.updateTime_; o->orderStatus_ = data_.orderStatus_; memcpy(&o->orderField_, &data_.orderField_, sizeof(CThostFtdcInputOrderField)); // return static_pointer_cast(o); return o; } void CtpParkedOrderMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 27) throw std::out_of_range("OutofRange in CtpParkOrder deserialize."); destination_ = v[0]; source_ = v[1]; data_.api_ = v[3]; data_.account_ = v[4]; data_.clientID_ = stoi(v[5]); data_.clientOrderID_ = stol(v[6]); data_.tag_ = v[7]; data_.parkedOrderField_ = {}; strcpy(data_.parkedOrderField_.InstrumentID, v[8].c_str()); data_.parkedOrderField_.OrderPriceType = v[9][0]; data_.parkedOrderField_.Direction = v[10][0]; strcpy(data_.parkedOrderField_.CombOffsetFlag, v[11].c_str()); strcpy(data_.parkedOrderField_.CombHedgeFlag, v[12].c_str()); data_.parkedOrderField_.LimitPrice = stof(v[13]); data_.parkedOrderField_.VolumeTotalOriginal = stoi(v[14]); data_.parkedOrderField_.TimeCondition = v[15][0]; strcpy(data_.parkedOrderField_.GTDDate, v[16].c_str()); data_.parkedOrderField_.VolumeCondition = v[17][0]; data_.parkedOrderField_.MinVolume = stoi(v[18]); data_.parkedOrderField_.ContingentCondition = v[19][0]; data_.parkedOrderField_.StopPrice = stof(v[20]); data_.parkedOrderField_.ForceCloseReason = v[21][0]; data_.parkedOrderField_.IsAutoSuspend = stoi(v[22]); data_.parkedOrderField_.UserForceClose = stoi(v[23]); data_.parkedOrderField_.IsSwapOrder = stoi(v[24]); strcpy(data_.parkedOrderField_.BusinessUnit, v[25].c_str()); strcpy(data_.parkedOrderField_.CurrencyID, v[26].c_str()); } std::shared_ptr CtpParkedOrderMsg::toPOrder() { auto o = make_shared(); o->api_ = data_.api_; o->account_ = data_.account_; o->clientID_ = data_.clientID_; o->clientOrderID_ = data_.clientOrderID_; o->tag_ = data_.tag_; o->fullSymbol_ = data_.fullSymbol_; o->price_ = data_.price_; o->quantity_ = data_.quantity_; o->tradedvol_ = data_.tradedvol_; o->flag_ = data_.flag_; o->serverOrderID_ = data_.serverOrderID_; o->brokerOrderID_ = data_.brokerOrderID_; o->orderNo_ = data_.orderNo_; o->localNo_ = data_.localNo_; o->createTime_ = data_.createTime_; o->updateTime_ = data_.updateTime_; o->orderStatus_ = data_.orderStatus_; memcpy(&o->parkedOrderField_, &data_.parkedOrderField_, sizeof(CThostFtdcParkedOrderField)); //return static_pointer_cast(o); return o; } void OrderStatusMsg::set(std::shared_ptr po) { // data_ = *po; data_.api_ = po->api_; data_.account_ = po->account_; data_.clientID_ = po->clientID_; data_.clientOrderID_ = po->clientOrderID_; data_.tag_ = po->tag_; data_.orderType_ = po->orderType_; data_.fullSymbol_ = po->fullSymbol_; data_.price_ = po->price_; data_.quantity_ = po->quantity_; data_.tradedvol_ = po->tradedvol_; data_.flag_ = po->flag_; data_.serverOrderID_ = po->serverOrderID_; data_.brokerOrderID_ = po->brokerOrderID_; data_.orderNo_ = po->orderNo_; data_.localNo_ = po->localNo_; data_.createTime_ = po->createTime_; data_.updateTime_ = po->updateTime_; data_.orderStatus_ = po->orderStatus_; } string OrderStatusMsg::serialize() { string str = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_.api_ + SERIALIZATION_SEPARATOR + data_.account_ + SERIALIZATION_SEPARATOR + std::to_string(data_.clientID_) + SERIALIZATION_SEPARATOR + std::to_string(data_.clientOrderID_) + SERIALIZATION_SEPARATOR + data_.tag_ + SERIALIZATION_SEPARATOR + data_.fullSymbol_ + SERIALIZATION_SEPARATOR + std::to_string(data_.price_) + SERIALIZATION_SEPARATOR + std::to_string(data_.quantity_) + SERIALIZATION_SEPARATOR + std::to_string(data_.tradedvol_) + SERIALIZATION_SEPARATOR + std::to_string(data_.flag_) + SERIALIZATION_SEPARATOR + std::to_string(data_.serverOrderID_) + SERIALIZATION_SEPARATOR + std::to_string(data_.brokerOrderID_) + SERIALIZATION_SEPARATOR + data_.orderNo_ + SERIALIZATION_SEPARATOR + data_.localNo_ + SERIALIZATION_SEPARATOR + data_.createTime_ + SERIALIZATION_SEPARATOR + data_.updateTime_ + SERIALIZATION_SEPARATOR + std::to_string(data_.orderStatus_); return str; } string PosMsg::serialize() { string str = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_.key_ + SERIALIZATION_SEPARATOR + data_.account_ + SERIALIZATION_SEPARATOR + data_.api_ + SERIALIZATION_SEPARATOR + data_.fullSymbol_ + SERIALIZATION_SEPARATOR + data_.type_ + SERIALIZATION_SEPARATOR + std::to_string(data_.avgPrice_) + SERIALIZATION_SEPARATOR + std::to_string(data_.size_) + SERIALIZATION_SEPARATOR + std::to_string(data_.preSize_) + SERIALIZATION_SEPARATOR + std::to_string(data_.freezedSize_) + SERIALIZATION_SEPARATOR + std::to_string(data_.closedpl_) + SERIALIZATION_SEPARATOR + std::to_string(data_.openpl_) + SERIALIZATION_SEPARATOR + ymdhmsf(); return str; } void PosMsg::set(std::shared_ptr pp) { // data_ = *pp; data_.key_ = pp->key_; data_.account_ = pp->account_; data_.api_ = pp->api_; data_.fullSymbol_ = pp->fullSymbol_; data_.avgPrice_ = pp->avgPrice_; data_.size_ = pp->size_; data_.preSize_ = pp->preSize_; data_.freezedSize_ = pp->freezedSize_; data_.openpl_ = pp->openpl_; data_.closedpl_ = pp->closedpl_; data_.type_ = pp->type_; data_.posNo_ = pp->posNo_; } void OrderActionMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 6) throw std::out_of_range("OutofRange in OrderAction deserialize."); destination_ = v[0]; source_ = v[1]; data_.clientID_ = stoi(v[3]); data_.clientOrderID_ = stol(v[4]); data_.serverOrderID_ = stol(v[5]); } void SubscribeMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 5) throw std::out_of_range("OutofRange in Subscribe deserialize."); destination_ = v[0]; source_ = v[1]; symtype_ = SymbolType(stoi(v[3])); for (int32_t i = 4; i < v.size(); i++) data_.push_back(v[i]); } void UnSubscribeMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 5) throw std::out_of_range("OutofRange in Unsubscribe deserialize."); destination_ = v[0]; source_ = v[1]; symtype_ = SymbolType(stoi(v[3])); for (int32_t i = 4; i < v.size(); i++) data_.push_back(v[i]); } void QryContractMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 5) throw std::out_of_range("OutofRange in qrycontract deserialize."); destination_ = v[0]; source_ = v[1]; symtype_ = SymbolType(stoi(v[3])); data_ = v[4]; } void CancelAllMsg::deserialize(const string& msgin) { vector v = stringsplit(msgin, SERIALIZATION_SEPARATOR); if (v.size() < 5) throw std::out_of_range("OutofRange in cancelall deserialize."); destination_ = v[0]; source_ = v[1]; symtype_ = SymbolType(stoi(v[3])); data_ = v[4]; } string ErrorMsg::serialize() { string str = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_ + SERIALIZATION_SEPARATOR + ymdhms(); return str; } string InfoMsg::serialize() { string str = destination_ + SERIALIZATION_SEPARATOR + source_ + SERIALIZATION_SEPARATOR + to_string(msgtype_) + SERIALIZATION_SEPARATOR + data_ + SERIALIZATION_SEPARATOR + ymdhms(); return str; } } // namespace StarQuant