Administrator
4 天以前 48fb7a00951f91bdc707e5dd2d196e5bccb752c3
trade/trade_huaxin.py
@@ -1,47 +1,27 @@
"""
华鑫交易
"""
import copy
import json
import time
import constant
from db.redis_manager import RedisManager
from log_module.log import logger_juejin_trade
from l2.huaxin import huaxin_delegate_postion_manager
from log_module import async_log_util
from log_module.log import logger_juejin_trade, hx_logger_trade_debug, logger_trade
from trade.buy_money_count_setting import BuyMoneyUtil
from trade.huaxin import huaxin_trade_api
from trade.huaxin.huaxin_trade_record_manager import TradeOrderIdManager
from utils import tool, huaxin_util
from l2 import huaxin
from l2 import huaxin, l2_data_util
__context_dict = {}
# 交易订单号管理
class TradeOrderIdManager:
    __redisManager = RedisManager(2)
    @classmethod
    def __get_redis(cls):
        return cls.__redisManager.getRedis()
    # 添加订单ID
    @classmethod
    def add_order_id(cls, code, account_id, order_id):
        cls.__get_redis().sadd(f"huaxin_order_id-{code}", json.dumps((account_id, order_id)))
        cls.__get_redis().expire(f"huaxin_order_id-{code}", tool.get_expire())
    # 删除订单ID
    @classmethod
    def remove_order_id(cls, code, account_id, order_id):
        cls.__get_redis().srem(f"huaxin_order_id-{code}", json.dumps((account_id, order_id)))
    # 查询所有的订单号
    @classmethod
    def list_order_ids(cls, code):
        return cls.__get_redis().smembers(f"huaxin_order_id-{code}")
__TradeOrderIdManager = TradeOrderIdManager()
def init(context):
    __context_dict["init"] = context
    print("掘金交易初始化成功")
# 可用金额
@@ -53,58 +33,180 @@
# 通过量下单,返回(代码,账号ID,订单号)
def order_volume(code, price, count, last_data_index):
    if code.find("00") != 0 and code.find("60") != 0:
        raise Exception("只支持00开头与60开头的代码下单")
    start_time = time.time()
    # 保存下单信息
    huaxin.huaxin_delegate_postion_manager.place_order(code, price, count, last_data_index)
    if not constant.TRADE_ENABLE:
        return
    result = huaxin_trade_api.order(1, code, count, price)
    print("华鑫下单耗时", time.time() - start_time)
    logger_juejin_trade.info(f"{code}:下单耗时{round(time.time() - start_time, 3)}s")
    if result:
        print("下单结果", result)
        if result['code'] == 0:
            result = result["data"]
            if result["orderStatus"] == huaxin_util.TORA_TSTP_OST_Rejected:
                logger_juejin_trade.info(f"{code}:下单失败:{result.get('statusMsg')}")
                raise Exception(result.get('statusMsg'))
