"""
|
交易管理器,
|
对一系列的代码交易变量,下单,撤单进行管理
|
"""
|
# 交易管理器
|
import datetime
|
import json
|
from db import mysql_data as mysql_data, redis_manager as redis_manager
|
from db.redis_manager import RedisUtils
|
|
from utils import tool
|
|
__db = 2
|
__redis_manager = redis_manager.RedisManager(2)
|
|
# 未交易
|
TRADE_STATE_NOT_TRADE = 0
|
# 下单
|
TRADE_STATE_BUY_PLACE_ORDER = 10
|
# 已委托买
|
TRADE_STATE_BUY_DELEGATED = 11
|
# 委托取消进行中
|
TRADE_STATE_BUY_CANCEL_ING = 13
|
# 撤销成功
|
TRADE_STATE_BUY_CANCEL_SUCCESS = 14
|
# 买成功
|
TRADE_STATE_BUY_SUCCESS = 12
|
|
latest_trade_delegate_data = []
|
|
|
# 关闭购买入口
|
# 开启购买入口
|
class TradeStateManager:
|
__instance = None
|
redisManager = redis_manager.RedisManager(2)
|
|
def __new__(cls, *args, **kwargs):
|
if not cls.__instance:
|
cls.__instance = super(TradeStateManager, cls).__new__(cls, *args, **kwargs)
|
cls.__instance.__trade_buy_state_cache = cls.is_can_buy()
|
return cls.__instance
|
|
@classmethod
|
def __get_redis(cls):
|
return cls.redisManager.getRedis()
|
|
def sync(self):
|
self.__trade_buy_state_cache = self.is_can_buy()
|
|
# 开启购买入口
|
def open_buy(self):
|
self.__trade_buy_state_cache = True
|
RedisUtils.setex_async(self.__get_redis(), "trade_buy_state", tool.get_expire(), 1)
|
|
# 关闭购买入口
|
def close_buy(self):
|
self.__trade_buy_state_cache = False
|
RedisUtils.setex_async(self.__get_redis(), "trade_buy_state", tool.get_expire(), 0)
|
|
# 是否可以下单
|
@classmethod
|
def is_can_buy(cls):
|
# 默认设置为可交易
|
val = RedisUtils.get(cls.__get_redis(), "trade_buy_state")
|
if val is None:
|
return True
|
if int(val) == 1:
|
return True
|
else:
|
return False
|
|
# 是否可以下单
|
|
def is_can_buy_cache(self):
|
# 默认设置为可交易
|
return self.__trade_buy_state_cache
|
|
|
# 交易目标票模式
|
class TradeTargetCodeModeManager:
|
# 只买想买单
|
MODE_ONLY_BUY_WANT_CODES = 1
|
# 买所有
|
MODE_BUY_ALL = 0
|
|
__instance = None
|
|
redisManager = redis_manager.RedisManager(2)
|
|
def __new__(cls, *args, **kwargs):
|
if not cls.__instance:
|
cls.__instance = super(TradeTargetCodeModeManager, cls).__new__(cls, *args, **kwargs)
|
# 初始化设置
|
# 获取交易窗口的锁
|
cls.__instance.__trade_buy_mode_cache = cls.get_mode()
|
return cls.__instance
|
|
@classmethod
|
def __get_redis(cls):
|
return cls.redisManager.getRedis()
|
|
# 开启购买入口
|
def sync(self):
|
self.__trade_buy_mode_cache = self.get_mode()
|
|
def set_mode(self, mode):
|
if mode != self.MODE_ONLY_BUY_WANT_CODES and mode != self.MODE_BUY_ALL:
|
raise Exception("mode参数值错误")
|
self.__trade_buy_mode_cache = mode
|
RedisUtils.setex(self.__get_redis(), "trade_buy_mode", tool.get_expire(), mode)
|
|
# 是否可以下单
|
@classmethod
|
def get_mode(cls):
|
# 默认设置为可交易
|
val = RedisUtils.get(cls.__get_redis(), "trade_buy_mode")
|
if val is None:
|
return cls.MODE_BUY_ALL
|
return int(val)
|
|
def get_mode_cache(self):
|
return self.__trade_buy_mode_cache
|
|
|
# 根据分数禁止买的票管理
|
class ForbiddenBuyCodeByScoreManager:
|
__instance = None
|
|
def __new__(cls, *args, **kwargs):
|
if not cls.__instance:
|
cls.__instance = super(ForbiddenBuyCodeByScoreManager, cls).__new__(cls, *args, **kwargs)
|
cls.__instance.__redisManager = redis_manager.RedisManager(2)
|
cls.__instance.__key = "forbidden_codes_by_score"
|
cls.__instance.__forbidden_codes_by_score_cache = RedisUtils.smembers(cls.__instance.__get_redis(),
|
cls.__instance.__key)
|
return cls.__instance
|
|
def __get_redis(self):
|
return self.__redisManager.getRedis()
|
|
def add_code(self, code):
|
self.__forbidden_codes_by_score_cache.add(code)
|
RedisUtils.sadd(self.__get_redis(), self.__key, code)
|
|
def remove_code(self, code):
|
self.__forbidden_codes_by_score_cache.discard(code)
|
RedisUtils.srem(self.__get_redis(), self.__key, code)
|
|
def is_in(self, code):
|
return RedisUtils.sismember(self.__get_redis(), self.__key, code)
|
|
def is_in_cache(self, code):
|
return code in self.__forbidden_codes_by_score_cache
|
|
def clear(self):
|
self.__forbidden_codes_by_score_cache.clear()
|
RedisUtils.delete(self.__get_redis(), self.__key)
|
|
|
# 代码的交易状态管理
|
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)
|
cls.__load_datas()
|
|
return cls.__instance
|
|
@classmethod
|
def __get_redis(cls):
|
return cls.__redis_manager.getRedis()
|
|
@classmethod
|
def __load_datas(cls):
|
__redis = cls.__get_redis()
|
try:
|
# 初始化数据
|
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))
|
finally:
|
RedisUtils.realse(__redis)
|
|
# 获取交易状态
|
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]
|
return TRADE_STATE_NOT_TRADE
|
|
# 设置交易状态
|
def set_trade_state(self, 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_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 = []
|
for code in self.__trade_state_cache:
|
if self.__trade_state_cache[code] in states:
|
codes.append(code)
|
return codes
|
# 设置交易账户的可用金额
|
|
|
# 账户可用资金管理
|
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
|
|
@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(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
|
|
|
# 获取交易成功数据
|
def get_trade_success_data():
|
day = datetime.datetime.now().strftime("%Y%m%d")
|
mysqldb = mysql_data.Mysqldb()
|
results = mysqldb.select_all("select * from ths_trade_success_record where day='{}'".format(day))
|
datas = []
|
for result in results:
|
data = {"_id": result[0], "code": result[1], "money": result[2], "num": result[3], "price": result[4],
|
"time": result[5], "trade_num": result[6], "type": result[7], "day": result[8],
|
"create_time": result[9]}
|
datas.append(data)
|
return datas, RedisUtils.get(__redis_manager.getRedis(), "trade-success-latest-time")
|
|
|
# 获取交易委托数据
|
def get_trade_delegate_data():
|
redis = __redis_manager.getRedis()
|
try:
|
result = RedisUtils.get(redis, "trade-delegate-latest", auto_free=False)
|
time_str = RedisUtils.get(redis, "trade-delegate-latest-time", auto_free=False)
|
if result is None:
|
return [], time_str
|
else:
|
return json.loads(result), time_str
|
finally:
|
RedisUtils.realse(redis)
|