当前位置:   article > 正文

量化交易之HFT篇 - 高频做市模型源码(.cpp文件)_wtsvariant

wtsvariant
  1. """
  2. 事先声明, 模型源码仅作参考和交流使用, 不能直接用于实盘
  3. """
'
运行
  1. #include "WtHftStraDemo.h"
  2. //#include "../Includes/IHftStraCtx.h"
  3. #include "../WtCore/HftStraBaseCtx.h"
  4. #include "../Includes/WTSVariant.hpp"
  5. #include "../Includes/WTSDataDef.hpp"
  6. #include "../Includes/WTSContractInfo.hpp"
  7. #include "../Share/TimeUtils.hpp"
  8. #include "../Share/decimal.h"
  9. extern const char* FACT_NAME;
  10. /// alpha params
  11. #define OPEN_CLOSE_POSITION_OFFSET_TICKS 2
  12. #define UNIT 1
  13. #define MIDPRICE_OFFSET_TICKS 1
  14. #define ALPHA_TICK_COUNTS 600
  15. WtHftStraDemo::WtHftStraDemo(const char* id): HftStrategy(id)
  16. , _last_tick(nullptr)
  17. , _last_scan_time(0)
  18. , _channel_ready(false)
  19. , _re_connect_ready(false)
  20. , _last_mid_price(-1)
  21. , _current_session_status(DEFAULT_STATUS)
  22. , _code_buy_lock(false)
  23. , _code_sell_lock(false)
  24. , _code_short_lock(false)
  25. , _code_cover_lock(false)
  26. , _re_marketMaking(true)
  27. , _ticks_uptr(make_unique<Ticks>())
  28. {
  29. this->_commoditiesDocument = this->__tqz_loadJsonDocument("commodities.json");
  30. this->_sessionsDocument = this->__tqz_loadJsonDocument("sessions.json");
  31. }
  32. WtHftStraDemo::~WtHftStraDemo() {
  33. if (_last_tick)
  34. _last_tick->release();
  35. this->_ticks_uptr.reset();
  36. this->__tqz_cancelAllOrders();
  37. }
  38. const char* WtHftStraDemo::getName() {
  39. return "HftDemoStrategy";
  40. }
  41. const char* WtHftStraDemo::getFactName() {
  42. return FACT_NAME;
  43. }
  44. bool WtHftStraDemo::init(WTSVariant* cfg) {
  45. this->_code = cfg->getCString("code");
  46. this->_marketMaking_scan_interval = cfg->getUInt32("market_making_scan_interval");
  47. this->_long_order_offset = cfg->getUInt32("long_order_offset");
  48. this->_short_order_offset = cfg->getUInt32("short_order_offset");
  49. this->_offset_open_minutes = cfg->getUInt32("offset_open_minutes");
  50. this->_offset_close_minutes = cfg->getUInt32("offset_close_minutes");
  51. this->_record_hft_log = cfg->getBoolean("record_hft_log");
  52. this->_cancel_limit_counts = cfg->getUInt32("cancel_limit_counts");
  53. return true;
  54. }
  55. void WtHftStraDemo::on_init(HftStraBaseCtx* ctx) {
  56. ctx->stra_sub_ticks(_code.c_str());
  57. this->_ctx = ctx;
  58. }
  59. void WtHftStraDemo::on_tick(HftStraBaseCtx* ctx, const char* code, WTSTickData* newTick) {
  60. if (0 != this->_code.compare(code))
  61. return;
  62. if (!this->__isTradingTime(code))
  63. return;
  64. if (!this->_channel_ready)
  65. return;
  66. if (!this->_re_connect_ready) {
  67. if (!this->__isNewScanInterval(this->_marketMaking_scan_interval))
  68. return;
  69. /// query re_connect_ready & do reconnect.
  70. this->_re_connect_ready = this->__tqz_queryReconnectResult();
  71. if (!this->_re_connect_ready)
  72. this->tqz_doReconnect();
  73. return;
  74. }
  75. if (!this->updateTicks(*newTick))
  76. return;
  77. if (this->__isClosePositionsTime(code)) {
  78. if (this->_current_session_status != CLOSE_POSTIONS_STATUS)
  79. this->__initSessionStatus(CLOSE_POSTIONS_STATUS);
  80. if (!this->__isNewScanInterval(this->_marketMaking_scan_interval))
  81. return;
  82. if (this->__marketMakingIsLock(true))
  83. return;
  84. if (this->__closeCodeIsLock(true))
  85. return;
  86. this->tqz_closePositions(this->_code, OPEN_CLOSE_POSITION_OFFSET_TICKS);
  87. } else {
  88. if (this->_current_session_status != MARKET_MAKING_STATUS)
  89. this->__initSessionStatus(MARKET_MAKING_STATUS);
  90. if (this->__closeCodeIsLock(true))
  91. return;
  92. /// scan only new time slice.
  93. if (!this->__isNewScanInterval(this->_marketMaking_scan_interval))
  94. return;
  95. if (!this->__midPriceIsChange(MIDPRICE_OFFSET_TICKS))
  96. return;
  97. /// do market making with time slice.
  98. if (this->_re_marketMaking) {
  99. this->tqz_marketMaking(this->getLongOffsetValue(), this->getShortOffsetValue());
  100. this->_re_marketMaking = !this->_re_marketMaking;
  101. } else {
  102. this->__marketMakingIsLock(true);
  103. }
  104. }
  105. }
  106. int32_t WtHftStraDemo::totalAlphasValue(TicksUPtr& ticksUPtr) {
  107. int32_t maAlphaValue = MaAlpha::alphaValue(ticksUPtr, 20);
  108. /*int32_t macdAlphaValue = MacdAlpha::alphaValue(ticksUPtr, 9, 12, 26);
  109. int32_t diffAlphaValue = DiffAlpha::alphaValue(ticksUPtr, 20);
  110. int32_t lastTradedQuantityAlphaValue = LastTradedQuantityAlpha::alphaValue(ticksUPtr, 20);
  111. int32_t bookAlphaValue = BookAlpha::alphaValue(ticksUPtr, 20);*/
  112. /*
  113. /// output all values to terminal for test...
  114. std::cout << "-------------------------------------------" << std::endl;
  115. //std::cout << "maAlphaValue: " << maAlphaValue << std::endl;
  116. std::cout << "macdAlphaValue: " << macdAlphaValue << std::endl;
  117. //std::cout << "diffAlphaValue: " << diffAlphaValue << std::endl;
  118. std::cout << "lastTradedQuantityAlphaValue: " << lastTradedQuantityAlphaValue << std::endl;
  119. //std::cout << "bookAlphaValue: " << bookAlphaValue << std::endl;
  120. std::cout << "-------------------------------------------" << std::endl;
  121. */
  122. //return (maAlphaValue + macdAlphaValue + diffAlphaValue + lastTradedQuantityAlphaValue + bookAlphaValue);
  123. return maAlphaValue;
  124. }
  125. uint32_t WtHftStraDemo::getLongOffsetValue() {
  126. int32_t totalAlphasValue = this->totalAlphasValue(this->_ticks_uptr);
  127. return (totalAlphasValue < 0) ? this->_long_order_offset : (this->_long_order_offset + totalAlphasValue);
  128. }
  129. uint32_t WtHftStraDemo::getShortOffsetValue() {
  130. int32_t totalAlphasValue = this->totalAlphasValue(this->_ticks_uptr);
  131. return (totalAlphasValue < 0) ? this->_short_order_offset : (this->_short_order_offset + totalAlphasValue);
  132. }
  133. bool WtHftStraDemo::updateTicks(WTSTickData tickData) {
  134. if (this->_ticks_uptr->size() == ALPHA_TICK_COUNTS)
  135. this->_ticks_uptr->erase(this->_ticks_uptr->begin());
  136. this->_ticks_uptr->push_back(tickData);
  137. return (this->_ticks_uptr->size() == ALPHA_TICK_COUNTS);
  138. }
  139. void WtHftStraDemo::on_trade(HftStraBaseCtx* ctx, uint32_t localid, const char* stdCode, bool isBuy, double qty, double price, const char* userTag) {
  140. if (this->__isBelongToHft(localid)) { // localid is code
  141. this->__tqz_receiveCodeOnlyCloseCode(localid, this->_code, qty);
  142. } else {
  143. /// this->_ctx->stra_log_text("[WtHftStraDemo::on_trade], localid(%d) is not belong to hft strategy(%s)", localid, stdCode);
  144. }
  145. this->__tqz_writeStrategyTradeLog(localid, price, qty);
  146. }
  147. void WtHftStraDemo::on_order(HftStraBaseCtx* ctx, uint32_t localid, const char* stdCode, bool isBuy, double totalQty, double leftQty, double price, bool isCanceled, const char* userTag) { // 下单成功后调用
  148. if (0 != this->_code.compare(stdCode))
  149. return;
  150. if (!isCanceled) // order is not cancel.
  151. return;
  152. TQZOrderType orderType = this->__tqz_getOrderType(localid); // get order type first.
  153. if (this->__isBelongToHft(localid)) { // localid is inside.
  154. switch (orderType) {
  155. case BUY_TYPE: {
  156. this->__unlockBuy();
  157. this->tqz_marketMaking(this->getLongOffsetValue(), this->getShortOffsetValue());
  158. break;
  159. }
  160. case SELL_TYPE: {
  161. std::string orderComment(this->_re_connect_ready ? "code_sellOrder_reSend" : "code_sellOrder_reConnect_reSend");
  162. if (this->_code_sell_lock) // re send code sell order.
  163. this->tqz_sell(this->_code, UNIT, OPEN_CLOSE_POSITION_OFFSET_TICKS, orderComment.c_str());
  164. break;
  165. }
  166. case SHORT_TYPE: {
  167. this->__unlockShort();
  168. this->tqz_marketMaking(this->getLongOffsetValue(), this->getShortOffsetValue());
  169. break;
  170. }
  171. case COVER_TYPE: {
  172. std::string orderComment(this->_re_connect_ready ? "code_coverOrder_reSend" : "code_coverOrder_reConnect_reSend");
  173. if (this->_code_cover_lock) // re send code cover order.
  174. this->tqz_cover(this->_code, UNIT, OPEN_CLOSE_POSITION_OFFSET_TICKS, orderComment.c_str());
  175. break;
  176. }
  177. default:
  178. break;
  179. }
  180. } else {
  181. this->_ctx->stra_log_text("[WtHftStraDemo::on_order] localid is not code, stdCode: %s, localid: %d", stdCode, localid);
  182. }
  183. }
  184. void WtHftStraDemo::on_channel_ready(HftStraBaseCtx* ctx) {
  185. std::cout << "HFT_strategy code: " << this->_code << "\n\n" << std::endl;
  186. this->_tradeChange_log_filename = this->__tqz_getLogFileName(TRADE_CHANGE_TYPE);
  187. this->_channel_ready = true;
  188. this->__initSessionStatus(RE_CONNECT_STATUS);
  189. }
  190. void WtHftStraDemo::on_entrust(uint32_t localid, bool bSuccess, const char* message, const char* userTag) {
  191. this->_ctx->stra_log_text("WtHftStraDemo::on_entrust bSuccess: %d, message: %s\n\n", bSuccess, message);
  192. TQZOrderType orderType = this->__tqz_getOrderType(localid);
  193. switch (orderType) {
  194. case BUY_TYPE:
  195. this->__unlockBuy();
  196. break;
  197. case SELL_TYPE:
  198. this->__unlockSell();
  199. break;
  200. case SHORT_TYPE:
  201. this->__unlockShort();
  202. break;
  203. case COVER_TYPE:
  204. this->__unlockCover();
  205. break;
  206. default:
  207. break;
  208. }
  209. }
  210. void WtHftStraDemo::on_channel_lost(HftStraBaseCtx* ctx) {
  211. this->_channel_ready = false;
  212. }
  213. void WtHftStraDemo::on_bar(HftStraBaseCtx* ctx, const char* code, const char* period, uint32_t times, WTSBarStruct* newBar) {
  214. }
  215. void WtHftStraDemo::on_position(HftStraBaseCtx* ctx, const char* stdCode, bool isLong, double prevol, double preavail, double newvol, double newavail) {
  216. }
  217. void WtHftStraDemo::tqz_buy(const std::string code, const double lots, const int offsetTicks, const std::string orderComment) {
  218. if (!this->__isEntrustable(code))
  219. return;
  220. this->__lockBuy();
  221. // send buy order & update local var.
  222. double buyOrderPrice = this->__tqz_getLongPrice(code, offsetTicks);
  223. uint32_t buyOrderLocalid = this->_ctx->stra_enter_long(code.c_str(), buyOrderPrice, lots, orderComment.c_str());
  224. std::string currentMarketTimeString = this->__tqz_getCurrentMarketTime();
  225. std::string sendOrderTimeString = this->__tqz_getCurrentTime();
  226. this->_code_buy_order = buyOrderLocalid;
  227. this->_code_buy_orders.insert(buyOrderLocalid);
  228. if (this->_record_hft_log) // recode log or not.
  229. this->_log_message_map[buyOrderLocalid] = this->__tqz_getNewLogMessage(
  230. code,
  231. buyOrderLocalid,
  232. this->_ctx->stra_get_price(code.c_str()),
  233. buyOrderPrice,
  234. "buy_order",
  235. currentMarketTimeString,
  236. sendOrderTimeString,
  237. orderComment
  238. );
  239. }
  240. void WtHftStraDemo::tqz_sell(const std::string code, const double lots, const int offsetTicks, const std::string orderComment) {
  241. if (!this->__isEntrustable(code))
  242. return;
  243. this->__lockSell();
  244. // send sell order & update local var.
  245. double sellOrderPrice = this->__tqz_getShortPrice(code, offsetTicks);
  246. uint32_t sellOrderLocalid = this->_ctx->stra_exit_long(code.c_str(), sellOrderPrice, lots, orderComment.c_str(), true);
  247. std::string currentMarketTimeString = this->__tqz_getCurrentMarketTime();
  248. std::string sendOrderTimeString = this->__tqz_getCurrentTime();
  249. this->_code_sell_order = sellOrderLocalid;
  250. this->_code_sell_orders.insert(sellOrderLocalid);
  251. if (this->_record_hft_log) // recode log or not.
  252. this->_log_message_map[sellOrderLocalid] = this->__tqz_getNewLogMessage(
  253. code,
  254. sellOrderLocalid,
  255. this->_ctx->stra_get_price(code.c_str()),
  256. sellOrderPrice,
  257. "sell_order",
  258. currentMarketTimeString,
  259. sendOrderTimeString,
  260. orderComment
  261. );
  262. }
  263. void WtHftStraDemo::tqz_short(const std::string code, const double lots, const int offsetTicks, const std::string orderComment) {
  264. if (!this->__isEntrustable(code))
  265. return;
  266. this->__lockShort();
  267. double shortOrderPrice = this->__tqz_getShortPrice(code, offsetTicks);
  268. uint32_t shortOrderLocalid = this->_ctx->stra_enter_short(code.c_str(), shortOrderPrice, lots, orderComment.c_str());
  269. std::string currentMarketTimeString = this->__tqz_getCurrentMarketTime();
  270. std::string sendOrderTimeString = this->__tqz_getCurrentTime();
  271. this->_code_short_order = shortOrderLocalid;
  272. this->_code_short_orders.insert(shortOrderLocalid);
  273. if (this->_record_hft_log) // recode log or not.
  274. this->_log_message_map[shortOrderLocalid] = this->__tqz_getNewLogMessage(
  275. code,
  276. shortOrderLocalid,
  277. this->_ctx->stra_get_price(code.c_str()),
  278. shortOrderPrice,
  279. "short_order",
  280. currentMarketTimeString,
  281. sendOrderTimeString,
  282. orderComment
  283. );
  284. }
  285. void WtHftStraDemo::tqz_cover(const std::string code, const double lots, const int offsetTicks, const std::string orderComment) {
  286. if (!this->__isEntrustable(code))
  287. return;
  288. this->__lockCover();
  289. // send cover order & update local var.
  290. double coverOrderPrice = this->__tqz_getLongPrice(code, offsetTicks);
  291. uint32_t coverOrderLocalid = this->_ctx->stra_exit_short(code.c_str(), coverOrderPrice, lots, orderComment.c_str(), true);
  292. std::string currentMarketTimeString = this->__tqz_getCurrentMarketTime();
  293. std::string sendOrderTimeString = this->__tqz_getCurrentTime();
  294. this->_code_cover_order = coverOrderLocalid;
  295. this->_code_cover_orders.insert(coverOrderLocalid);
  296. if (this->_record_hft_log) // recode log or not.
  297. this->_log_message_map[coverOrderLocalid] = this->__tqz_getNewLogMessage(
  298. code,
  299. coverOrderLocalid,
  300. this->_ctx->stra_get_price(code.c_str()),
  301. coverOrderPrice,
  302. "cover_order",
  303. currentMarketTimeString,
  304. sendOrderTimeString,
  305. orderComment
  306. );
  307. }
  308. void WtHftStraDemo::tqz_marketMaking(const int codeLongOffsetTicks, const int codeShortOffsetTicks) {
  309. if (!this->__isMarketMakingAble())
  310. return;
  311. this->__lockBuy(); // lock market_making.
  312. this->__lockShort();
  313. std::string buyOrderComment("code_buyOrder_marketMaking");
  314. std::string shortOrderComment("code_shortOrder_marketMaking");
  315. double currentMidPrice = this->_last_mid_price; // make sure mid price of market making is same.
  316. double buyOrderPrice = this->__tqz_getMarketMakingLongPrice(this->_code.c_str(), currentMidPrice, codeLongOffsetTicks);
  317. double shortOrderPrice = this->__tqz_getMarketMakingShortPrice(this->_code.c_str(), currentMidPrice, codeShortOffsetTicks);
  318. uint32_t buyOrderLocalid = this->_ctx->stra_enter_long(this->_code.c_str(), buyOrderPrice, UNIT, buyOrderComment.c_str());
  319. uint32_t shortOrderLocalid = this->_ctx->stra_enter_short(this->_code.c_str(), shortOrderPrice, UNIT, shortOrderComment.c_str());
  320. std::string currentMarketTimeString = this->__tqz_getCurrentMarketTime();
  321. std::string sendOrderTimeString = this->__tqz_getCurrentTime();
  322. this->_code_buy_order = buyOrderLocalid;
  323. this->_code_buy_orders.insert(buyOrderLocalid);
  324. this->_code_short_order = shortOrderLocalid;
  325. this->_code_short_orders.insert(shortOrderLocalid);
  326. if (!this->_record_hft_log)
  327. return;
  328. double currentPrice = this->_ctx->stra_get_price(this->_code.c_str()); // current market price.
  329. this->_log_message_map[buyOrderLocalid] = this->__tqz_getNewLogMessage(this->_code, buyOrderLocalid, currentPrice, buyOrderPrice, "buy_order", currentMarketTimeString, sendOrderTimeString, buyOrderComment);
  330. this->_log_message_map[shortOrderLocalid] = this->__tqz_getNewLogMessage(this->_code, shortOrderLocalid, currentPrice, shortOrderPrice, "short_order", currentMarketTimeString, sendOrderTimeString, shortOrderComment);
  331. }
  332. void WtHftStraDemo::tqz_closePositions(const std::string code, const uint32_t closePositionsOffsetTicks) {
  333. if (this->_ctx->tqz_getLongPosition(code.c_str()) > 0) { /// close long positions.
  334. this->tqz_sell(code, UNIT, closePositionsOffsetTicks, "code_sellOrder_closePositions");
  335. } else if (this->_ctx->tqz_getShortPosition(code.c_str()) > 0) { /// close short positions.
  336. this->tqz_cover(code, UNIT, closePositionsOffsetTicks, "code_coverOrder_closePositions");
  337. }
  338. }
  339. void WtHftStraDemo::tqz_doReconnect() {
  340. if (this->__closeCodeIsLock(true))
  341. return;
  342. double currentCodeLongLots = this->_ctx->tqz_getLongPosition(this->_code.c_str());
  343. double currentCodeShortLots = this->_ctx->tqz_getShortPosition(this->_code.c_str());
  344. if (currentCodeLongLots > 0 && currentCodeLongLots >= currentCodeShortLots) { /// have long position & long lots big.
  345. this->tqz_sell(this->_code, UNIT, OPEN_CLOSE_POSITION_OFFSET_TICKS, "code_sellOrder_reConnect");
  346. } else if (currentCodeShortLots > 0 && currentCodeLongLots < currentCodeShortLots) { /// have short position & short lots big.
  347. this->tqz_cover(this->_code, UNIT, OPEN_CLOSE_POSITION_OFFSET_TICKS, "code_coverOrder_reConnect");
  348. }
  349. }
  350. bool WtHftStraDemo::__isEntrustable(std::string code) {
  351. if (this->__isBeyondUpperlimitOrLowerlimit(code, OPEN_CLOSE_POSITION_OFFSET_TICKS, OPEN_CLOSE_POSITION_OFFSET_TICKS)) /// because cancel limit is 100.
  352. return false;
  353. if (this->_ctx->tqz_getCancelCounts(code.c_str()) > (this->_cancel_limit_counts + 10)) {
  354. this->_ctx->stra_log_text("[WtHftStraDemo::__isEntrustable], out of cancel limit counts when entrust, code: %s, 如果这条log被记录了, 说明策略执行逻辑被强行干扰了", code.c_str());
  355. return false;
  356. }
  357. return true;
  358. }
  359. void WtHftStraDemo::__initSessionStatus(TQZSessionStatus sessionStatus) {
  360. this->_current_session_status = sessionStatus;
  361. switch (sessionStatus) {
  362. case CLOSE_POSTIONS_STATUS: {
  363. break;
  364. }
  365. case MARKET_MAKING_STATUS: { // position and order is empty in theory.
  366. this->__unlockAllOrders();
  367. this->__tqz_clearPreviousSessionCache();
  368. this->_re_marketMaking = true;
  369. break;
  370. }
  371. case RE_CONNECT_STATUS: {
  372. this->__tqz_writeCancelOrderCountsLog(this->_code);
  373. this->_re_connect_ready = this->__tqz_queryReconnectResult();
  374. }
  375. default:
  376. break;
  377. }
  378. }
  379. bool WtHftStraDemo::__tqz_queryReconnectResult() {
  380. double codeLongLots = this->_ctx->tqz_getLongPosition(this->_code.c_str());
  381. double codeShortLots = this->_ctx->tqz_getShortPosition(this->_code.c_str());
  382. return (codeLongLots < 0.00001 && codeShortLots < 0.00001); // hold positions is empty.
  383. }
  384. void WtHftStraDemo::__tqz_clearPreviousSessionCache() {
  385. // 缓存清理无效, 成员变量换成指针类型; (每小节初始化时清理一次)
  386. this->_code_buy_orders.erase(this->_code_buy_orders.begin(), this->_code_buy_orders.end());
  387. this->_code_sell_orders.erase(this->_code_sell_orders.begin(), this->_code_sell_orders.end());
  388. this->_code_short_orders.erase(this->_code_short_orders.begin(), this->_code_short_orders.end());
  389. this->_code_cover_orders.erase(this->_code_cover_orders.begin(), this->_code_cover_orders.end());
  390. this->_log_message_map.clear();
  391. }
  392. void WtHftStraDemo::__tqz_cancelOrder(const std::string code, const uint32_t orderId) {
  393. if (this->_ctx->tqz_getCancelCounts(code.c_str()) > (this->_cancel_limit_counts + 15)) {
  394. this->_ctx->stra_log_text("[WtHftStraDemo::__tqz_cancelOrder] out of cancel limit counts when cancel order, code: %s, orderId: %d, 如果这条log被记录了, 说明策略执行逻辑被强行干扰了", code.c_str(), orderId);
  395. return;
  396. }
  397. this->_ctx->stra_cancel(orderId);
  398. }
  399. void WtHftStraDemo::__tqz_cancelOrders(const std::string code, const IDSet orderIds) {
  400. for (auto& localid : orderIds)
  401. this->__tqz_cancelOrder(code, localid);
  402. }
  403. void WtHftStraDemo::__tqz_cancelAllOrders() {
  404. this->__tqz_cancelOrders(this->_code, this->_code_buy_orders);
  405. this->__tqz_cancelOrders(this->_code, this->_code_sell_orders);
  406. this->__tqz_cancelOrders(this->_code, this->_code_short_orders);
  407. this->__tqz_cancelOrders(this->_code, this->_code_cover_orders);
  408. }
  409. TQZOrderType WtHftStraDemo::__tqz_getOrderType(const uint32_t orderId) {
  410. TQZOrderType orderType = DEFAULT_ORDER_TYPE;
  411. if (this->_code_buy_orders.find(orderId) != std::end(this->_code_buy_orders)) {
  412. orderType = BUY_TYPE;
  413. } else if (this->_code_sell_orders.find(orderId) != std::end(this->_code_sell_orders)) {
  414. orderType = SELL_TYPE;
  415. } else if (this->_code_short_orders.find(orderId) != std::end(this->_code_short_orders)) {
  416. orderType = SHORT_TYPE;
  417. } else if (this->_code_cover_orders.find(orderId) != std::end(this->_code_cover_orders)) {
  418. orderType = COVER_TYPE;
  419. } else {
  420. orderType = NO_TYPE;
  421. }
  422. return orderType;
  423. }
  424. double WtHftStraDemo::__tqz_getAskPrice(const std::string code) {
  425. return this->_ctx->stra_get_last_tick(code.c_str())->askprice(0);
  426. }
  427. double WtHftStraDemo::__tqz_getBidPrice(const std::string code) {
  428. return this->_ctx->stra_get_last_tick(code.c_str())->bidprice(0);
  429. }
  430. double WtHftStraDemo::__tqz_getCurrentMidPrice(const std::string code) {
  431. return (this->__tqz_getAskPrice(code) + this->__tqz_getBidPrice(code)) * 0.5;
  432. }
  433. bool WtHftStraDemo::__midPriceIsChange(int offsetTicks) {
  434. double currentMidPrice = this->__tqz_getCurrentMidPrice(this->_code);
  435. double minPriceTick = this->_ctx->stra_get_comminfo(this->_code.c_str())->getPriceTick();
  436. double midPriceOffset = abs(currentMidPrice - this->_last_mid_price);
  437. bool midPriceIsChange = (midPriceOffset >= (minPriceTick * offsetTicks));
  438. if (midPriceIsChange)
  439. this->_last_mid_price = currentMidPrice;
  440. return midPriceIsChange;
  441. }
  442. double WtHftStraDemo::__tqz_getLowerlimitPrice(const std::string code) {
  443. return this->_ctx->stra_get_last_tick(code.c_str())->lowerlimit();
  444. }
  445. double WtHftStraDemo::__tqz_getUpperlimitPrice(const std::string code) {
  446. return this->_ctx->stra_get_last_tick(code.c_str())->upperlimit();
  447. }
  448. double WtHftStraDemo::__tqz_getMarketMakingLongPrice(const std::string code, const double currentMidPrice, const int offsetTicks) {
  449. double minPriceTick = this->_ctx->stra_get_comminfo(code.c_str())->getPriceTick();
  450. double marketMakerLongOrderPrice = currentMidPrice - minPriceTick * offsetTicks;
  451. int longOrderPriceTicks = static_cast<int>(floor(marketMakerLongOrderPrice / minPriceTick));
  452. return longOrderPriceTicks * minPriceTick;
  453. }
  454. double WtHftStraDemo::__tqz_getMarketMakingShortPrice(const std::string code, const double currentMidPrice, const int offsetTicks) {
  455. double minPriceTick = this->_ctx->stra_get_comminfo(code.c_str())->getPriceTick();
  456. double marketMakerShortOrderPrice = currentMidPrice + minPriceTick * offsetTicks;
  457. int shortOrderPriceTicks = static_cast<int>(ceil(marketMakerShortOrderPrice / minPriceTick));
  458. return shortOrderPriceTicks * minPriceTick;
  459. }
  460. bool WtHftStraDemo::__isBeyondUpperlimitOrLowerlimit(const string code, const int longOrderOffsetTicks, const int shortOrderOffsetTicks) {
  461. if (this->__tqz_getLongPrice(code, longOrderOffsetTicks) >= this->__tqz_getUpperlimitPrice(code))
  462. return true;
  463. if (this->__tqz_getShortPrice(code, shortOrderOffsetTicks) <= this->__tqz_getLowerlimitPrice(code))
  464. return true;
  465. return false;
  466. }
  467. double WtHftStraDemo::__tqz_getLongPrice(const std::string code, const int offsetTicks = 0) {
  468. WTSCommodityInfo* codeInfo = this->_ctx->stra_get_comminfo(code.c_str());
  469. double longPrice = this->__tqz_getAskPrice(code.c_str()) + codeInfo->getPriceTick() * offsetTicks;
  470. if (longPrice >= this->__tqz_getUpperlimitPrice(code))
  471. longPrice = this->__tqz_getUpperlimitPrice(code);
  472. if (longPrice <= this->__tqz_getLowerlimitPrice(code))
  473. longPrice = this->__tqz_getLowerlimitPrice(code);
  474. return longPrice;
  475. }
  476. double WtHftStraDemo::__tqz_getShortPrice(const std::string code, const int offsetTicks = 0) {
  477. WTSCommodityInfo* codeInfo = this->_ctx->stra_get_comminfo(code.c_str());
  478. double shortPrice = this->__tqz_getBidPrice(code) - codeInfo->getPriceTick() * offsetTicks;
  479. if (shortPrice <= this->__tqz_getLowerlimitPrice(code))
  480. shortPrice = this->__tqz_getLowerlimitPrice(code);
  481. if (shortPrice >= this->__tqz_getUpperlimitPrice(code))
  482. shortPrice = this->__tqz_getUpperlimitPrice(code);
  483. return shortPrice;
  484. }
  485. void WtHftStraDemo::__tqz_receiveCodeOnlyCloseCode(const uint32_t localid, const std::string code, const double lots) {
  486. switch (this->__tqz_getOrderType(localid)) {
  487. case BUY_TYPE: {
  488. this->__tqz_cancelOrder(code, this->_code_short_order);
  489. if (this->_ctx->tqz_getLongPosition(code.c_str()) > 0)
  490. this->tqz_sell(code, lots, OPEN_CLOSE_POSITION_OFFSET_TICKS, "code_sellOrder_onlyClose");
  491. break;
  492. } case SELL_TYPE: { // close positions time.
  493. this->__unlockBuy();
  494. this->__unlockSell();
  495. this->_re_marketMaking = true;
  496. break;
  497. } case SHORT_TYPE: {
  498. this->__tqz_cancelOrder(code, this->_code_buy_order);
  499. if (this->_ctx->tqz_getShortPosition(code.c_str()) > 0)
  500. this->tqz_cover(code, lots, OPEN_CLOSE_POSITION_OFFSET_TICKS, "code_coverOrder_onlyClose");
  501. break;
  502. } case COVER_TYPE: { // close positions time.
  503. this->__unlockShort();
  504. this->__unlockCover();
  505. this->_re_marketMaking = true;
  506. break;
  507. }
  508. }
  509. }
  510. bool WtHftStraDemo::__isBelongToHft(const uint32_t orderId) {
  511. bool isBelongToHft = false;
  512. if (this->_code_buy_orders.find(orderId) != std::end(this->_code_buy_orders)) {
  513. isBelongToHft = true;
  514. } else if (this->_code_sell_orders.find(orderId) != std::end(this->_code_sell_orders)) {
  515. isBelongToHft = true;
  516. } else if (this->_code_short_orders.find(orderId) != std::end(this->_code_short_orders)) {
  517. isBelongToHft = true;
  518. } else if (this->_code_cover_orders.find(orderId) != std::end(this->_code_cover_orders)) {
  519. isBelongToHft = true;
  520. }
  521. return isBelongToHft;
  522. }
  523. int WtHftStraDemo::__tqz_getCurrentHourMinute() {
  524. struct tm *newtime;
  525. time_t long_time;
  526. time(&long_time);
  527. newtime = localtime(&long_time);
  528. return newtime->tm_hour * 100 + newtime->tm_min;
  529. }
  530. rapidjson::Document WtHftStraDemo::__tqz_loadJsonDocument(const std::string jsonPath) {
  531. char readBuffer[65536];
  532. FILE* filePoint = fopen(jsonPath.c_str(), "r");
  533. rapidjson::FileReadStream fileStream(filePoint, readBuffer, sizeof(readBuffer));
  534. rapidjson::Document document;
  535. document.ParseStream(fileStream);
  536. fclose(filePoint);
  537. return document;
  538. }
  539. std::string WtHftStraDemo::__tqz_getSession(const std::string symbolCode) {
  540. std::vector<std::string> elements;
  541. std::stringstream stringStream(symbolCode.c_str());
  542. std::string item;
  543. int index = 0;
  544. std::string exchangeString;
  545. std::string symString;
  546. std::string symbolYearMonth;
  547. while (std::getline(stringStream, item, '.')) {
  548. elements.push_back(item);
  549. if (index == 0) {
  550. exchangeString = item;
  551. } else if (index == 1) {
  552. symString = item;
  553. } else if (index == 2) {
  554. symbolYearMonth = item;
  555. }
  556. index++;
  557. }
  558. return this->_commoditiesDocument[exchangeString.c_str()][symString.c_str()]["session"].GetString();
  559. }
  560. bool WtHftStraDemo::__isTradingTime(const std::string code) {
  561. string sessionString = this->__tqz_getSession(code);
  562. rapidjson::Value& sections = this->_sessionsDocument[sessionString.c_str()]["sections"];
  563. bool tradeable = false;
  564. if (sections.IsArray() && !sections.Empty()) {
  565. for (auto& section : sections.GetArray()) {
  566. if (!section.IsObject()) // type of section is not object.
  567. continue;
  568. if (!(section.HasMember("from") && section.HasMember("to"))) // has no from key or to key.
  569. continue;
  570. int currentHourMinute = this->__tqz_getCurrentHourMinute();
  571. if (section["from"].GetInt() <= currentHourMinute && currentHourMinute < section["to"].GetInt()) { // is trading time.
  572. tradeable = true;
  573. }
  574. if (section["from"].GetInt() > section["to"].GetInt()) { // is night trading time.
  575. if (currentHourMinute >= section["from"].GetInt() || currentHourMinute < section["to"].GetInt()) {
  576. tradeable = true;
  577. }
  578. }
  579. }
  580. } else {
  581. throw exception("result is not array type or empty array");
  582. }
  583. return tradeable;
  584. }
  585. bool WtHftStraDemo::__isClosePositionsTime(const std::string code) {
  586. string sessionString = this->__tqz_getSession(code);
  587. rapidjson::Value& sections = this->_sessionsDocument[sessionString.c_str()]["sections"];
  588. bool isClosePositionsTime = false;
  589. if (sections.IsArray() && !sections.Empty()) {
  590. for (auto& section : sections.GetArray()) {
  591. if (!section.IsObject()) // type of section is not object.
  592. continue;
  593. if (!(section.HasMember("from") && section.HasMember("to"))) // has no from key or to key.
  594. continue;
  595. uint32_t toHourMinute = this->__tqz_resetToHourMinute(section["to"].GetInt(), this->_offset_close_minutes);
  596. uint32_t currentHourMinute = this->__tqz_getCurrentHourMinute();
  597. if ((toHourMinute - this->_offset_close_minutes) <= currentHourMinute && currentHourMinute < toHourMinute) // is close positions time.
  598. isClosePositionsTime = true;
  599. }
  600. } else {
  601. throw exception("result is not array type or empty array");
  602. }
  603. return isClosePositionsTime;
  604. }
  605. int WtHftStraDemo::__tqz_resetToHourMinute(int toHourMinute, const int offsetCloseMinutes = 0){
  606. int toMinute = toHourMinute % 100;
  607. int toHour = toHourMinute / 100;
  608. int offsetMinutes = offsetCloseMinutes % 60;
  609. int offsetHours = offsetCloseMinutes / 60;
  610. int newMinute = 60 + toMinute; // reset minutes
  611. int newHour = (toHour - (offsetHours % 24 + 1) + 24) % 24; // reset hours
  612. if (toMinute - offsetMinutes < 0 || offsetHours != 0) // reset toHourMinute or not
  613. toHourMinute = newHour * 100 + newMinute;
  614. return toHourMinute;
  615. }
  616. std::string WtHftStraDemo::__tqz_getLogFileName(const TQZLogFileType logfileType) {
  617. switch (logfileType) {
  618. case TRADE_CHANGE_TYPE:
  619. return "hft_tradeChange_" + to_string(this->_ctx->tqz_getTradingDate());
  620. case CANCEL_ORDER_COUNTS_TYPE:
  621. return "hft_cancelOrderCounts_" + to_string(this->_ctx->tqz_getTradingDate());
  622. default:
  623. return "";
  624. }
  625. }
  626. std::string WtHftStraDemo::__tqz_getCurrentTime() {
  627. const boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
  628. const boost::posix_time::time_duration timeOfDay = now.time_of_day();
  629. const uint64_t hours = timeOfDay.hours();
  630. const uint64_t minutes = timeOfDay.minutes();
  631. const uint64_t seconds = timeOfDay.seconds();
  632. const uint64_t milliseconds = timeOfDay.total_milliseconds() - (hours * 3600 + minutes * 60 + seconds) * 1000;
  633. return this->__tqz_getTimeString(hours, minutes, seconds, milliseconds);
  634. }
  635. std::string WtHftStraDemo::__tqz_getCurrentMarketTime() {
  636. uint32_t time = this->_ctx->stra_get_time();
  637. uint32_t secs = this->_ctx->stra_get_secs();
  638. int hours = time / 100;
  639. int minutes = time % 100;
  640. int seconds = secs / 1000;
  641. int milliseconds = secs % 1000;
  642. return this->__tqz_getTimeString(hours, minutes, seconds, milliseconds);
  643. }
  644. std::string WtHftStraDemo::__tqz_getTimeString(const uint64_t hours, const uint64_t minutes, const uint64_t seconds, const uint64_t milliseconds) {
  645. std::string hoursString = to_string(hours);
  646. if (hours < 10)
  647. hoursString = "0" + to_string(hours);
  648. std::string minutesString = to_string(minutes);
  649. if (minutes < 10)
  650. minutesString = "0" + to_string(minutes);
  651. std::string secondsString = to_string(seconds);
  652. if (seconds < 10)
  653. secondsString = "0" + to_string(seconds);
  654. std::string millisecondsString = to_string(milliseconds);
  655. if (milliseconds < 10) {
  656. millisecondsString = "00" + to_string(milliseconds);
  657. } else if (milliseconds < 100) {
  658. millisecondsString = "0" + to_string(milliseconds);
  659. }
  660. return hoursString + ":" + minutesString + ":" + secondsString + "." + millisecondsString;
  661. }
  662. void WtHftStraDemo::__tqz_writeStrategyTradeLog(const uint32_t orderid, const double receiveTradePrice, const double lots) {
  663. if (this->_log_message_map.find(orderid) == this->_log_message_map.end())
  664. return;
  665. TQZLogMessage logMessage = this->_log_message_map[orderid];
  666. std::string logString = "[code|" + logMessage.code + ",order_type|" + logMessage.orderType + ",orderid|" + to_string(logMessage.orderid) + ",market_price_of_send_order|" + to_string(logMessage.currentPrice) + ",market_time_of_send_order|" + logMessage.currentMarketTime + ",send_order_price|" + to_string(logMessage.orderPrice) + ",send_order_time|" + logMessage.sendOrderTime + ",receive_trade_price|" + to_string(receiveTradePrice) + ",receive_trade_time|" + this->__tqz_getCurrentTime() + ",lots|" + to_string(lots) + ",volScale|" + to_string(this->_ctx->stra_get_comminfo(this->_code.c_str())->getVolScale()) + ",order_comment|" + logMessage.orderComment + "]";
  667. this->_ctx->tqz_writeLog(this->_tradeChange_log_filename, logString);
  668. }
  669. void WtHftStraDemo::__tqz_writeCancelOrderCountsLog(const std::string code) {
  670. int now = this->__tqz_getCurrentHourMinute();
  671. if (now < 1500 || now > 1630)
  672. return;
  673. uint32_t cancel_order_counts = this->_ctx->tqz_getCancelCounts(code.c_str());
  674. std::string logString = "[code|" + code + ",cancel_order_counts|" + to_string(cancel_order_counts) + "]";
  675. this->_ctx->tqz_writeLog(this->__tqz_getLogFileName(CANCEL_ORDER_COUNTS_TYPE), logString);
  676. }
  677. TQZLogMessage WtHftStraDemo::__tqz_getNewLogMessage(std::string code, uint32_t orderid, double currentPrice, double orderPrice, char* orderType, std::string currentMarketTime, std::string sendOrderTime, std::string orderComment) {
  678. return TQZLogMessage(code, orderid, currentPrice, orderPrice, orderType, currentMarketTime, sendOrderTime, orderComment);
  679. }
  680. uint64_t WtHftStraDemo::__getCurrentTimestamp() {
  681. const boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
  682. const boost::posix_time::time_duration timeOfDay = now.time_of_day();
  683. boost::posix_time::ptime epoch(boost::gregorian::date(1970, boost::gregorian::Jan, 1));
  684. boost::posix_time::time_duration time_from_epoch = boost::posix_time::second_clock::universal_time() - epoch;
  685. return time_from_epoch.total_seconds();
  686. }
  687. bool WtHftStraDemo::__isNewScanInterval(const uint32_t scanInterval) {
  688. uint64_t now = this->__getCurrentTimestamp();
  689. bool isNew = (now - this->_last_scan_time < scanInterval) ? false : true;
  690. if (isNew)
  691. this->_last_scan_time = now;
  692. return isNew;
  693. }
  694. void WtHftStraDemo::__lockBuy() {
  695. this->_code_buy_lock = true;
  696. }
  697. void WtHftStraDemo::__lockSell() {
  698. this->_code_sell_lock = true;
  699. }
  700. void WtHftStraDemo::__lockShort() {
  701. this->_code_short_lock = true;
  702. }
  703. void WtHftStraDemo::__lockCover() {
  704. this->_code_cover_lock = true;
  705. }
  706. void WtHftStraDemo::__unlockBuy() {
  707. this->_code_buy_lock = false;
  708. }
  709. void WtHftStraDemo::__unlockSell() {
  710. this->_code_sell_lock = false;
  711. }
  712. void WtHftStraDemo::__unlockShort() {
  713. this->_code_short_lock = false;
  714. }
  715. void WtHftStraDemo::__unlockCover() {
  716. this->_code_cover_lock = false;
  717. }
  718. void WtHftStraDemo::__unlockAllOrders() {
  719. this->__unlockBuy();
  720. this->__unlockSell();
  721. this->__unlockShort();
  722. this->__unlockCover();
  723. this->__unlockBuy();
  724. this->__unlockSell();
  725. this->__unlockShort();
  726. this->__unlockCover();
  727. }
  728. bool WtHftStraDemo::__isMarketMakingAble() {
  729. if (this->__marketMakingIsLock(false))
  730. return false;
  731. if (this->_ctx->tqz_getCancelCounts(this->_code.c_str()) > this->_cancel_limit_counts)
  732. return false;
  733. if (this->_current_session_status != MARKET_MAKING_STATUS)
  734. return false;
  735. if (this->__isBeyondUpperlimitOrLowerlimit(this->_code, this->_long_order_offset, this->_short_order_offset)) // judge this->_re_market_making is true or false, then modify it...
  736. return false;
  737. return true;
  738. }
  739. bool WtHftStraDemo::__closeCodeIsLock(bool reSendLockOrder) {
  740. bool isLock = (this->_code_sell_lock || this->_code_cover_lock);
  741. if (!reSendLockOrder)
  742. return isLock;
  743. if (this->_code_sell_lock)
  744. this->__tqz_cancelOrder(this->_code, this->_code_sell_order);
  745. if (this->_code_cover_lock)
  746. this->__tqz_cancelOrder(this->_code, this->_code_cover_order);
  747. return isLock;
  748. }
  749. bool WtHftStraDemo::__marketMakingIsLock(bool cancelLockOrder) {
  750. bool isLock = !(!this->_code_buy_lock && !this->_code_short_lock);
  751. if (!cancelLockOrder)
  752. return isLock;
  753. if (this->_code_buy_lock)
  754. this->__tqz_cancelOrder(this->_code, this->_code_buy_order);
  755. if (this->_code_short_lock)
  756. this->__tqz_cancelOrder(this->_code, this->_code_short_order);
  757. return isLock;
  758. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/817826
推荐阅读
相关标签
  

闽ICP备14008679号