def order_volume(code, price, count, last_data, order_ref=None, exec_index=None, shadow_volume=None):
    if not shadow_volume:
        shadow_volume = 100
    async_log_util.info(logger_trade, f"{code} trade_huaxin.order_volume 开始")
    try:
        price = round(float(price), 2)
        if not tool.is_can_buy_code(code):
            raise Exception("只支持00开头与60开头的代码下单")
        # 保存下单信息
        shadow_price = tool.get_shadow_price(price)
        huaxin.huaxin_delegate_postion_manager.place_order(code, price, count, exec_index, last_data, order_ref,
                                                           shadow_price=shadow_price, shadow_volume=shadow_volume)
        if not constant.TRADE_ENABLE:
            return
        result = None
        blocking = False
        try:
            async_log_util.info(logger_trade, f"{code}下单开始")
            result = huaxin_trade_api.order(1, code, count, price, blocking=blocking, order_ref=order_ref,
                                            shadow_price=shadow_price, shadow_volume=shadow_volume)
            async_log_util.info(logger_trade, f"{code}下单结束")
        except Exception as e:
            if str(e).find("超时") >= 0:
                # 此处出现超时,需要通过读取委托列表来设置订单信息
                async_log_util.error(hx_logger_trade_debug, f"{code}:下单结果反馈出错-{str(e)}")
            else:
                TradeOrderIdManager.add_order_id(code, result["accountID"], result["orderSysID"])
                logger_juejin_trade.info(f"{code}:下单成功 orderSysID:{result['orderSysID']}")
                return result["securityId"], result["accountID"], result["orderSysID"]
                raise e
        if result:
            if blocking:
                if result['code'] == 0:
                    result = result["data"]
                    if result["orderStatus"] == huaxin_util.TORA_TSTP_OST_Rejected:
                        async_log_util.info(hx_logger_trade_debug, f"{code}:下单失败:{result.get('statusMsg')}")
                        raise Exception(result.get('statusMsg'))
                    else:
                        __TradeOrderIdManager.add_order_id(code, result["accountID"], result["orderSysID"])
                        async_log_util.info(hx_logger_trade_debug, f"{code}:下单成功 orderSysID:{result['orderSysID']}")
                        return result["securityId"], result["accountID"], result["orderSysID"]
                else:
                    raise Exception(result['msg'])
            else:
                order_ref = result["order_ref"]
                __TradeOrderIdManager.add_order_ref(code, order_ref)
                async_log_util.info(hx_logger_trade_debug, f"{code}:下单成功 orderRef:{order_ref}")
                return code, "local", order_ref
        else:
            raise Exception(result['msg'])
    else:
        raise Exception("下单失败,无返回")
            raise Exception("下单失败,无返回")
    finally:
        async_log_util.info(logger_trade, f"{code} trade_huaxin.order_volume 结束")
def order_success(code, accountId, orderSysID):
    TradeOrderIdManager.add_order_id(code, accountId, orderSysID)
# 通过量下单,返回(代码,账号ID,订单号)
def order_volume_new(code, price, volume, last_data, exec_index=None):
    """
    新版下单:拆分为2个订单
    @param code:
    @param price:
    @param volume: 总股数
    @param last_data: 最后一条L2数据
    @param exec_index: 执行位
    @return:
    """
    async_log_util.info(logger_trade, f"{code} trade_huaxin.order_volume_new 开始")
    try:
        price = round(float(price), 2)
        if not tool.is_can_buy_code(code):
            raise Exception("只支持00开头与60开头的代码下单")
        # 拆单
        v1, v2 = BuyMoneyUtil.get_possible_buy_volumes_by_total_volume(volume)
        oredr_info_list = [(v1, price, huaxin_util.create_order_ref()), (v2, price, huaxin_util.create_order_ref())]
        huaxin.huaxin_delegate_postion_manager.RealDelegateOrderPositionManager.place_order(code, oredr_info_list,
                                                                                            exec_index, last_data)
        if not constant.TRADE_ENABLE:
            return
        result = None
        blocking = False
        try:
            async_log_util.info(logger_trade, f"{code}下单开始")
            result = huaxin_trade_api.order_new(1, code, oredr_info_list, blocking=blocking)
            async_log_util.info(logger_trade, f"{code}下单结束")
        except Exception as e:
            if str(e).find("超时") >= 0:
                # 此处出现超时,需要通过读取委托列表来设置订单信息
                async_log_util.error(hx_logger_trade_debug, f"{code}:下单结果反馈出错-{str(e)}")
            else:
                raise e
        if result:
            if blocking:
                if result['code'] == 0:
                    result = result["data"]
                    if result["orderStatus"] == huaxin_util.TORA_TSTP_OST_Rejected:
                        async_log_util.info(hx_logger_trade_debug, f"{code}:下单失败:{result.get('statusMsg')}")
                        raise Exception(result.get('statusMsg'))
                    else:
                        __TradeOrderIdManager.add_order_id(code, result["accountID"], result["orderSysID"])
                        async_log_util.info(hx_logger_trade_debug, f"{code}:下单成功 orderSysID:{result['orderSysID']}")
                        return result["securityId"], result["accountID"], result["orderSysID"]
                else:
                    raise Exception(result['msg'])
            else:
                order_ref_list = result["order_ref_list"]
                __TradeOrderIdManager.add_order_refs(code, order_ref_list)
                async_log_util.info(hx_logger_trade_debug, f"{code}:下单成功 orderRefs:{order_ref_list}")
                return code, "local", order_ref_list
        else:
            raise Exception("下单失败,无返回")
    finally:
        async_log_util.info(logger_trade, f"{code} trade_huaxin.order_volume_new 结束")
