教程:ccc_executor
在本教程中,让我们创建一个简单的应用程序来下订单并处理订单更新回调。
实现一个简单
的策略 SDK 使用基类 OrderSender 来保存订单更新回调函数。我们首先继承这个类并实现回调:
class MyStrategy : public OrderSender
{
public:
using OrderSender::OrderSender;
// implements OrderSender
void onOrderCreated(LOrder *order) override
{
cout << "order created. local id = " << order->orderId << endl;
};
void onOrderAcked(LOrder *order) override
{
cout << "order ack. local id = " << order->orderId << ", id = " << order->remoteOrderId << endl;
};
void onOrderRejected(LOrder *order) override
{
cout << "order rejected. local id = " << order->orderId << endl;
};
void onOrderCancelCreated(LOrder *order) override
{
cout << "order cancel created. id = " << order->remoteOrderId << endl;
};
void onOrderCancelAcked(LOrder *order) override
{
cout << "order cancel ack. id = " << order->remoteOrderId << endl;
};
void onOrderCancelRejected(LOrder *order) override
{
cout << "order cancel rejected. id = " << order->remoteOrderId << endl;
};
void onOrderExec(TradeDirs side, double px, double qty, Liquidity liq, LOrder *order) override
{
cout << "order exec. id = " << order->remoteOrderId << (side == BUY ? " buy" : "sell")
<< "order px: " << px << " size: " << qty << endl;
};
void onOrderCanceled(LOrder *order) override
{
cout << "order canceled. id = " << order->remoteOrderId << endl;
};
void onOrderClosed(LOrder *order) override
{
cout << "order closed. id = " << order->remoteOrderId << endl;
};
};
现在让我们编写一些代码来加载配置文件和设置记录器。
int main(int argc, char **argv)
{
if (argc <= 1)
{
cout << "Usage: ccc_executor cfg_path" << endl;
return 0;
}
// load configuration
std::time_t t = std::time(0);
std::tm *now = std::localtime(&t);
int date = (now->tm_year + 1900) * 10000 + (now->tm_mon + 1) * 100 + now->tm_mday;
json cfg = loadConfig(argv[1], date);
json &instCfg = cfg["instance"];
instCfg["tradeDate"] = date;
instCfg["isLive"] = true;
instCfg["listenAllSymbol"] = true;
// setup logger
string instName = getJsonValue(instCfg, "name", string("instname"));
string logPath = getJsonValue(instCfg, "log_path", string("."));
date = instCfg["tradeDate"];
logPath += "/" + to_string(date);
mkdirs(logPath);
logPath += "/inst_" + instName + ".log";
int logLevel = getJsonValue(instCfg, "log_level", qts::log4z::LOG_LEVEL_DEBUG);
QTS_LOG_START(logLevel, logPath);
ConfigManager::instance()->setJsonCfg(cfg);
然后我们得到 TraderApiManager 实例和 SymbolManager 实例。这些是单例。您通过 TraderApiManager 下订单,并使用 SymbolManager 来管理交易品种。我们在这里创建一个交易品种,以便我们稍后进行交易。
auto tradeApiMgr = TradeApiManager::instance();
auto symMgr = SymbolManager::instance();
string symbol = "BTCUSDT";
string exch = "BINANCEUS";
auto sh = symMgr->getSymbolHandler(symbol, exch);
auto si = &sh->symbolInfo();
添加符号后,是时候启动 Apfiny Algo 框架的主循环了:
CCTradeEngine client(cfg);
client.initialize();
client.async_run();
现在我们可以创建一个 MyStrategy 类的实例,并实现一些虚拟交易逻辑。在这个应用程序中,我们每 60 秒发送一次 IOC 命令。
要发送订单,我们首先创建一个 LOrder 对象,然后使用 tradeApi 发送。我们需要设置 sender 属性以接收订单更新回调。
MyStrategy *strat = new MyStrategy();
TradeApi *tradeApi = tradeApiMgr->tradeApi(); // Must be called after initialize() function
sleep(10);
while (true)
{
cout << "send a random IOC order" << endl;
LOrder *ord = new LOrder();
ord->sender = strat;
ord->account = 101;
ord->use_margin = true;
ord->margin_source = "cross";
ord->side = BUY;
ord->si = si;
ord->px = 39300.0;
ord->qty = 0.001;
ord->remainingQty = ord->qty;
ord->signal = 0.0;
ord->spread = si->spread();
ord->tif = Tif::TIF_IOC;
ord->intention = OrderIntention::OI_AGGRESSIVE;
tradeApi->sendOrder(ord);
sleep(60);
}
}
现在我们有了一个完整的交易应用程序,是时候构建、配置和运行了。
构建应用程序
该版本包含完整的源代码和用于构建它的 premake 文件。按照以下步骤构建:
cd algo_sdk/examples/ccc_executor/build_scripts
premake4 gmake
make -j 10 config=release
创建配置文件
我们使用 JSON 文件来配置交易应用程序。该文件包含有关 api 密钥、日志路径和策略组件的信息。请更新以下示例配置中的 API 密钥信息:
{
"instance": {
"license_id":"",
"license_key":"",
"log_path": "./ccc_executor_test_01",
"name": "ccc_executor_test_01"
},
"servers":{
"redis_server":"127.0.0.1"
},
"exchanges":[
{"exchange":"BINANCE_SWAP","trade_type":"Direct","market_data_type":"None"}
],
"apikeys": {
"BINANCE_SWAP": {
"key": "enter your api key",
"secret": "enter your api secert",
"pass": "enter your api passphrase"
}
},
"fees": {
"BINANCE_SWAP": {
"make": 0.0,
"take": 0.0002
}
},
"symbol_info": {
},
"symbols": [
],
"samplers": [
],
"pricing_models": [
],
"variables": [
],
"models": [
],
"strategies": [
]
}
运行应用
Apfiny Algo 依赖于几个共享库,所以你需要先设置一些环境变量。
设置环境变量 ALGO_HOME 使用algo_sdk 的路径。例如 /data/cc/algo_sdk:
export ALGO_HOME=YOUR_ALGO_SDK_PATH
设置其他环境变量:
export TZ=UTC
export LD_LIBRARY_PATH=${ALGO_HOME}/bin:$LD_LIBRARY_PATH
export PATH=${ALGO_HOME}/ bin:$PATH
你现在可以启动应用程序了。它需要一个命令行参数,即 json 配置文件的路径。
ccc_executor ${ALGO_HOME}/examples/ccc_executor/cfg/executor_cfg.json