/* 设置开仓量 */ void COMPLIANCE_CHECK_API_CALL ComplianceCheck_SetOpenVolume( const char * account, // account char exchange_code, // 交易所编码 const char * product, // 品种 char hedge_flag, // 投机套保类型 int open_volume // 开仓数量 ) { lock_guard<std::mutex> lock(check_mutex); auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { int index = GetCommodityIndex(product); if (index != -1) { if (hedge_flag == CONST_SHFLAG_TOU) { ait->second.cur_speculate_open_times[index] = open_volume; ait->second.cur_total_open_times[index] = open_volume; } else if (hedge_flag == CONST_SHFLAG_TAO) { ait->second.cur_arbitrage_open_times[index] = open_volume; ait->second.cur_total_open_times[index] = open_volume; } } } }
/* 设置撤单数 */ void COMPLIANCE_CHECK_API_CALL ComplianceCheck_SetCancelTimes( const char * account, // account const char * code, // 证券代码 int cancel_times // 撤单次数 ) { char key[64]; sprintf(key, "%s_%s", account, code); lock_guard<std::mutex> lock(check_mutex); auto acit = account_contract_infomap.find(key); if (acit != account_contract_infomap.end()) { acit->second.cur_cancel_times = cancel_times; } else { auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { AccountContractInfo item(ait->second); item.cur_cancel_times = cancel_times; account_contract_infomap.insert(make_pair(key, item)); } } }
/* 订单已撤销,修正完撤单数后删除订单 */ void COMPLIANCE_CHECK_API_CALL ComplianceCheck_OnOrderCanceled( const char * account, // account const char * code, // 证券代码 OrderRefDataType order_ref, // 报单引用 char exchange_code, // 交易所编码 int canceled_volumn, // 撤单数量 char hedge_flag, // 投机套保类型 char open_close_flag // 开平方向 ) { lock_guard<std::mutex> lock(check_mutex); auto oit = order_infomap.find(order_ref); if (oit != order_infomap.end()) { char buy_sell_flag = oit->second.buy_sell_flag; if (oit->second.status == PENDING_CANCEL) { auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { if (open_close_flag == CONST_ENTRUST_OPEN && exchange_code == CONST_EXCHCODE_CFFEX) { int index = GetCommodityIndex(code); if (index != -1) { if (hedge_flag == CONST_SHFLAG_TOU) { ait->second.cur_speculate_open_times[index] -= canceled_volumn; ait->second.cur_total_open_times[index] -= canceled_volumn; } else if (hedge_flag == CONST_SHFLAG_TAO) { ait->second.cur_arbitrage_open_times[index] -= canceled_volumn; ait->second.cur_total_open_times[index] -= canceled_volumn; } } } oit->second.status = CANCELED; order_infomap.erase(order_ref); char key[64]; sprintf(key, "%s_%s", account, code); auto acit = account_contract_infomap.find(key); if (acit != account_contract_infomap.end()) { ResetCurPriceAndOrder(acit, account, code, buy_sell_flag); } auto cit = contract_infomap.find(key); if (cit != contract_infomap.end()) { ResetCurPriceAndOrder(cit, code, buy_sell_flag); } } } } }
/* 开仓数合规检查 */ static int OpenTimesInsertCheck(const AccountContractInfoMap::iterator &acit, const string &account, const char exchange_code, const char open_close_flag, const char hedge_flag, const string &code, const int volume) { if (acit->second.open_times_check) { if (exchange_code == CONST_EXCHCODE_CFFEX && open_close_flag == CONST_ENTRUST_OPEN) { auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { int index = GetCommodityIndex(code); if (index != -1) { if (hedge_flag == CONST_SHFLAG_TOU) { if (ait->second.cur_speculate_open_times[index] + volume > ait->second.max_open_speculate_times || ait->second.cur_total_open_times[index] + volume > ait->second.max_open_total_times) { return COMPLIANCE_CHECK_RESULT_OPEN_REACH_EXCEED_LIMIT; } else if (ait->second.cur_speculate_open_times[index] + volume == ait->second.max_open_speculate_times || ait->second.cur_total_open_times[index] + volume == ait->second.max_open_total_times) { return COMPLIANCE_CHECK_RESULT_OPEN_EQUAL_LIMIT; } } else if (hedge_flag == CONST_SHFLAG_TAO) { if (ait->second.cur_arbitrage_open_times[index] + volume > ait->second.max_open_arbitrage_times || ait->second.cur_total_open_times[index] + volume > ait->second.max_open_total_times) { return COMPLIANCE_CHECK_RESULT_OPEN_REACH_EXCEED_LIMIT; } else if (ait->second.cur_arbitrage_open_times[index] + volume == ait->second.max_open_arbitrage_times || ait->second.cur_total_open_times[index] + volume == ait->second.max_open_total_times) { return COMPLIANCE_CHECK_RESULT_OPEN_EQUAL_LIMIT; } } } } } } return COMPLIANCE_CHECK_RESULT_SUCCESS; }
void COMPLIANCE_CHECK_API_CALL ComplianceCheck_Init( const char * account, // account int warn_threthold, // 撤单警告阈值 int max_cancel, // 最大撤单次数(不可达到) int max_open_speculate, // 最大投机手数 int max_open_arbitrage, // 最大套利手数 int max_open_total, // 最大总手数 const char *switch_mask ) { lock_guard<std::mutex> lock(check_mutex); //pthread_spin_init(&account_mutex , 0); //pthread_spin_init(&account_contract_mutex, 0); //pthread_spin_init(&order_mutex, 0); auto it = account_infomap.find(account); // 如果不存在当前用户则添加到用户信息表里 if (it == account_infomap.end()) { AccountInfo new_item; new_item.max_cancel_times = max_cancel; new_item.max_open_arbitrage_times = max_open_arbitrage; new_item.max_open_speculate_times = max_open_speculate; new_item.max_open_total_times = max_open_total; new_item.warn_threthold_cancel_times = warn_threthold; if (switch_mask) { if (strlen(switch_mask) > 0 && switch_mask[0] == '0') { new_item.self_match_check = false; } if (strlen(switch_mask) > 0 && switch_mask[0] == '2') { new_item.self_match_check_in_all = true; } if (strlen(switch_mask) > 1 && switch_mask[1] == '0') { new_item.cancal_times_check = false; } if (strlen(switch_mask) > 2 && switch_mask[2] == '0') { new_item.open_times_check = false; } } account_infomap.insert(make_pair(account, new_item)); } }
void COMPLIANCE_CHECK_API_CALL ComplianceCheck_OnOrderInsertFailed( const char * account, // account OrderRefDataType order_ref, // 报单引用 char exchange_code, // 交易所编码 const char * code, // 证券代码 int volumn, // 数量 char hedge_flag, // 投机套保类型 char open_close_flag, // 开平方向 char order_type // 报单类型 ) { char key[64]; sprintf(key, "%s_%s", account, code); lock_guard<std::mutex> lock(check_mutex); if (order_type != CONST_ENTRUSTKIND_FAK && order_type != CONST_ENTRUSTKIND_FOK) { order_infomap.erase(order_ref); } auto cit = contract_infomap.find(code); if (cit != contract_infomap.end()) { if (cit->second.cur_buy_ref == order_ref) { ResetCurPriceAndOrder(cit, code, CONST_ENTRUST_BUY); } else if (cit->second.cur_sell_ref == order_ref) { ResetCurPriceAndOrder(cit, code, CONST_ENTRUST_SELL); } } auto it = account_contract_infomap.find(key); if (it != account_contract_infomap.end()) { if (exchange_code == CONST_EXCHCODE_CFFEX) { int index = GetCommodityIndex(code); if (index != -1) { auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { if (hedge_flag == CONST_SHFLAG_TOU) { ait->second.cur_speculate_open_times[index] -= volumn; ait->second.cur_total_open_times[index] -= volumn; } else if (hedge_flag == CONST_SHFLAG_TAO) { ait->second.cur_arbitrage_open_times[index] -= volumn; ait->second.cur_total_open_times[index] -= volumn; } } } } if (it->second.cur_buy_ref == order_ref) { ResetCurPriceAndOrder(it, account, code, CONST_ENTRUST_BUY); } else if (it->second.cur_sell_ref == order_ref) { ResetCurPriceAndOrder(it, account, code, CONST_ENTRUST_BUY); } } }
RESULT_TYPE COMPLIANCE_CHECK_API_CALL ComplianceCheck_TryReqOrderInsert( const char * account, // account OrderRefDataType order_ref, // 报单引用 char exchange_code, // 交易所编码 const char * code, // 证券代码 int volumn, // 数量 double price, // 价格 char price_flag, // 价格类型 char hedge_flag, // 投机套保类型 char buy_sell_flag, // 买卖方向 char open_close_flag, // 开平方向 char order_type, // 报单类型 OrderRefDataType * opposite_serial_no // 【输出】导致自成交对手单的报单引用 ) { char key[64]; sprintf(key, "%s_%s", account, code); lock_guard<std::mutex> lock(check_mutex); RESULT_TYPE ret = COMPLIANCE_CHECK_RESULT_SUCCESS; auto acit = account_contract_infomap.find(key); if (acit != account_contract_infomap.end()) { //撤单数检查 ret = CancelTimesInsertCheck(acit, order_type, open_close_flag); if (ret != COMPLIANCE_CHECK_RESULT_SUCCESS && ret != COMPLIANCE_CHECK_RESULT_CANCEL_TIMES_EQUAL_WARN_THRETHOLD) { return ret; } //开仓数检查 int tmp_ret; tmp_ret = OpenTimesInsertCheck(acit, account, exchange_code, open_close_flag, hedge_flag, code, volumn); if (tmp_ret != COMPLIANCE_CHECK_RESULT_SUCCESS && tmp_ret != COMPLIANCE_CHECK_RESULT_OPEN_EQUAL_LIMIT) { return tmp_ret; } else if (ret == COMPLIANCE_CHECK_RESULT_SUCCESS && tmp_ret == COMPLIANCE_CHECK_RESULT_OPEN_EQUAL_LIMIT) { ret = tmp_ret; } //自成交检查 tmp_ret = SelfTradeInsertCheck(acit, account, code, price_flag, buy_sell_flag, price, opposite_serial_no); if (tmp_ret != COMPLIANCE_CHECK_RESULT_SUCCESS) { return tmp_ret; } //成功下单,录入操作 if (open_close_flag == CONST_ENTRUST_OPEN && exchange_code == CONST_EXCHCODE_CFFEX) { int index = GetCommodityIndex(code); if (index != -1) { auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { if (hedge_flag == CONST_SHFLAG_TOU) { ait->second.cur_speculate_open_times[index] += volumn; ait->second.cur_total_open_times[index] += volumn; } else if (hedge_flag == CONST_SHFLAG_TAO) { ait->second.cur_arbitrage_open_times[index] += volumn; ait->second.cur_total_open_times[index] += volumn; } } } } if (order_type != CONST_ENTRUSTKIND_FAK && order_type != CONST_ENTRUSTKIND_FOK && order_infomap.find(order_ref) == order_infomap.end()) { auto cit = contract_infomap.find(code); if (cit != contract_infomap.end()) { if (buy_sell_flag == CONST_ENTRUST_BUY && price >= cit->second.cur_buy_price) { cit->second.cur_buy_price = price; cit->second.cur_buy_ref = order_ref; } else if (buy_sell_flag == CONST_ENTRUST_SELL && price >= cit->second.cur_buy_price) { cit->second.cur_sell_price = price; cit->second.cur_sell_ref = order_ref; } } if (buy_sell_flag == CONST_ENTRUST_BUY && price >= acit->second.cur_buy_price) { acit->second.cur_buy_price = price; acit->second.cur_buy_ref = order_ref; } else if (buy_sell_flag == CONST_ENTRUST_SELL && price >= acit->second.cur_buy_price) { acit->second.cur_sell_price = price; acit->second.cur_sell_ref = order_ref; } OrderInfo item(account, code, order_type, buy_sell_flag, price, volumn); order_infomap.insert(make_pair(order_ref, item)); } } else { auto ait = account_infomap.find(account); if (ait != account_infomap.end()) { ret = NewOrderInsertCheck(ait, exchange_code, open_close_flag, hedge_flag, volumn); if (ret != COMPLIANCE_CHECK_RESULT_OPEN_REACH_EXCEED_LIMIT) { int tmp_ret = COMPLIANCE_CHECK_RESULT_SUCCESS; if (ait->second.self_match_check_in_all) { tmp_ret = SelfTradeInsertCheck(account, code, price_flag, buy_sell_flag, price, opposite_serial_no); } if (tmp_ret != COMPLIANCE_CHECK_RESULT_SUCCESS) { return tmp_ret; } AccountContractInfo item(ait->second); if (open_close_flag == CONST_ENTRUST_OPEN && exchange_code == CONST_EXCHCODE_CFFEX) { int index = GetCommodityIndex(code); if (index != -1) { if (hedge_flag == CONST_SHFLAG_TOU) { ait->second.cur_speculate_open_times[index] += volumn; ait->second.cur_total_open_times[index] += volumn; } else if (hedge_flag == CONST_SHFLAG_TAO) { ait->second.cur_arbitrage_open_times[index] += volumn; ait->second.cur_total_open_times[index] += volumn; } } } if (order_type != CONST_ENTRUSTKIND_FAK && order_type != CONST_ENTRUSTKIND_FOK) { auto cit = contract_infomap.find(code); if (cit != contract_infomap.end()) { if (buy_sell_flag == CONST_ENTRUST_BUY && price >= cit->second.cur_buy_price) { cit->second.cur_buy_price = price; cit->second.cur_buy_ref = order_ref; } else if (buy_sell_flag == CONST_ENTRUST_SELL && price >= cit->second.cur_buy_price) { cit->second.cur_sell_price = price; cit->second.cur_sell_ref = order_ref; } } else { ContractInfo citem; if (buy_sell_flag == CONST_ENTRUST_BUY) { citem.cur_buy_price = price; citem.cur_buy_ref = order_ref; } else if (buy_sell_flag == CONST_ENTRUST_SELL){ citem.cur_sell_price = price; citem.cur_sell_ref = order_ref; } contract_infomap.insert(make_pair(code, citem)); } if (buy_sell_flag == CONST_ENTRUST_BUY) { item.cur_buy_price = price; item.cur_buy_ref = order_ref; } else { item.cur_sell_price = price; item.cur_sell_ref = order_ref; } } account_contract_infomap.insert(make_pair(key, item)); } if (order_type != CONST_ENTRUSTKIND_FAK && order_type != CONST_ENTRUSTKIND_FOK && order_infomap.find(order_ref) == order_infomap.end()) { OrderInfo item(account, code, order_type, buy_sell_flag, price, volumn); order_infomap.insert(make_pair(order_ref, item)); } } else { return COMPLIANCE_CHECK_RESULT_FAIL; } } return ret; }