Skip to content

Commit

Permalink
upload
Browse files Browse the repository at this point in the history
  • Loading branch information
nickhuangxinyu1 committed May 27, 2020
1 parent 5e99476 commit ee92298
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 29 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ simdata:
backtest:
$(WAF) configure backtest $(PARAMS)

backtest2:
$(WAF) configure backtest2 $(PARAMS)

backtestpr:
$(WAF) configure backtestpr $(PARAMS)

Expand Down
18 changes: 8 additions & 10 deletions config/backtest/backtest.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
fixed_path="/home/nick/future";
backtest_outputdir = "backtest_ni10";
backtest_outputdir = "backtest_high";
strategy = (
/*
{
unique_name = "IC";
ticker = "IC";
Expand All @@ -18,8 +17,7 @@ strategy = (
stop_loss_margin = 10.0;
max_loss_times = 2;
no_close_today = true;
}*/
/*,
},
{
unique_name = "IH";
split_num = 6;
Expand Down Expand Up @@ -53,7 +51,7 @@ strategy = (
stop_loss_margin = 10.0;
max_loss_times = 2;
no_close_today = true;
},*/
},

{
unique_name = "cu";
Expand Down Expand Up @@ -90,7 +88,7 @@ strategy = (
max_holding_sec = 3600000;
stop_loss_margin = 300.0;
max_loss_times = 2;
}/*,
},

{
unique_name = "sn";
Expand Down Expand Up @@ -124,14 +122,14 @@ strategy = (
max_holding_sec = 3600000;
stop_loss_margin = 3.0;
max_loss_times = 2;
}*/
}
);

// start_date = "today";
// start_date = "yesterday";
test_mode = "test";
start_date = "2019-03-01";
period = 10;
test_mode = "nexttest";
start_date = "2019-01-01";
period = 1000;

order_file = "order_backtest.dat";
exchange_file = "exchange_backtest.dat";
Expand Down
2 changes: 1 addition & 1 deletion lib-hft
19 changes: 19 additions & 0 deletions rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ class pairtrading_class(BuildContext):
cmd = "pairtrading"
class backtest_class(BuildContext):
cmd = "backtest"
class backtest2_class(BuildContext):
cmd = "backtest2"
class backtestpr_class(BuildContext):
cmd = "backtestpr"
class order_matcher_class(BuildContext):
Expand Down Expand Up @@ -104,6 +106,9 @@ def build(bld):
if bld.cmd == "backtest":
run_backtest(bld)
return
if bld.cmd == "backtest2":
run_backtest2(bld)
return
if bld.cmd == "backtestpr":
run_backtestpr(bld)
return
Expand Down Expand Up @@ -262,6 +267,19 @@ def run_backtest(bld):
use = 'zmq nick pthread config++ python2.7 z'
)

def run_backtest2(bld):
bld.read_shlib('nick', paths=['external/common/lib'])
bld.program(
target = 'bin/backtest2',
source = ['src/backtest2/main.cpp',
'src/backtest2/strategy.cpp'
],
includes = [
'external/zeromq/include'
],
use = 'zmq nick pthread config++ python2.7 z'
)

