diff --git a/config/contract/bk_contract.config b/config/contract/bk_contract.config index 96afdbb..18ef20f 100644 --- a/config/contract/bk_contract.config +++ b/config/contract/bk_contract.config @@ -856,34 +856,34 @@ map = ( }, { - ticker = "ETH-USDT-SWAP"; + ticker = "OKEX@ETH-USDT-SWAP"; info = ""; exchange = ""; deposit_rate = 0.; contract_size = 1; min_price_move = 0.01; - cancel_limit = 1000000000000000; + cancel_limit = 100000000; is_fixed_open_fee_rate = false; is_fixed_close_today_fee_rate = false; is_fixed_close_fee_rate = false; open_fee_rate = 0.0005; close_today_fee_rate = 0.0005; - close_fee_fee_rate = 0.0005; + close_fee_rate = 0.0005; }, { - ticker = "ETH-USDT-this_week"; + ticker = "OKEX@ETH-USDT-this_week"; info = ""; exchange = ""; deposit_rate = 0.; contract_size = 1; min_price_move = 0.01; - cancel_limit = 1000000000000000; + cancel_limit = 100000000; is_fixed_open_fee_rate = false; is_fixed_close_today_fee_rate = false; is_fixed_close_fee_rate = false; open_fee_rate = 0.0005; close_today_fee_rate = 0.0005; - close_fee_fee_rate = 0.0005; + close_fee_rate = 0.0005; } ); diff --git a/config/prod/coin_prod.config b/config/prod/coin_prod.config index a362a07..d12a609 100644 --- a/config/prod/coin_prod.config +++ b/config/prod/coin_prod.config @@ -1,11 +1,11 @@ strategy = ( { unique_name = "btc"; - paris = ("OKEX/ETH-USD-SWAP", "OKEX/ETH-USD-this_week"); + pairs = ("OKEX@ETH-USDT-SWAP", "OKEX@ETH-USDT-this_week"); max_position = 1; - max_round = 4000; - range_width = 2.0; - train_samples = 1200; + max_round = 10000; + range_width = 1.0; + train_samples = 12000; min_range = 4.0; min_profit = 1.0; add_margin = 3.0; @@ -14,7 +14,7 @@ strategy = ( stop_loss_margin = 10.0; max_loss_times = 2; split_num = 6; - no_close_today = true; + no_close_today = false; } ); order_file = "order.dat"; diff --git a/config/prod/coin_time.config b/config/prod/coin_time.config new file mode 100644 index 0000000..9c3cde3 --- /dev/null +++ b/config/prod/coin_time.config @@ -0,0 +1,7 @@ +time_controller : +{ + sleep_time = []; + close_time = []; + force_close_time = []; + invalid_time = []; +}; diff --git a/external/common/include/core/strategy_container.hpp b/external/common/include/core/strategy_container.hpp index b6081ea..f926da4 100644 --- a/external/common/include/core/strategy_container.hpp +++ b/external/common/include/core/strategy_container.hpp @@ -18,8 +18,9 @@ using namespace std; template class T> class StrategyContainer { public: - StrategyContainer(unordered_map > &m) + StrategyContainer(unordered_map > &m, bool debug_mode = false) : m(m), + debug_mode_(debug_mode), marketdata_recver(new T("data_recver")), exchangeinfo_recver(new T("exchange_info")), command_recver(new ZmqRecver("*:33334", "tcp", "bind")) { @@ -32,7 +33,7 @@ class StrategyContainer { void Start() { thread command_thread(RunCommandListener, std::ref(m), command_recver.get()); thread exchangeinfo_thread(RunExchangeListener, std::ref(m), exchangeinfo_recver.get()); - thread marketdata_thread(RunMarketDataListener, std::ref(m), marketdata_recver.get()); + thread marketdata_thread(RunMarketDataListener, std::ref(m), marketdata_recver.get(), debug_mode_); command_thread.join(); exchangeinfo_thread.join(); marketdata_thread.join(); @@ -68,11 +69,15 @@ class StrategyContainer { } } - static void RunMarketDataListener(unordered_map > &m, T * marketdata_recver) { + static void RunMarketDataListener(unordered_map > &m, T * marketdata_recver, bool debug_mode) { + int count = 0; while (true) { MarketSnapshot shot; marketdata_recver->Recv(shot); auto sv = m[shot.ticker]; + if (debug_mode && count++ < 1000) { + shot.Show(stdout); + } for (auto s : sv) { s->UpdateData(shot); } @@ -80,6 +85,7 @@ class StrategyContainer { } unordered_map > &m; + bool debug_mode_; unique_ptr > marketdata_recver; unique_ptr > exchangeinfo_recver; unique_ptr > command_recver; diff --git a/external/common/lib/libnick.so b/external/common/lib/libnick.so index 21e14bc..11ba692 100755 Binary files a/external/common/lib/libnick.so and b/external/common/lib/libnick.so differ diff --git a/lib-hft b/lib-hft index eb47506..32c6e9c 160000 --- a/lib-hft +++ b/lib-hft @@ -1 +1 @@ -Subproject commit eb475061d2fc1a9c3d2d8e416868da404498aee0 +Subproject commit 32c6e9cd236bfb0b65026cb686c4e0ec5f29d430 diff --git a/src/coinarb/main.cpp b/src/coinarb/main.cpp index 9a43a87..3bbaf5d 100644 --- a/src/coinarb/main.cpp +++ b/src/coinarb/main.cpp @@ -27,27 +27,26 @@ int main() { std::string default_path = GetDefaultPath(); libconfig::Config param_cfg; - std::string config_path = default_path + "/hft/config/prod/prod.config"; + std::string config_path = default_path + "/hft/config/prod/coin_prod.config"; param_cfg.readFile(config_path.c_str()); - std::string time_config_path = default_path + "/hft/config/prod/time.config"; + std::string time_config_path = default_path + "/hft/config/prod/coin_time.config"; TimeController tc(time_config_path); std::unique_ptr > ui_sender(new ZmqSender("*:33333", "bind", "tcp", "mid.dat")); - std::unique_ptr > order_sender(new ZmqSender("order_sender", "connect", "ipc", "order.dat")); + std::unique_ptr > order_sender(new ZmqSender("order_recver", "bind", "ipc", "order.dat")); // std::unique_ptr > order_sender(new ZmqSender("order_recver", 100000, "order.dat")); std::unordered_map > ticker_strat_map; std::string contract_config_path = default_path + "/hft/config/contract/bk_contract.config"; - HistoryWorker hw(Dater::FindOneValid(Dater::GetCurrentDate(), -20)); ContractWorker cw(contract_config_path); const libconfig::Setting & strategies = param_cfg.lookup("strategy"); for (int i = 0; i < strategies.getLength(); i++) { const libconfig::Setting & param_setting = strategies[i]; - auto s = new Strategy(param_setting, &ticker_strat_map, ui_sender.get(), order_sender.get(), &tc, &cw, &hw, Dater::GetCurrentDate()); + auto s = new Strategy(param_setting, &ticker_strat_map, ui_sender.get(), order_sender.get(), &tc, &cw, Dater::GetCurrentDate()); s->Print(); } - StrategyContainer sc(ticker_strat_map); + StrategyContainer sc(ticker_strat_map, false); sc.Start(); } diff --git a/src/coinarb/strategy.cpp b/src/coinarb/strategy.cpp index b327830..9d11433 100644 --- a/src/coinarb/strategy.cpp +++ b/src/coinarb/strategy.cpp @@ -6,7 +6,7 @@ #include "./strategy.h" -Strategy::Strategy(const libconfig::Setting & param_setting, std::unordered_map >*ticker_strat_map, ZmqSender* uisender, ZmqSender* ordersender, TimeController* tc, ContractWorker* cw, HistoryWorker* hw, const std::string & date, StrategyMode::Enum mode, std::ofstream* exchange_file) +Strategy::Strategy(const libconfig::Setting & param_setting, std::unordered_map >*ticker_strat_map, ZmqSender* uisender, ZmqSender* ordersender, TimeController* tc, ContractWorker* cw, const std::string & date, StrategyMode::Enum mode, std::ofstream* exchange_file) : date_(date), max_close_try_(10), close_round_(0), @@ -16,7 +16,6 @@ Strategy::Strategy(const libconfig::Setting & param_setting, std::unordered_map< exchange_file_(exchange_file) { m_tc = tc; m_cw = cw; - m_hw = hw; // mids_.reserve(30000); SetStrategyMode(mode, exchange_file); if (FillStratConfig(param_setting)) { @@ -41,26 +40,27 @@ void Strategy::RunningSetup(std::unordered_mapLookup(unique_name); m_strat_name = unique_name; const libconfig::Setting& pairs = param_setting["pairs"]; const std::string& main_ticker = pairs[0]; const std::string& hedge_ticker = pairs[1]; - main_ticker_ = main_ticker; - hedge_ticker_ = hedge_ticker; - raw_main_ = TransCoin(main_ticker_); - raw_hedge_ = TransCoin(hedge_ticker_); - hedge_ticker_ = hedge_ticker; + raw_main_ = main_ticker; + raw_hedge_ = hedge_ticker; + main_ticker_ = TransCoin(raw_main_); + hedge_ticker_ = TransCoin(raw_hedge_); + printf("main=%s, hedge=%s\n", raw_main_.c_str(), raw_hedge_.c_str()); + printf("main_ticker=%s, hedge_ticker=%s\n", main_ticker_.c_str(), hedge_ticker_.c_str()); + const libconfig::Setting & main_contract_setting = m_cw->Lookup(raw_main_); + const libconfig::Setting & hedge_contract_setting = m_cw->Lookup(raw_hedge_); max_pos_ = param_setting["max_position"]; train_samples_ = param_setting["train_samples"]; double m_r = param_setting["min_range"]; double m_p = param_setting["min_profit"]; - min_price_move_ = contract_setting["min_price_move"]; + double min_price_move_main = main_contract_setting["min_price_move"]; + double min_price_move_hedge = hedge_contract_setting["min_price_move"]; + min_price_move_ = std::max(min_price_move_main, min_price_move_hedge); min_profit_ = m_p * min_price_move_; min_range_ = m_r * min_price_move_; double spread_threshold_int = param_setting["spread_threshold"]; @@ -91,7 +95,9 @@ bool Strategy::FillStratConfig(const libconfig::Setting& param_setting) { m_max_holding_sec = param_setting["max_holding_sec"]; range_width_ = param_setting["range_width"]; std::string con = GetCon(main_ticker_); - cancel_limit_ = contract_setting["cancel_limit"]; + int main_cancel_limit_ = main_contract_setting["cancel_limit"]; + int hedge_cancel_limit_ = hedge_contract_setting["cancel_limit"]; + cancel_limit_ = std::min(main_cancel_limit_, hedge_cancel_limit_); max_round_ = param_setting["max_round"]; if (param_setting.exists("no_close_today")) { no_close_today_ = param_setting["no_close_today"]; @@ -239,20 +245,24 @@ void Strategy::Open(OrderSide::Enum side) { bool Strategy::OpenLogic() { if (abs(m_position_map[main_ticker_]) >= max_pos_ || !m_order_map.empty()) { + // printf("block order exsited! no open \n"); + // PrintMap(m_order_map); return false; } auto main_shot = m_shot_map[main_ticker_]; auto hedge_shot = m_shot_map[hedge_ticker_]; if (main_shot.asks[0] - hedge_shot.asks[0] >= up_diff_) { // sell at high price - if (hedge_shot.ask_sizes[0] < 5) { // filter those too thin oppounity + printf("[%s %s]sell open, as %lf-%lf>= %lf, %d\n", main_ticker_.c_str(), hedge_ticker_.c_str(), main_shot.asks[0], hedge_shot.asks[0], up_diff_, hedge_shot.ask_sizes[0]); + if (hedge_shot.ask_sizes[0] < 1) { // filter those too thin oppounity return false; } - PlaceOrder(main_ticker_, main_shot.asks[0], -1, no_close_today_, "open")->Show(stdout); + PlaceOrder(main_ticker_, main_shot.asks[0]-min_price_move_, -1, no_close_today_, "open")->Show(stdout); } else if (main_shot.bids[0] - hedge_shot.bids[0] <= down_diff_) { // buy at low price - if (hedge_shot.bid_sizes[0] < 5) { // filter those too thin oppounity + printf("[%s %s]buy open, as %lf-%lf<= %lf, %d\n", main_ticker_.c_str(), hedge_ticker_.c_str(), main_shot.bids[0], hedge_shot.bids[0], down_diff_, hedge_shot.bid_sizes[0]); + if (hedge_shot.bid_sizes[0] < 1) { // filter those too thin oppounity return false; } - PlaceOrder(main_ticker_, main_shot.bids[0], 1, no_close_today_, "open")->Show(stdout); + PlaceOrder(main_ticker_, main_shot.bids[0]+min_price_move_, 1, no_close_today_, "open")->Show(stdout); } else { return false; } @@ -263,6 +273,7 @@ bool Strategy::OpenLogic() { void Strategy::Run() { if (!IsAlign() || close_round_ >= max_round_) { + if (close_round) return; } if (OpenLogic()) { @@ -296,7 +307,9 @@ void Strategy::DoOperationAfterUpdateData(const MarketSnapshot& shot) { current_spread_ = m_shot_map[main_ticker_].asks[0] - m_shot_map[main_ticker_].bids[0]; if (IsAlign()) { // && Spread_Good()) { mids_.push_back(GetMid(main_ticker_) - GetMid(hedge_ticker_)); - printf("[%s %s]mid_diff=%lf, head:%d, tail:%d\n", main_ticker_.c_str(), hedge_ticker_.c_str(), mids_.back(), sample_head_, sample_tail_); + if (mids_.size() % 300 == 0) { + printf("[%s %s]mid_diff=%lf, head:%d, tail:%d\n", main_ticker_.c_str(), hedge_ticker_.c_str(), mids_.back(), sample_head_, sample_tail_); + } if (++ sample_tail_ - sample_head_ > train_samples_) { UpdateParams("[tail-head hit]"); } @@ -329,9 +342,11 @@ void Strategy::ModerateOrders(const std::string & ticker) { if ((o->side == OrderSide::Buy && o->price - reasonable_price >= min_price_move_ / 2) // buy, order price > reasonable buy price, loss || (o->side == OrderSide::Sell && o->price - reasonable_price <= min_price_move_ / 2)) { // sell, order price < reasonable sell CancelOrder(o); + o->Show(stdout); } } else if (o->ticker == hedge_ticker_) { ModOrder(o); + o->Show(stdout); } else { continue; } diff --git a/src/coinarb/strategy.h b/src/coinarb/strategy.h index 70782a6..f742552 100644 --- a/src/coinarb/strategy.h +++ b/src/coinarb/strategy.h @@ -29,7 +29,7 @@ class Strategy : public BaseStrategy { public: - explicit Strategy(const libconfig::Setting & param_setting, std::unordered_map >*ticker_strat_map, ZmqSender* uisender, ZmqSender* ordersender, TimeController* tc, ContractWorker* cw, HistoryWorker* hw, const std::string & date, StrategyMode::Enum mode = StrategyMode::Real, std::ofstream* exchange_file = nullptr); + explicit Strategy(const libconfig::Setting & param_setting, std::unordered_map >*ticker_strat_map, ZmqSender* uisender, ZmqSender* ordersender, TimeController* tc, ContractWorker* cw, const std::string & date, StrategyMode::Enum mode = StrategyMode::Real, std::ofstream* exchange_file = nullptr); ~Strategy(); void Start() override; diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..ab0838d --- /dev/null +++ b/test.cpp @@ -0,0 +1,36 @@ +#include "util/dater.h" +#include +#include +using namespace std; + +std::string TransCoin(std::string ticker) { + std::string date; + if (ticker.find("this_week") != ticker.npos) { + date = Dater::get_weekday_string(5); + date.erase(std::remove(date.begin(), date.end(), '-'), date.end()); + cout << date << endl; + date = date.substr(2, 6); + cout << date << endl; + return ticker.replace(ticker.find("this_week"), sizeof("this_week"), date); + } else if (ticker.find("next_week") != ticker.npos) { + date = Dater::get_next_weekday_string(5); + date.erase(std::remove(date.begin(), date.end(), '-'), date.end()); + date = date.substr(date.find("20")); + return ticker.replace(ticker.find("next_week"), sizeof("next_week"), date); + } else if (ticker.find("this_quarter") != ticker.npos) { + date = Dater::get_quarter_lastday_string(5); + date.erase(std::remove(date.begin(), date.end(), '-'), date.end()); + date = date.substr(date.find("20")); + return ticker.replace(ticker.find("this_quarter"), sizeof("this_quarter"), date); + } else if (ticker.find("next_quarter") != ticker.npos) { + date = Dater::get_next_quarter_lastday_string(5); + date.erase(std::remove(date.begin(), date.end(), '-'), date.end()); + date = date.substr(date.find("20")); + return ticker.replace(ticker.find("next_quarter"), sizeof("next_quarter"), date); + } + return ticker; +} + +int main() { + cout << TransCoin("'OKEX'/ETH-USDT-this_week"); +}