/***************************************************************************** * 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 #include #include #include #include #include namespace StarQuant { DataManager* DataManager::pinstance_ = nullptr; mutex DataManager::instancelock_; DataManager::DataManager() : count_(0) { loadSecurityFile(); } DataManager::~DataManager() {} DataManager& DataManager::instance() { if (pinstance_ == nullptr) { lock_guard g(instancelock_); if (pinstance_ == nullptr) { pinstance_ = new DataManager(); } } return *pinstance_; } void DataManager::updateOrderBook(const Fill& fill) { // assume only price change if (orderBook_.find(fill.fullSymbol_) != orderBook_.end()) { orderBook_[fill.fullSymbol_].price_ = fill.tradePrice_; orderBook_[fill.fullSymbol_].size_ = fill.tradeSize_; } else { Tick newk; newk.depth_ = 0; newk.price_ = fill.tradePrice_; newk.size_ = fill.tradeSize_; orderBook_[fill.fullSymbol_] = newk; } } void DataManager::loadSecurityFile() { try { string contractpath = boost::filesystem::current_path().string() + "/etc/ctpcontract.yaml"; YAML::Node contractinfo = YAML::LoadFile(contractpath); for (YAML::const_iterator symsec = contractinfo.begin(); symsec != contractinfo.end(); symsec++) { auto sym = symsec->first.as(); auto securities = symsec->second; Security sec; sec.symbol_ = securities["symbol"].as(); sec.exchange_ = securities["exchange"].as(); sec.securityType_ = securities["product"].as(); sec.multiplier_ = securities["size"].as(); sec.localName_ = securities["name"].as(); sec.ticksize_ = securities["pricetick"].as(); sec.postype_ = securities["positiontype"].as(); sec.longMarginRatio_ = securities["long_margin_ratio"].as(); sec.shortMarginRatio_ = securities["short_margin_ratio"].as(); sec.underlyingSymbol_ = securities["option_underlying"].as(); sec.optionType_ = securities["option_type"].as(); sec.strikePrice_ = securities["option_strike"].as(); sec.expiryDate_ = securities["option_expiry"].as(); sec.fullSymbol_ = securities["full_symbol"].as(); securityDetails_[sym] = sec; ctp2Full_[sym] = sec.fullSymbol_; full2Ctp_[sec.fullSymbol_] = sym; } // back up std::ofstream fout("etc/ctpcontract.yaml.bak"); fout<< contractinfo; } catch(exception &e) { fmt::print("Read contract exception:{}.", e.what()); } catch(...) { fmt::print("Read contract error!"); } } void DataManager::saveSecurityToFile() { try { YAML::Node securities; for (auto iterator = securityDetails_.begin(); iterator != securityDetails_.end(); ++iterator) { auto sym = iterator->first; auto sec = iterator->second; securities[sym]["symbol"] = sec.symbol_; securities[sym]["exchange"] = sec.exchange_; securities[sym]["product"] = sec.securityType_; securities[sym]["size"] = sec.multiplier_; securities[sym]["name"] = sec.localName_; securities[sym]["pricetick"] = sec.ticksize_; securities[sym]["positiontype"] = sec.postype_; securities[sym]["long_margin_ratio"] = sec.longMarginRatio_; securities[sym]["short_margin_ratio"] = sec.shortMarginRatio_; securities[sym]["option_underlying"] = sec.underlyingSymbol_; securities[sym]["option_type"] = sec.optionType_; securities[sym]["option_strike"] = sec.strikePrice_; securities[sym]["option_expiry"] = sec.expiryDate_; string fullsym; string type; string product; string contracno; int32_t i; if (sec.securityType_ == '1' || sec.securityType_ == '2') { for (i = 0; i < sym.size(); i++) { if (isdigit(sym[i])) break; } product = sym.substr(0, i); contracno = sym.substr(i); type = (sec.securityType_ == '1'? "F":"O"); fullsym = sec.exchange_ + " " + type + " " + boost::to_upper_copy(product) + " " + contracno; } else if (sec.securityType_ == '3') { int32_t pos = sym.find(" "); string combo = sym.substr(pos+1); int32_t sep = combo.find("&"); string sym1 = combo.substr(0, sep); string sym2 = combo.substr(sep+1); for (i = 0; i < sym1.size(); i++) { if (isdigit(sym1[i])) break; } product = sym1.substr(0, i) + "&"; contracno = sym1.substr(i) + "&"; for (i = 0; i < sym2.size(); i++) { if (isdigit(sym2[i])) break; } product += sym2.substr(0, i); contracno += sym2.substr(i); fullsym = sec.exchange_ + " " + "S" + " " + boost::to_upper_copy(product) + " " + contracno; } else { fullsym = sec.exchange_ + " " + sec.securityType_ + " " + sym; } securities[sym]["full_symbol"] = fullsym; ctp2Full_[sym] = fullsym; full2Ctp_[fullsym] = sym; securityDetails_[sym].fullSymbol_ = fullsym; } std::ofstream fout("etc/ctpcontract.yaml"); fout<< securities; } catch(exception &e) { fmt::print("Write Contract exception:{}.", e.what()); } catch(...) { fmt::print("Write Contract error!"); } } void DataManager::reset() { orderBook_.clear(); //_5s.clear(); //_15s.clear(); // _60s.clear(); //_1d.clear(); securityDetails_.clear(); count_ = 0; } void DataManager::rebuild() { // for (auto& s : CConfig::instance().securities) { // Tick_L5 k; // k.fullsymbol_ = s; // _latestmarkets[s] = k; // //_5s[s].fullsymbol = s; _5s[s].interval_ = 5; // //_15s[s].fullsymbol = s; _15s[s].interval_ = 15; // // _60s[s].fullsymbol = s; _60s[s].interval_ = 60; // //_1d[s].fullsymbol = s; _1d[s].interval_ = 24 * 60 * 60; // } } // void DataManager::SetTickValue(Tick& k) { // PRINT_TO_FILE("INFO:[%s,%d][%s]%s, %.2f\n", __FILE__, __LINE__, __FUNCTION__, k.fullsymbol_.c_str(), k.price_); // for debug // //cout<<"settickvalue ktype: "<(k); // default assigement shallow copy // _latestmarkets[k.fullsymbol_].price_ = k.price_; // _latestmarkets[k.fullsymbol_].size_ = k.size_; // //cout<<"settickvalue price"<<_latestmarkets[k.fullsymbol_].price_<