import json
|
import time
|
|
# 交易撤销数据管理器
|
import l2_data_util
|
import redis_manager
|
import tool
|
from log import logger_trade
|
|
|
class TradeCancelDataManager:
|
capture_time_dict = {}
|
|
# 保存截图时间
|
@classmethod
|
def save_l2_capture_time(cls, client_id, pos, code, capture_time):
|
cls.capture_time_dict["{}-{}-{}".format(client_id, pos, code)] = {"create_time": round(time.time() * 1000),
|
"capture_time": capture_time}
|
|
# 获取最近一次的截图时间
|
@classmethod
|
def get_latest_l2_capture_time(cls, client_id, pos, code):
|
val = cls.capture_time_dict.get("{}-{}-{}".format(client_id, pos, code))
|
if val is None:
|
return -1
|
# 间隔时间不能大于1s
|
if round(time.time() * 1000) - val["create_time"] > 1000:
|
return -1
|
return val["capture_time"]
|
|
# 获取l2数据的增长速度
|
@classmethod
|
def get_l2_data_grow_speed(cls, client_id, pos, code, add_datas, capture_time):
|
count = 0
|
for data in add_datas:
|
count += data["re"]
|
lastest_capture_time = cls.get_latest_l2_capture_time(client_id, pos, code)
|
if lastest_capture_time < 0:
|
raise Exception("获取上次l2数据截图时间出错")
|
return count / (capture_time - lastest_capture_time)
|
|
# 获取买入确认点的位置
|
@classmethod
|
def get_buy_sure_position(cls, index, speed, trade_time):
|
return index + round(speed * trade_time)
|
|
|
class TradeBuyDataManager:
|
redisManager = redis_manager.RedisManager(0)
|
buy_sure_position_dict = {}
|
|
# 设置买入点的信息
|
# trade_time: 买入点截图时间与下单提交时间差值
|
# capture_time: 买入点截图时间
|
# last_data: 买入点最后一条数据
|
@classmethod
|
def set_buy_position_info(cls, code, capture_time, trade_time, last_data, last_data_index):
|
redis = cls.redisManager.getRedis()
|
redis.setex("buy_position_info-{}".format(code), tool.get_expire(),
|
json.dumps((capture_time, trade_time, last_data, last_data_index)))
|
|
# 获取买入点信息
|
@classmethod
|
def get_buy_position_info(cls, code):
|
redis = cls.redisManager.getRedis()
|
val_str = redis.get("buy_position_info-{}".format(code))
|
if val_str is None:
|
return None, None, None,None
|
else:
|
val = json.loads(val_str)
|
return val[0], val[1], val[2], val[3]
|
|
# 删除买入点信息
|
@classmethod
|
def remove_buy_position_info(cls, code):
|
redis = cls.redisManager.getRedis()
|
redis.delete("buy_position_info-{}".format(code))
|
|
# 设置买入确认点信息
|
@classmethod
|
def __set_buy_sure_position(cls, code, index, data):
|
logger_trade.debug("买入确认点信息: code:{} index:{} data:{}", code, index, data)
|
redis = cls.redisManager.getRedis()
|
key = "buy_sure_position-{}".format(code)
|
redis.setex(key, tool.get_expire(), json.dumps((index, data)))
|
cls.buy_sure_position_dict[code] = (index, data)
|
# 移除下单信号的详细信息
|
cls.remove_buy_position_info(code)
|
|
# 清除买入确认点信息
|
@classmethod
|
def __clear_buy_sure_position(cls, code):
|
redis = cls.redisManager.getRedis()
|
key = "buy_sure_position-{}".format(code)
|
redis.delete(key)
|
if code in cls.buy_sure_position_dict:
|
cls.buy_sure_position_dict.pop(code)
|
|
# 获取买入确认点信息
|
@classmethod
|
def get_buy_sure_position(cls, code):
|
temp = cls.buy_sure_position_dict.get(code)
|
if temp is not None:
|
return temp[0], temp[1]
|
|
redis = cls.redisManager.getRedis()
|
key = "buy_sure_position-{}".format(code)
|
val = redis.get(key)
|
if val is None:
|
return None, None
|
else:
|
val = json.loads(val)
|
cls.buy_sure_position_dict[code] = (val[0], val[1])
|
return val[0], val[1]
|
|
# 处理买入确认点信息
|
@classmethod
|
def process_buy_sure_position_info(cls, code, capture_time, l2_today_datas, l2_latest_data, l2_add_datas):
|
buy_capture_time, trade_time, l2_data, l2_data_index = cls.get_buy_position_info(code)
|
if buy_capture_time is None:
|
# 没有购买者信息
|
return None
|
if capture_time - buy_capture_time < trade_time:
|
# 时间未等待足够
|
return None
|
# 时间差是否相差2s及以上
|
old_time = l2_data["val"]["time"]
|
new_time = l2_latest_data["val"]["time"]
|
old_time_int = l2_data_util.get_time_as_seconds(old_time)
|
new_time_int = l2_data_util.get_time_as_seconds(new_time)
|
if new_time_int - old_time_int >= 2:
|
# 间隔2s及其以上表示数据异常
|
# 间隔2s以上的就以下单时间下一秒末尾作为确认点
|
start_index = l2_data_index
|
if len(l2_today_datas)-1 > start_index:
|
for i in range(start_index + 1, len(l2_today_datas)):
|
_time = l2_today_datas[i]["val"]["time"]
|
if l2_data_util.get_time_as_seconds(_time) - old_time_int >= 2:
|
index = i - 1
|
data = l2_today_datas[index]
|
cls.__set_buy_sure_position(code, index, data)
|
break
|
else:
|
cls.__set_buy_sure_position(code, l2_data_index, l2_data)
|
elif new_time_int - old_time_int >= 0:
|
# 间隔2s内表示数据正常,将其位置设置为新增数据的中间位置
|
index = len(l2_today_datas)-1 - (len(l2_add_datas)) // 2
|
data = l2_today_datas[index]
|
cls.__set_buy_sure_position(code, index, data)
|
else:
|
# 间隔时间小于0 ,一般产生原因是数据回溯产生,故不做处理
|
logger_trade.warning("预估委托位置错误:数据间隔时间小于0 code-{}", code)
|
pass
|
|
|
if __name__ == "__main__":
|
TradeBuyDataManager.set_buy_capture_time("123456", 178938828, 1232)
|
print(TradeBuyDataManager.get_buy_capture_time("123456"))
|