def cancel_order_success(code, accountId, orderSysID):
    TradeOrderIdManager.remove_order_id(code, accountId, orderSysID)
def order_success(code, accountId, orderSysID, orderRef, insertTime):
    # 加入系统订单号
    __TradeOrderIdManager.add_order_id(code, accountId, orderSysID)
    # 删除临时订单号
    __TradeOrderIdManager.remove_order_ref(code, orderRef)
    # 根据插入时间判断下单位置是否正确
    try:
        place_index = huaxin_delegate_postion_manager.get_place_order_position(code)
        if place_index and insertTime:
            # 大致判断是否为真实下单位置
            total_datas = l2_data_util.local_today_datas.get(code)
            if total_datas:
                if 0 < tool.trade_time_sub(insertTime, total_datas[place_index]["val"]["time"]) < 4:
                    # 4s内才会校验
                    volume = total_datas[place_index]["val"]["num"]
                    for i in range(place_index + 1, len(total_datas)):
                        if total_datas[i]["val"]["num"] == volume and insertTime == total_datas[i]["val"]["time"]:
                            huaxin_delegate_postion_manager.set_place_order_position(code, i)
                            hx_logger_trade_debug.info("{}校验真实下单成功,{}->{}", code, place_index, i)
                            return i
                else:
                    raise Exception(f"不满足校验条件,真实下单时间:{insertTime}  预估下单时间:{total_datas[place_index]['val']['time']}")
            else:
                raise Exception("未获取到L2数据")
        else:
            raise Exception(f"尚未获取到数据(place_index-{place_index} insertTime-{insertTime})")
    except Exception as e:
        hx_logger_trade_debug.warning("{}校验真实下单位置出错:{}", code, str(e))
    return None
# 撤单
def cancel_order(code):
    orders_info = TradeOrderIdManager.list_order_ids(code)
def cancel_order(code, msg=''):
    if not constant.TRADE_ENABLE:
        return
    orders_info = __TradeOrderIdManager.list_order_ids_cache(code)
    orders_info = copy.deepcopy(orders_info)
    orders = []
    if orders_info:
        for order in orders_info:
            order_info = json.loads(order)
            orders.append({'orderSysID': order_info[1], 'accountId': order_info[0]})
    if orders:
        logger_juejin_trade.info(f"{code}:开始执行撤单")
        logger_juejin_trade.info(f"{code}:撤单成功,撤单数量:{len(orders)}")
        for order in orders:
            huaxin_trade_api.cancel_order(1, code, order["orderSysID"])
            TradeOrderIdManager.remove_order_id(code, order["accountId"], order["orderSysID"])
        if orders:
            async_log_util.info(logger_trade, f"{code}:华鑫开始执行撤单 {msg}")
            huaxin_trade_api.batch_cancel_order(huaxin_trade_api.TRADE_DIRECTION_BUY, code,
                                                [('', order["orderSysID"]) for order in orders])
            for order in orders:
                __TradeOrderIdManager.remove_order_id(code, order["accountId"], order["orderSysID"])
            async_log_util.info(logger_trade, f"{code}:华鑫撤单结束,撤单数量:{len(orders)}")
        # 查询是否有本地订单号
    order_refs_info = __TradeOrderIdManager.list_order_refs_cache(code)
    if order_refs_info:
        order_refs_info = copy.deepcopy(order_refs_info)
        async_log_util.info(logger_trade, f"{code}:华鑫开始执行撤单 {msg}")
        huaxin_trade_api.batch_cancel_order(huaxin_trade_api.TRADE_DIRECTION_BUY, code,
                                            [(order_ref, '') for order_ref in order_refs_info])
        for order_ref in order_refs_info:
            __TradeOrderIdManager.remove_order_ref(code, order_ref)
        async_log_util.info(logger_trade, f"{code}:华鑫执行撤单结束")
if __name__ == "__main__":