void GatewayMgr::showVersion() { g_sm->checkCurrentOn(ServiceMgr::LOGIC); BfInfo(QString("mdapi version: ") + MdSm::version()); BfInfo(QString("tdapi version: ") + TdSm::version()); }
void GatewayMgr::onTdSmStateChanged(int state) { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (!tdsm_) { BfDebug("tdsm freed,ingore onTdSmStateChanged:%d", state); return; } if (state == TDSM_CONNECTED) { tdsm_logined_ = false; if (autoLoginTd_) { tdsm_->login(1000); } else { tdsm_->stop(); } } if (state == TDSM_DISCONNECTED) { resetCmds(); tdsm_logined_ = false; if (!autoLoginTd_) { tdsm_->stop(); } else { BfInfo("waiting for tdapi auto-reconnect......"); } } if (state == TDSM_LOGINED) { tdsm_logined_ = true; tryStartSubscrible(); } if (state == TDSM_LOGINFAIL) { if (autoLoginTd_) { BfInfo("tdsm login fail,try again 1 minute later"); tdsm_->login(60 * 1000); } else { tdsm_->stop(); } } if (state == TDSM_LOGOUTED) { tdsm_logined_ = false; tdsm_->stop(); } if (state == TDSM_LOGOUTFAIL) { tdsm_logined_ = false; tdsm_->stop(); } if (state == TDSM_STOPPED) { resetCmds(); tdsm_logined_ = false; delete tdsm_; tdsm_ = nullptr; tdsm_logined_ = false; } }
void DbService::dbOpen() { BfDebug(__FUNCTION__); g_sm->checkCurrentOn(ServiceMgr::DB); if (db_) { BfInfo("db opened already"); return; } QString path = Profile::dbPath(); mkDir(path); leveldb::Options options; options.create_if_missing = true; options.error_if_exists = false; options.compression = leveldb::kNoCompression; options.paranoid_checks = false; leveldb::DB* db; leveldb::Status status = leveldb::DB::Open(options, path.toStdString(), &db); if (!status.ok()) { qFatal("leveldb::DB::Open fail"); } db_ = db; }
void MainWindow::runOnExternalEx(QFutureInterface<void>& future) { g_sm->checkCurrentOn(ServiceMgr::EXTERNAL); BfInfo(__FUNCTION__); future.reportFinished(); }
void OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) override { if (bIsLast) { BfInfo(__FUNCTION__); isErrorRsp(pRspInfo, nRequestID); } }
QString GatewayMgr::genOrderId() { if (tdsm_ == nullptr) { BfInfo("GatewayMgr::genOrderId,please login first"); return "888.888.888"; } return tdsm_->genBfOrderId(); }
bool isErrorRsp(CThostFtdcRspInfoField* pRspInfo, int reqId) { if (pRspInfo && pRspInfo->ErrorID != 0) { BfInfo("<==error,reqid=%d,errorId=%d,msg=%s", reqId, pRspInfo->ErrorID, gbk2utf16(pRspInfo->ErrorMsg).toUtf8().constData()); return true; } return false; }
void CtpMgr::onMdSmStateChanged(int state) { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (!mdsm_) { BfDebug("mdsm freed,ingore onMdSmStateChanged:%d", state); return; } if (state == MDSM_CONNECTED) { mdsm_logined_ = false; if (autoLoginMd_) { mdsm_->login(1000, ""); } else { mdsm_->stop(); } } if (state == MDSM_DISCONNECTED) { mdsm_logined_ = false; if (!autoLoginMd_) { mdsm_->stop(); }else{ BfInfo("waiting for mdapi auto-reconnect......"); } } if (state == MDSM_LOGINED) { mdsm_logined_ = true; tryStartSubscrible(); } if (state == MDSM_LOGINFAIL) { if (autoLoginMd_) { BfInfo("mdsm login fail,try again 1 minute later"); mdsm_->login(60 * 1000, ""); } else { mdsm_->stop(); } } if (state == MDSM_STOPPED) { mdsm_logined_ = false; delete mdsm_; mdsm_ = nullptr; mdsm_logined_ = false; } }
void GatewayMgr::queryOrders() { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (tdsm_ == nullptr) { BfInfo("GatewayMgr::queryOrders,please login first"); return; } tdsm_->queryOrders(0); }
void CtpMgr::queryPosition() { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (tdsm_ == nullptr) { BfInfo("CtpMgr::queryPosition,please login first"); return; } tdsm_->queryPosition(0, ""); }
void CtpMgr::queryAccount() { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (tdsm_ == nullptr) { BfInfo("CtpMgr::queryAccount,please login first"); return; } tdsm_->queryAccount(0); }
void CtpMgr::sendOrder(const BfSendOrderReq& req) { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (tdsm_ == nullptr) { BfInfo("CtpMgr::sendOrder,please login first"); return; } tdsm_->sendOrder(0, "", req); }
void MainWindow::on_actionAppQuit_triggered() { if (g_sm->ctpMgr()->running()) { this->showNormal(); BfInfo("please stop ctp first"); return; } Logger::stopExitMonitor(); qApp->quit(); }
void GatewayMgr::cancelOrder(const BfCancelOrderReq& req) { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (tdsm_ == nullptr) { BfInfo("GatewayMgr::cancelOrder,please login first"); return; } tdsm_->cancelOrder(0, req); }
void GatewayMgr::sendOrderWithId(QString bfOrderId, const BfSendOrderReq& req) { g_sm->checkCurrentOn(ServiceMgr::LOGIC); if (tdsm_ == nullptr) { BfInfo("GatewayMgr::sendOrder,please login first"); return; } tdsm_->sendOrder(0, bfOrderId, req); }
void DbService::dbClose() { BfDebug(__FUNCTION__); g_sm->checkCurrentOn(ServiceMgr::DB); if (db_ == nullptr) { BfInfo("db not open yet"); return; } delete db_; db_ = nullptr; }
// errorId=7,msg=CTP:还没有初始化= void OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) override { BfInfo(__FUNCTION__); if (bIsLast) { if (isErrorRsp(pRspInfo, nRequestID)) { emit sm()->statusChanged(MDSM_LOGINFAIL); } else { emit sm()->statusChanged(MDSM_LOGINED); } } }
bool CtpMgr::initMdSm() { g_sm->checkCurrentOn(ServiceMgr::LOGIC); mdsm_ = new MdSm; bool res = mdsm_->init(profile()->get("userId").toString(), password_, profile()->get("brokerId").toString(), profile()->get("frontMd").toString(), Profile::flowPathMd()); if (!res) { delete mdsm_; mdsm_ = nullptr; BfInfo("invalid parameter,check please"); return false; } return true; }
bool GatewayMgr::initTdSm() { g_sm->checkCurrentOn(ServiceMgr::LOGIC); tdsm_ = new TdSm; bool res = tdsm_->init(profile()->get("userId").toString(), password_, profile()->get("brokerId").toString(), profile()->get("frontTd").toString(), Profile::flowPathTd(), profile()->get("idPrefixList").toString()); if (!res) { delete tdsm_; tdsm_ = nullptr; BfInfo("invalid parameter,check please"); return false; } return true; }
// 订阅成功了也会调用,目前是不管啥都返回订阅成功= void OnRspSubMarketData( CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) override { if (!isErrorRsp(pRspInfo, nRequestID) && pSpecificInstrument) { QString iid = pSpecificInstrument->InstrumentID; got_ids_ << iid; } if (bIsLast) { QString ids; for (auto id : got_ids_) { ids = ids + id + ";"; } BfInfo("total sub ids:%d,reqId=%d,%s", got_ids_.length(),nRequestID, ids.toUtf8().constData()); } }
void BarForm::on_delButton_clicked() { leveldb::DB* db = g_sm->dbService()->getDb(); QString key = ui->lineEdit->text(); leveldb::ReadOptions options; std::string val; leveldb::Status status = db->Get(options, key.toStdString(), &val); if (status.ok()) { leveldb::WriteOptions options; status = db->Delete(options, key.toStdString()); } if (status.ok()) { BfInfo("del,ok"); } else { QString errStr = QString::fromStdString(status.ToString()); BfError(errStr); } }
void MainWindow::runOnExternal() { g_sm->checkCurrentOn(ServiceMgr::EXTERNAL); BfInfo(__FUNCTION__); }
// 如果不是上期所,平今仓可用close或closeToday,平昨仓可用close或closeYesterday= // 如果是上期所,平今仓只可用closeToday,平昨仓可用close或closeYesterday= // 那成交回报的流水回来的时侯: // CloseYesterday=> insert =>CloseYesterday // CloseToday=> insert =>CloseToday // 也存在:closeToday =>close或closeYesterday =>close的情况= // 参考:http://www.cnblogs.com/xiaouisme/p/4654750.html void PositionForm::on_pushButtonCloseAll_clicked() { for (auto pos : positions_) { // 没有持仓的pass if (pos.position() == 0) { continue; } QString symbol = pos.symbol().c_str(); QString exchange = pos.exchange().c_str(); if (exchange.length() == 0) { void* contract = g_sm->gatewayMgr()->getContract(symbol); exchange = CtpUtils::getExchangeFromContract(contract); } // 没有订阅的pass if (!symbols_my_.contains(symbol)) { BfInfo(symbol + " not subscrible,please close byhand"); continue; } // 取不到tick的pass,比如晚上if不开盘= void* tick = g_sm->gatewayMgr()->getLatestTick(symbol); if (!tick) { BfInfo(symbol + " has no tick,please close byhand"); continue; } BfTickData bfTick; CtpUtils::translateTick(tick, nullptr, &bfTick); // 平昨= if (pos.ydposition() > 0) { // 限价单= BfOffset offset = OFFSET_CLOSE; BfPriceType priceType = PRICETYPE_LIMITPRICE; //TODO(hege):这里要判断是否超过了contract->maxLimit //TODO(hege):这里要判断昨持仓和今持仓,先平昨再平今= int volume = pos.ydposition(); //空单-->最高价+多+平= //多单-->最低价+空+平= double price = bfTick.upperlimit(); BfDirection direction = DIRECTION_LONG; if (pos.direction() == DIRECTION_NET || pos.direction() == DIRECTION_LONG) { direction = DIRECTION_SHORT; price = bfTick.lowerlimit(); } BfSendOrderReq req; req.set_symbol(symbol.toStdString()); req.set_exchange(exchange.toStdString()); req.set_price(price); req.set_volume(volume); req.set_direction(direction); req.set_offset(offset); req.set_pricetype(priceType); QMetaObject::invokeMethod(g_sm->gatewayMgr(), "sendOrder", Qt::QueuedConnection, Q_ARG(BfSendOrderReq, req)); } // 平今= if (pos.position() - pos.ydposition() > 0) { // 限价单= BfOffset offset = OFFSET_CLOSETODAY; BfPriceType priceType = PRICETYPE_LIMITPRICE; //TODO(hege):这里要判断是否超过了contract->maxLimit int volume = pos.position() - pos.ydposition(); //空单-->最高价+多+平= //多单-->最低价+空+平= double price = bfTick.upperlimit(); BfDirection direction = DIRECTION_LONG; if (pos.direction() == DIRECTION_NET || pos.direction() == DIRECTION_LONG) { direction = DIRECTION_SHORT; price = bfTick.lowerlimit(); } BfSendOrderReq req; req.set_symbol(symbol.toStdString()); req.set_exchange(exchange.toStdString()); req.set_price(price); req.set_volume(volume); req.set_direction(direction); req.set_offset(offset); req.set_pricetype(priceType); QMetaObject::invokeMethod(g_sm->gatewayMgr(), "sendOrder", Qt::QueuedConnection, Q_ARG(BfSendOrderReq, req)); } } }
void MainWindow::on_actionAppVersion_triggered() { BfInfo(QString("application's buildtime<error>: ") + QString(__DATE__) + " " + QString(__TIME__)); BfInfo(QString("application's buildtime<info>: ") + QString(__DATE__) + " " + QString(__TIME__)); BfInfo(QString("application's buildtime<debug>: ") + QString(__DATE__) + " " + QString(__TIME__)); }
void OnFrontConnected() override { BfInfo(__FUNCTION__); emit sm()->statusChanged(MDSM_CONNECTED); }
// 如果网络异常,会直接调用OnFrontDisconnected,需要重置状态数据= // 网络错误当再次恢复时候,会自动重连重新走OnFrontConnected void OnFrontDisconnected(int nReason) override { BfInfo("MdSmSpi::OnFrontDisconnected,nReason=0x%x", nReason); emit sm()->statusChanged(MDSM_DISCONNECTED); }