"""
|
掘金交易
|
"""
|
import json
|
import logging
|
import time
|
|
import gm.api as gmapi
|
|
import constant
|
from code_attribute import gpcode_manager
|
from db.redis_manager import RedisManager, RedisUtils
|
from log_module.log import logger_juejin_trade
|
from utils import network_util, tool
|
|
__context_dict = {}
|
|
account_id = "77916efb-b856-46ee-9680-71be0fe18a42"
|
token = "38fb624832c1949708c7600abaf1e863d27663b3"
|
gmapi.set_token(token)
|
|
|
# gmapi.set_account_id(account_id)
|
|
|
# 交易订单号管理
|
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):
|
RedisUtils.sadd(cls.__get_redis(),f"juejin_order_id-{code}", json.dumps((account_id, order_id)))
|
cls.__get_redis().expire(f"juejin_order_id-{code}", tool.get_expire())
|
|
# 删除订单ID
|
@classmethod
|
def remove_order_id(cls, code, account_id, order_id):
|
cls.__get_redis().srem(f"juejin_order_id-{code}", json.dumps((account_id, order_id)))
|
|
# 查询所有的订单号
|
@classmethod
|
def list_order_ids(cls, code):
|
return RedisUtils.smembers(cls.__get_redis(), f"juejin_order_id-{code}")
|
|
|
def init(context):
|
__context_dict["init"] = context
|
print("掘金交易初始化成功")
|
|
|
# 可用金额
|
def get_account_left_money():
|
if "init" in __context_dict:
|
dict_ = __context_dict["init"].account().cash
|
return dict_["available"]
|
return None
|
|
|
# 通过量下单,返回(代码,账号ID,订单号)
|
def order_volume(code, price, count):
|
if not constant.TRADE_ENABLE:
|
return
|
if code.find("00") != 0 and code.find("60") != 0:
|
raise Exception("只支持00开头与60开头的代码下单")
|
code_str = code
|
if code[0:2] == '00':
|
code_str = f"SZSE.{code}"
|
elif code[0:2] == '60':
|
code_str = f"SHSE.{code}"
|
start_time = time.time()
|
results = gmapi.order_volume(code_str, count, gmapi.OrderSide_Buy, gmapi.OrderType_Limit, gmapi.PositionEffect_Open,
|
price=price,
|
order_duration=gmapi.OrderDuration_GFD, account=account_id)
|
print("掘金下单耗时", time.time() - start_time)
|
logger_juejin_trade.info(f"{code}:下单耗时{round(time.time() - start_time, 3)}s")
|
|
if results:
|
print("下单结果", results)
|
result = results[0]
|
if result["ord_rej_reason_detail"]:
|
logger_juejin_trade.info(f"{code}:下单失败:{result['ord_rej_reason_detail']}")
|
raise Exception(result["ord_rej_reason_detail"])
|
else:
|
TradeOrderIdManager.add_order_id(code, result["account_id"], result["cl_ord_id"])
|
logger_juejin_trade.info(f"{code}:下单成功 ord_id:{result['cl_ord_id']}")
|
return result["symbol"].split(".")[1], result["account_id"], result["cl_ord_id"]
|
else:
|
raise Exception("下单失败,无返回")
|
|
|
# 撤单
|
def cancel_order(code):
|
orders_info = TradeOrderIdManager.list_order_ids(code)
|
orders = []
|
if orders_info:
|
for order in orders_info:
|
order_info = json.loads(order)
|
orders.append({'cl_ord_id': order_info[1], 'account_id': order_info[0]})
|
if orders:
|
logger_juejin_trade.info(f"{code}:开始执行撤单")
|
# 执行3次撤单
|
for i in range(3):
|
gmapi.order_cancel(orders)
|
logger_juejin_trade.info(f"{code}:撤单成功,撤单数量:{len(orders)}")
|
for order in orders:
|
TradeOrderIdManager.remove_order_id(code, order["account_id"], order["cl_ord_id"])
|
|
|
# 撤单
|
def __cancel_order(account_id, cl_ord_id):
|
orders = [{'cl_ord_id': cl_ord_id, 'account_id': account_id}]
|
gmapi.order_cancel(orders)
|
|
|
def test():
|
symbols = gpcode_manager.get_gp_list_with_prefix(["002531"])
|
data = gmapi.get_instruments(symbols=",".join(symbols))
|
print(data)
|
|
|
def run():
|
if constant.TRADE_WAY == constant.TRADE_WAY_JUEJIN:
|
print("启动读取掘金交易数据")
|
# strategy_id = "e97a257e-1bba-11ed-a1b1-00e070c694ff"
|
# token = "a2eed2b159e9238dc0353fc3e73734d7677f7baf"
|
# gmapi.run(strategy_id, filename="trade.trade_juejin.py", mode=gmapi.MODE_LIVE, token=token)
|
while True:
|
try:
|
if tool.is_trade_time():
|
datas = get_execution_reports()
|
# 上传数据
|
fdatas = []
|
for d in datas:
|
fdatas.append(
|
{"code": d[0], "money": d[4], "num": d[2], "price": d[3], "time": d[7], "trade_num": d[5],
|
"type": d[1] - 1})
|
if fdatas:
|
network_util.send_socket_msg("127.0.0.1", 9001, {"type": 3, "data": fdatas})
|
except Exception as e:
|
logging.exception(e)
|
# 2s更新
|
time.sleep(1.5)
|
|
|
# 获取成交列表,返回的内容为:[(代码,买(1)/卖(2),量,价格,成交金额,订单ID,委托客户端ID,成交时间,成交日期)]
|
def get_execution_reports():
|
gmapi.set_account_id(account_id)
|
reports = gmapi.get_execution_reports()
|
results = []
|
for r in reports:
|
if not r['ord_rej_reason_detail']:
|
results.append(
|
[r["symbol"].split(".")[1], r["side"], r["volume"], round(r["price"], 2), round(r["amount"], 2),
|
r["order_id"],
|
r["cl_ord_id"], r["created_at"].strftime("%H:%M:%S"), r["created_at"].strftime("%Y-%m-%d")])
|
# 根据订单号合并数据
|
temp_dict = {}
|
for r in results:
|
if r[5] not in temp_dict:
|
temp_dict[r[5]] = r
|
else:
|
temp_dict[r[5]][2] += r[2]
|
temp_dict[r[5]][4] += r[4]
|
results = [temp_dict[k] for k in temp_dict]
|
print("获取已成交数量:", len(results))
|
|
return results
|
|
|
if __name__ == "__main__":
|
datas = get_execution_reports()
|
# 上传数据
|
fdatas = []
|
for d in datas:
|
fdatas.append(
|
{"code": d[0], "money": d[4], "num": d[2], "price": d[3], "time": d[7], "trade_num": d[5],
|
"type": d[1] - 1})
|
print(fdatas)
|
network_util.send_socket_msg("127.0.0.1", 9001, {"type": 3, "data": fdatas})
|
# print(order_volume("000566", 4.66, 100))
|
# gmapi.set_token(token)
|
# gmapi.set_account_id(account_id)
|
# cancel_order("000566")
|
# orders=[]
|
# orders.append({'cl_ord_id':"3a691f3d-fdc7-11ed-838e-f4b5203f67bf", 'account_id': "8099a935-a991-4871-977f-206c6d3e04ca"})
|
# gmapi.order_cancel(orders)
|