| | |
| | | RedisUtils.delete(self.__get_redis(), self.__key) |
| | | |
| | | |
| | | __trade_state_cache = {} |
| | | # 代码的交易状态管理 |
| | | class CodesTradeStateManager: |
| | | __trade_state_cache = {} |
| | | __db = 2 |
| | | __redis_manager = redis_manager.RedisManager(2) |
| | | __instance = None |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(CodesTradeStateManager, cls).__new__(cls, *args, **kwargs) |
| | | __redis = cls.__get_redis() |
| | | # 初始化数据 |
| | | keys = RedisUtils.keys(__redis, "trade-state-*", auto_free=False) |
| | | if keys: |
| | | for key in keys: |
| | | code = key.replace("trade-state-", '') |
| | | cls.__trade_state_cache[code] = int(RedisUtils.get(__redis, key, auto_free=False)) |
| | | |
| | | # 获取交易状态 |
| | | def get_trade_state(code): |
| | | state = RedisUtils.get(__redis_manager.getRedis(), "trade-state-{}".format(code)) |
| | | if state is None: |
| | | return TRADE_STATE_NOT_TRADE |
| | | return int(state) |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | def get_trade_state_cache(code): |
| | | cache_result = tool.CodeDataCacheUtil.get_cache(__trade_state_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = get_trade_state(code) |
| | | tool.CodeDataCacheUtil.set_cache(__trade_state_cache, code, val) |
| | | return val |
| | | # 获取交易状态 |
| | | def get_trade_state(self, code): |
| | | state = RedisUtils.get(self.__get_redis(), "trade-state-{}".format(code)) |
| | | if state is None: |
| | | return TRADE_STATE_NOT_TRADE |
| | | return int(state) |
| | | |
| | | def get_trade_state_cache(self, code): |
| | | cache_result = tool.CodeDataCacheUtil.get_cache(self.__trade_state_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = self.get_trade_state(code) |
| | | tool.CodeDataCacheUtil.set_cache(self.__trade_state_cache, code, val) |
| | | return val |
| | | |
| | | # 设置交易状态 |
| | | def set_trade_state(code, state): |
| | | logger_trade.info("set_trade_state {}-{}".format(code, state)) |
| | | tool.CodeDataCacheUtil.set_cache(__trade_state_cache, code, state) |
| | | RedisUtils.setex_async(__db, "trade-state-{}".format(code), tool.get_expire(), state) |
| | | # 设置交易状态 |
| | | def set_trade_state(self, code, state): |
| | | logger_trade.info("set_trade_state {}-{}".format(code, state)) |
| | | tool.CodeDataCacheUtil.set_cache(self.__trade_state_cache, code, state) |
| | | RedisUtils.setex_async(self.__db, "trade-state-{}".format(code), tool.get_expire(), state) |
| | | |
| | | def get_codes_by_trade_state(self, state): |
| | | redis = self.__get_redis() |
| | | try: |
| | | keys = RedisUtils.keys(redis, "trade-state-*", auto_free=False) |
| | | codes = [] |
| | | if keys is not None: |
| | | for key in keys: |
| | | if int(RedisUtils.get(redis, key, auto_free=False)) == state: |
| | | codes.append(key.replace("trade-state-", '')) |
| | | return codes |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | |
| | | def get_codes_by_trade_state(state): |
| | | redis = __redis_manager.getRedis() |
| | | try: |
| | | keys = RedisUtils.keys(redis, "trade-state-*", auto_free=False) |
| | | def get_codes_by_trade_states(self, states): |
| | | redis = self.__get_redis() |
| | | try: |
| | | keys = RedisUtils.keys(redis, "trade-state-*", auto_free=False) |
| | | codes = [] |
| | | if keys is not None: |
| | | for key in keys: |
| | | if int(RedisUtils.get(redis, key, auto_free=False)) in states: |
| | | codes.append(key.replace("trade-state-", '')) |
| | | return codes |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | |
| | | def get_codes_by_trade_states_cache(self, states): |
| | | # 获取 |
| | | codes = [] |
| | | if keys is not None: |
| | | for key in keys: |
| | | if int(RedisUtils.get(redis, key, auto_free=False)) == state: |
| | | codes.append(key.replace("trade-state-", '')) |
| | | for code in self.__trade_state_cache: |
| | | if self.__trade_state_cache[code] in states: |
| | | codes.append(code) |
| | | return codes |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | |
| | | # 设置交易账户的可用金额 |
| | | |
| | | |
| | | def get_codes_by_trade_states(states): |
| | | redis = __redis_manager.getRedis() |
| | | try: |
| | | keys = RedisUtils.keys(redis, "trade-state-*", auto_free=False) |
| | | codes = [] |
| | | if keys is not None: |
| | | for key in keys: |
| | | if int(RedisUtils.get(redis, key, auto_free=False)) in states: |
| | | codes.append(key.replace("trade-state-", '')) |
| | | return codes |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | # 账户可用资金管理 |
| | | class AccountAvailableMoneyManager: |
| | | __db = 2 |
| | | __redis_manager = redis_manager.RedisManager(2) |
| | | __available_money_cache = None |
| | | __instance = None |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(AccountAvailableMoneyManager, cls).__new__(cls, *args, **kwargs) |
| | | __redis = cls.__get_redis() |
| | | result = RedisUtils.get(cls.__get_redis(), "trade-account-canuse-money") |
| | | if result: |
| | | cls.__available_money_cache = round(float(result), 2) |
| | | return cls.__instance |
| | | |
| | | # 设置交易账户的可用金额 |
| | | def set_available_money(client_id, money): |
| | | RedisUtils.set(__redis_manager.getRedis(), "trade-account-canuse-money", money) |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | def set_available_money(self, client_id, money): |
| | | self.__available_money_cache = round(float(money), 2) |
| | | RedisUtils.set(self.__get_redis(), "trade-account-canuse-money", money) |
| | | |
| | | # 获取交易账户的可用金额 |
| | | def get_available_money(): |
| | | result = RedisUtils.get(__redis_manager.getRedis(), "trade-account-canuse-money") |
| | | if result is None: |
| | | return None |
| | | return round(float(result), 2) |
| | | # 获取交易账户的可用金额 |
| | | def get_available_money(self): |
| | | result = RedisUtils.get(self.__get_redis(), "trade-account-canuse-money") |
| | | if result is None: |
| | | return None |
| | | return round(float(result), 2) |
| | | |
| | | def get_available_money_cache(self): |
| | | return self.__available_money_cache |
| | | |
| | | |
| | | # 保存交易成功的数据 |
| | |
| | | |
| | | @dask.delayed |
| | | def is_state_right(code): |
| | | trade_state = get_trade_state_cache(code) |
| | | trade_state = CodesTradeStateManager().get_trade_state_cache(code) |
| | | if trade_state != TRADE_STATE_NOT_TRADE and trade_state != TRADE_STATE_BUY_CANCEL_SUCCESS and trade_state != TRADE_STATE_BUY_CANCEL_ING: |
| | | return Exception("代码处于不可交易状态"), trade_state |
| | | return None, trade_state |
| | | |
| | | @dask.delayed |
| | | def is_money_enough(code): |
| | | money = get_available_money() |
| | | money = AccountAvailableMoneyManager().get_available_money_cache() |
| | | if money is None: |
| | | return Exception("未获取到账户可用资金"), None |
| | | price = gpcode_manager.get_limit_up_price(code) |
| | |
| | | |
| | | print("开始买入") |
| | | logger_trade.info("{}开始买入".format(code)) |
| | | set_trade_state(code, TRADE_STATE_BUY_PLACE_ORDER) |
| | | CodesTradeStateManager().set_trade_state(code, TRADE_STATE_BUY_PLACE_ORDER) |
| | | _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "买入判断时间", force=True) |
| | | __buy(code, price, trade_state, capture_timestamp, last_data, last_data_index) |
| | | l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "异步买入时间", force=True) |
| | |
| | | def __place_order_fail(code, trade_state): |
| | | print("买入异常") |
| | | # 状态还原 |
| | | set_trade_state(code, trade_state) |
| | | CodesTradeStateManager().set_trade_state(code, trade_state) |
| | | |
| | | |
| | | # 开始取消买入 |
| | | def start_cancel_buy(code, force=False): |
| | | trade_state = get_trade_state_cache(code) |
| | | trade_state = CodesTradeStateManager().get_trade_state_cache(code) |
| | | if trade_state == TRADE_STATE_BUY_SUCCESS: |
| | | return None |
| | | if not force: |
| | |
| | | return None |
| | | try: |
| | | logger_trade.info("{}开始撤单".format(code)) |
| | | set_trade_state(code, TRADE_STATE_BUY_CANCEL_ING) |
| | | CodesTradeStateManager().set_trade_state(code, TRADE_STATE_BUY_CANCEL_ING) |
| | | logger_trade.info("{}撤单方法开始".format(code)) |
| | | if constant.API_TRADE_ENABLE: |
| | | if constant.TRADE_WAY == constant.TRADE_WAY_JUEJIN: |
| | |
| | | # pass |
| | | except Exception as e: |
| | | # 状态还原 |
| | | set_trade_state(code, trade_state) |
| | | CodesTradeStateManager().set_trade_state(code, trade_state) |
| | | logger_trade.error("{}撤单异常:{}".format(code, str(e))) |
| | | raise e |
| | | logger_trade.info("{}撤单完毕".format(code)) |
| | |
| | | time.sleep(0.02) |
| | | for i in range(0, 5): |
| | | # 如果时 |
| | | trade_state = get_trade_state_cache(code) |
| | | trade_state = CodesTradeStateManager().get_trade_state_cache(code) |
| | | if trade_state != TRADE_STATE_BUY_CANCEL_ING and trade_state != TRADE_STATE_BUY_CANCEL_SUCCESS: |
| | | return |
| | | try: |
| | |
| | | # 买入成功 |
| | | if code is not None and int(data["type"]) == 0: |
| | | l2_trade_util.forbidden_trade(code) |
| | | state = get_trade_state_cache(code) |
| | | state = CodesTradeStateManager().get_trade_state_cache(code) |
| | | if state != TRADE_STATE_BUY_SUCCESS: |
| | | set_trade_state(code, TRADE_STATE_BUY_SUCCESS) |
| | | CodesTradeStateManager().set_trade_state(code, TRADE_STATE_BUY_SUCCESS) |
| | | # 删除买撤记录的临时信息 |
| | | kp_client_msg_manager.add_msg(code, "买入成交") |
| | | l2_data_manager.TradePointManager.delete_compute_info_for_cancel_buy(code) |
| | |
| | | code = data["code"] |
| | | if code is not None: |
| | | codes.append(code) |
| | | trade_state = get_trade_state_cache(code) |
| | | trade_state = CodesTradeStateManager().get_trade_state_cache(code) |
| | | # 设置下单状态的代码为已委托 |
| | | if trade_state == TRADE_STATE_BUY_PLACE_ORDER: |
| | | set_trade_state(code, TRADE_STATE_BUY_DELEGATED) |
| | | ing_codes = get_codes_by_trade_state(TRADE_STATE_BUY_CANCEL_ING) |
| | | CodesTradeStateManager().set_trade_state(code, TRADE_STATE_BUY_DELEGATED) |
| | | ing_codes = CodesTradeStateManager().get_codes_by_trade_state(TRADE_STATE_BUY_CANCEL_ING) |
| | | if ing_codes is not None: |
| | | for code in ing_codes: |
| | | if code in codes: |
| | | # 强制重新取消 |
| | | start_cancel_buy(code, True) |
| | | else: |
| | | set_trade_state(code, TRADE_STATE_BUY_CANCEL_SUCCESS) |
| | | CodesTradeStateManager().set_trade_state(code, TRADE_STATE_BUY_CANCEL_SUCCESS) |
| | | l2_data_manager.remove_from_l2_fixed_codes(code) |
| | | |
| | | |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | price = 5 |
| | | r = (5000 // int(round(float(price) * 100))) * 100 |
| | | print(r) |
| | | print(CodesTradeStateManager().get_codes_by_trade_states_cache([0, 1])) |
| | | print(CodesTradeStateManager().get_trade_state_cache("002235")) |
| | | print(CodesTradeStateManager().get_trade_state_cache("002235")) |