def run_backtestpr(bld):
bld.read_shlib('nick', paths=['external/common/lib'])
bld.program(
Expand Down Expand Up @@ -315,6 +333,7 @@ def run_all(bld):
run_simplearb2(bld)
run_pairtrading(bld)
run_backtest(bld)
run_backtest2(bld)
run_backtestpr(bld)
run_order_matcher(bld)
run_demostrat(bld)
Expand Down
32 changes: 32 additions & 0 deletions src/backtest2/backtest.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
QMAKE_CXXFLAGS += -std=c++11


HEADERS += \
strategy.h \
order_handler.h \

SOURCES += \
main.cpp \
strategy.cpp \
order_handler.cpp \

INCLUDEPATH += $$PWD/../../external/common/include
INCLUDEPATH += $$PWD/../../external/ctp/include
INCLUDEPATH += $$PWD/../../external/zmq/include
INCLUDEPATH += $$PWD/../../external/libconfig/include
INCLUDEPATH += /root/anaconda2/include/python2.7
INCLUDEPATH += $$PWD/..


LIBS += -L$$PWD/lib64 -lpthread
LIBS += -L$$PWD/../../external/common/lib -lpython2.7
LIBS += -L$$PWD/../../external/zmq/lib -lzmq

LIBS += -L$$PWD/../../external/common/lib -lcommontools
LIBS += -L$$PWD/../../external/libconfig/lib -lconfig++
LIBS += -L$$PWD/../../external/ctp/lib -lthosttraderapi

132 changes: 132 additions & 0 deletions src/backtest2/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include <libconfig.h++>
#include <unordered_map>
#include <map>
#include <utility>
#include <string>
#include <vector>

#include "core/backtester.h"
#include "util/ThreadPool.h"
#include "util/time_controller.h"
#include "util/zmq_sender.hpp"
#include "util/zmq_recver.hpp"
#include "util/dater.h"
#include "util/history_worker.h"
#include "util/contract_worker.h"
#include "util/common_tools.h"
#include "struct/market_snapshot.h"
#include "./strategy.h"

// std::unique_ptr<Sender<MarketSnapshot> > ui_sender(new ZmqSender<MarketSnapshot>("*:33333", "bind", "tcp", "mid.dat"));
// std::unique_ptr<Sender<Order> > order_sender(new ZmqSender<Order>("order_sender", "connect", "ipc", "order.dat"));
// std::unique_ptr<Sender<Order> > order_sender(new ZmqSender<Order>("order_sender", 100000, "order.dat"));

struct BTConfig {
std::string fixed_path;
std::string backtest_outputdir;
std::string start_date;
int period;
std::string test_mode;
// std::vector<const libconfig::Setting> strats;
ContractWorker* strat_cw;
ContractWorker* cw;
TimeController* tc;
inline std::tuple<ZmqSender<MarketSnapshot> *, ZmqSender<Order> *, std::ofstream*> GenSender(const std::string& date) {
std::string ui_address = "backtest_ui_" + date;
std::string order_address = "order_sender_" + date;
std::string ui_file = backtest_outputdir + "/mid_" + date + ".dat";
std::string order_file = backtest_outputdir + "/order_" + date + ".dat";
return std::make_tuple(new ZmqSender<MarketSnapshot>(ui_address, "bind", "ipc", ui_file), new ZmqSender<Order>(order_address, "connect", "ipc", order_file), new std::ofstream(backtest_outputdir + "/exchange_" + date + ".dat", ios::out | ios::binary));
}
inline HistoryWorker* GenHw(const std::string & date) {
return new HistoryWorker(Dater::FindOneValid(date, -20, fixed_path));
}
} bt_config;

void LoadConfig() {
std::string default_path = GetDefaultPath();
libconfig::Config param_cfg;
std::string config_path = default_path + "/hft/config/backtest/backtest.config";
std::string contract_config_path = default_path + "/hft/config/contract/bk_contract.config";
param_cfg.readFile(config_path.c_str());
try {
std::string fixed_path = param_cfg.lookup("fixed_path");
std::string start_date = param_cfg.lookup("start_date");
std::string backtest_outputdir = param_cfg.lookup("backtest_outputdir");
std::string test_mode = param_cfg.lookup("test_mode");
EnsureDir(backtest_outputdir);
Dater dt;
if (start_date == "today") {
start_date = dt.GetDate();
}
if (start_date == "yesterday") {
start_date = dt.GetDate("", -1);
}
int period = param_cfg.lookup("period");
bt_config.backtest_outputdir = backtest_outputdir;
bt_config.fixed_path = fixed_path;
bt_config.start_date = start_date;
bt_config.period = period;
bt_config.test_mode = test_mode;
} catch(const libconfig::SettingNotFoundException &nfex) {
printf("Setting '%s' is missing", nfex.getPath());
exit(1);
} catch(const libconfig::SettingTypeException &tex) {
printf("Setting '%s' has the wrong type", tex.getPath());
exit(1);
} catch (const std::exception& ex) {
printf("EXCEPTION: %s\n", ex.what());
exit(1);
}

std::string time_config_path = default_path + "/hft/config/prod/time.config";
bt_config.tc = new TimeController(time_config_path);
bt_config.cw = new ContractWorker(contract_config_path);
bt_config.strat_cw = new ContractWorker(config_path, "strategy");
}

std::map<std::string, std::string> GetBacktestFile() {
auto dt = Dater();
return dt.GetValidMap(bt_config.start_date, bt_config.period, bt_config.fixed_path);
}

std::unordered_map<std::string, std::vector<BaseStrategy*> > GetStratMap(std::string date) {
std::unordered_map<std::string, std::vector<BaseStrategy*> > ticker_strat_map;
ZmqSender<MarketSnapshot> * data_sender;
ZmqSender<Order> * order_sender;
std::ofstream* f;
StrategyMode::Enum mode;
if (bt_config.test_mode == "test") {
mode = StrategyMode::PlainTest;
} else if (bt_config.test_mode == "nexttest") {
mode = StrategyMode::NextTest;
} else {
throw std::invalid_argument(bt_config.test_mode.c_str());
}
std::tie(data_sender, order_sender, f) = bt_config.GenSender(date);
for (auto ticker : bt_config.strat_cw->GetTicker()) {
const libconfig::Setting & p = bt_config.strat_cw->Lookup(ticker);
auto s = new Strategy(p, &ticker_strat_map, data_sender, order_sender, bt_config.tc, bt_config.cw, bt_config.GenHw(date), date, mode, f);
s->Print();
}
return ticker_strat_map;
}

void RunBacktest(const std::string& date, const std::string& f) {
TimeController tc;
tc.StartTimer();
auto tsm = GetStratMap(date);
Backtester bt(tsm);
bt.LoadData(f);
tc.EndTimer("Run@" + date);
}

int main() {
LoadConfig();
auto file_v = GetBacktestFile();
PrintMap(file_v);
ThreadPool pool(6);
for (auto i: file_v) {
pool.enqueue(RunBacktest, i.first, i.second);
}
}
1 change: 1 addition & 0 deletions src/backtest2/strategy.cpp
101 changes: 101 additions & 0 deletions src/backtest2/strategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#ifndef SRC_BACKTEST2_STRATEGY_H_
#define SRC_BACKTEST2_STRATEGY_H_

#include <libconfig.h++>
#include <unordered_map>

#include <cmath>
#include <vector>
#include <string>
#include <iostream>
#include <deque>
#include <memory>

#include "struct/market_snapshot.h"
#include "struct/strategy_status.h"
#include "struct/strategy_mode.h"
#include "struct/order.h"
#include "struct/command.h"
#include "struct/exchange_info.h"
#include "struct/order_status.h"
#include "util/time_controller.h"
#include "util/zmq_sender.hpp"
#include "util/dater.h"
#include "util/history_worker.h"
#include "util/contract_worker.h"
#include "util/common_tools.h"
#include "core/base_strategy.h"

class Strategy : public BaseStrategy {
public:
explicit Strategy(const libconfig::Setting & param_setting, std::unordered_map<std::string, std::vector<BaseStrategy*> >*ticker_strat_map, ZmqSender<MarketSnapshot>* uisender, ZmqSender<Order>* ordersender, TimeController* tc, ContractWorker* cw, HistoryWorker* hw, const std::string & date, StrategyMode::Enum mode = StrategyMode::Real, std::ofstream* exchange_file = nullptr);
~Strategy();

void Start() override;
void Stop() override;

private:
bool FillStratConfig(const libconfig::Setting& param_setting);
void RunningSetup(std::unordered_map<std::string, std::vector<BaseStrategy*> >*ticker_strat_map, ZmqSender<MarketSnapshot>* uisender, ZmqSender<Order>* ordersender);
void DoOperationAfterUpdateData(const MarketSnapshot& shot) override;
void DoOperationAfterFilled(Order* o, const ExchangeInfo& info) override;
void DoOperationAfterCancelled(Order* o) override;
void ModerateOrders(const std::string & contract) override;

bool Ready() override;
void Resume() override;
void Run() override;
void Flatting() override;

double OrderPrice(const std::string & contract, OrderSide::Enum side, bool control_price) override;

bool OpenLogic();
void CloseLogic();

void Open(OrderSide::Enum side);
bool Close(OrderSide::Enum side);

void ForceFlat() override;

bool Spread_Good();

bool IsAlign();

// bool NewHigh(OrderSide::Enum side);
void UpdateParams(const std::string& tag = "");

// strategy core param
std::string date_;
std::string main_ticker_;
std::string hedge_ticker_;
int max_close_try_;

// realtime update param
double current_spread_;
int close_round_;
int sample_head_;
int sample_tail_;
double target_hedge_price_;
std::vector<double> mids_;

// read from config
int max_pos_;
double min_price_move_;
int cancel_limit_;
double min_profit_;
int train_samples_;
double min_range_;
double range_width_;
double spread_threshold_;
bool no_close_today_;
int max_round_;

// strategy parameter
double up_diff_;
double down_diff_;
double mean_;

std::ofstream* exchange_file_;
};

#endif // SRC_BACKTEST2_STRATEGY_H_
Loading

0 comments on commit ee92298

Please sign in to comment.