#include "common/pch.h" #include "SellManager.h" #include "../common/NetworkApi.h" #include "../common/JsonUtil.h" #include "ConfigUtil.h" #include "../common/JsonUtil.h" #include "../common/TimeUtil.h" #include #include SellSetting* SellManager::getSellSetting(string code) { if (sellSettingMap.find(code) != sellSettingMap.end()) { return sellSettingMap[code]; } return nullptr; } CodePosition* SellManager::getCodePosition(string code) { if (codePositionMap.find(code) != codePositionMap.end()) { return codePositionMap[code]; } return nullptr; } int SellManager::sell(string code, int sellPriceType) { if (sellSettingMap.find(code) == sellSettingMap.end()) { throw wstring(L"ÉÐδÉèÖÃÂô³ö¹æÔò"); } //»ñÈ¡³Ö²ÖÐÅÏ¢ if (codePositionMap.find(code) == codePositionMap.end()) { throw wstring(L"ÉÐδ»ñÈ¡µ½³Ö²Ö"); } int money = computeCurrentMoney(code); if (money <= 0) { throw wstring(L"¿ÉÂô³öÁ¿Îª0"); } int volume = sellMoneyToVolume(money, codePositionMap[code]->costPrice); if (volume > codePositionMap[code]->available) { volume = codePositionMap[code]->available; } return sell(code, volume, sellPriceType); } int SellManager::sell(string code, int volume, int sellPriceType) { string result = NetworkApi::sell(code, volume, sellPriceType, true); CString msg(code.c_str()); msg.Append(L"£º"); auto doc = JsonUtil::parseUTF16(result); if (doc.IsObject() && doc.HasMember(L"code")) { if (doc[L"code"] == 0) { if (doc[L"data"].HasMember(L"orderRef")) { msg.Append(_T("Ìá½»Âô³É¹¦")); int orderRef = doc[L"data"][L"orderRef"].GetInt(); return orderRef; } else if (doc[L"data"].HasMember(L"orderStatusMsg")) { msg.Append(doc[L"data"][L"orderStatusMsg"].GetString()); throw wstring(msg); } } else { if (doc.HasMember(L"msg")) { msg.Append(doc[L"msg"].GetString()); throw wstring(msg); } } } else { msg.Append(L"½âÎö½á¹û³ö´í"); throw wstring(msg); } } void SellManager::lockVolume(string code, int volume) { } void SellManager::unLockVolume(string code) { } int SellManager::computeCurrentMoney(string code) { SellSetting* sellSetting = sellSettingMap[code]; CodePosition* pos = codePositionMap[code]; //if (pos->available <= 0) { // return 0; //} int sell_count_100 = 0; int available_100 = pos->available / 100; if (!sellSetting->lock) { if (sellSetting->setting_mode == SETTING_MODE_RATE) { list volumeList = distributeVolume(pos->total / 100, sellSetting->mode1_rate_index); sell_count_100 = computeSellVolume(volumeList, pos->sell_orders); } else { int first_percent = (sellSetting->mode2_first_index + 1) * 10; int second_count = (sellSetting->mode2_left_index + 1); int total_100 = pos->total / 100; if (pos->sell_orders.size() == 0) { sell_count_100 = total_100 * first_percent / 100; if (total_100 * first_percent % 100 != 0) { sell_count_100 += 1; } } else { // ×ֲּܳõÈ¥µÚÒ»´ÎµÄ³Ö²Ö list volumeList = distributeVolume(total_100 - *(pos->sell_orders.begin()) / 100, second_count); list::iterator el = volumeList.begin(); advance(el, pos->sell_orders.size() - 1); if (el != volumeList.end()) { sell_count_100 = *el; } else { sell_count_100 = 0; } } } } else { if (sellSetting->lockMoney <= 0) { CString msg = L"Ëø¶¨Á¿´íÎó:"; msg.Append(to_wstring(sellSetting->lockMoney).c_str()); throw wstring(msg); } // µ±Ç°Ê±¼äÔÚ09:30Ö®ºó£¬Ëø¶¨Ê±¼äÔÚ09:30֮ǰµÄ¾Í·µ»ØÄ¬ÈÏÖµ /*auto nowTime = stoi(TimeUtil::getNowTime("%H%M%S").c_str()); if (nowTime >= 93000 && sellSetting->lockTime < 93000) { return ConfigUtil::getSellMoney(); }*/ return sellSetting->lockMoney; } if (sell_count_100 > available_100) { sell_count_100 = available_100; } return (int) round(sell_count_100 * 100 * pos->costPrice); } void SellManager::syncSettingToFile(string code) { // ¶ÔÏóתΪjson if (sellSettingMap.find(code)== sellSettingMap.end()) { return; } SellSetting* sellSetting = sellSettingMap[code]; auto nowDate = getNowDate(); string key = string("sell_setting-").append(nowDate).append("-").append(code); rapidjson::StringBuffer buf; rapidjson::PrettyWriter writer(buf); writer.StartObject(); writer.Key("setting_mode"); writer.Int(sellSetting->setting_mode); writer.Key("lock"); writer.Bool(sellSetting->lock); writer.Key("lockMoney"); writer.Int(sellSetting->lockMoney); writer.Key("lockBuy"); writer.Bool(sellSetting->lockBuy); writer.Key("lockBuyMoney"); writer.Int(sellSetting->lockBuyMoney); writer.Key("mode1_rate_index"); writer.Int(sellSetting->mode1_rate_index); writer.Key("mode2_first_index"); writer.Int(sellSetting->mode2_first_index); writer.Key("mode2_left_index"); writer.Int(sellSetting->mode2_left_index); writer.EndObject(); const char* json_content = buf.GetString(); ConfigUtil::setStringConfig(key.c_str(), json_content); } void SellManager::clearPreSettings() { list keys = ConfigUtil::getKeys(); auto nowDate = getNowDate(); string prefix = string("sell_setting-"); string prefix_today = string("sell_setting-").append(nowDate); for (list::iterator e = keys.begin(); e != keys.end(); e++) { string key = *e; if (key.find(prefix) == 0 && key.find(prefix_today) < 0) { ConfigUtil::delKey(key); } } } string SellManager::getNowDate() { std::time_t now = std::time(nullptr); // ʹÓñ¾µØÊ±¼äת»»µ±Ç°Ê±¼ä std::tm currentDate; localtime_s(¤tDate,&now); // ¶¨ÒåÈÕÆÚ¸ñʽ char buffer[80]; std::strftime(buffer, sizeof(buffer), "%Y%m%d", ¤tDate); return string(buffer); } SellSetting* SellManager::loadSettingFromFile(string code) { auto nowDate = getNowDate(); string key = string("sell_setting-").append(nowDate).append("-").append(code); try { string result = ConfigUtil::readStringConfig(key.c_str()); auto doc = JsonUtil::parseUTF8(result); SellSetting* setting = new SellSetting(); setting->lock = doc["lock"].GetBool(); setting->lockMoney = doc["lockMoney"].GetInt(); setting->lockBuy = doc["lockBuy"].GetBool(); setting->lockBuyMoney = doc["lockBuyMoney"].GetInt(); setting->setting_mode = doc["setting_mode"].GetInt()==0? SETTING_MODE_RATE: SETTING_MODE_PERCENT; setting->mode2_first_index = doc["mode2_first_index"].GetInt(); setting->mode2_left_index = doc["mode2_left_index"].GetInt(); setting->mode1_rate_index = doc["mode1_rate_index"].GetInt(); return setting; } catch (...) { } return nullptr; } list SellManager::distributeVolume(UINT total, UINT percent) { list volumeList; UINT base = total / percent; UINT left = total % percent; for (UINT i = 0; i < percent; i++) { if (i + 1 <= left) { volumeList.push_back(base + 1); } else { volumeList.push_back(base); } } return volumeList; } UINT SellManager::computeSellVolume(list volumeList, list sell_volumes) { if (sell_volumes.size() >= volumeList.size()) { return 0; } list::iterator el = volumeList.begin(); advance(el, sell_volumes.size()); if (el != volumeList.end()) { return *el; } return 0; } int SellManager::sellMoneyToVolume(int money, double price) { int volume = ((int)round((money / price) * 100)) / 100; volume = volume < 0 ? 0 : volume; return volume / 100 * 100; } void SellManager::init(string code) { // ³õʼ»¯´úÂë if (getSellSetting(code) == nullptr) { SellSetting* setting = loadSettingFromFile(code); if (setting == nullptr) { setting = new SellSetting(); setting->lock = true; setting->lockMoney = ConfigUtil::getSellMoney(); setting->lockBuy = true; setting->lockTime = stoi(TimeUtil::getNowTime("%H%M%S").c_str()); setting->lockBuyMoney = 0; setting->setting_mode = SETTING_MODE_RATE; setting->mode1_rate_index = 4; } sellSettingMap[code] = setting; } if (getCodePosition(code) == nullptr) { CodePosition* codePosition = new CodePosition(); codePosition->available = 0; codePosition->costPrice = 0.0f; codePosition->total = 0; codePosition->sell_rules_count = 0; codePosition->sell_orders = list(); codePositionMap[code] = codePosition; } }