chongxie_run.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. # coding:utf-8
  2. from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
  3. from xtquant.xttype import StockAccount
  4. from xtquant import xtdata, xtconstant
  5. from datetime import datetime as dt
  6. import pandas as pd
  7. import time
  8. import datetime
  9. import sys
  10. import os
  11. pd.set_option('display.max_columns', None) # 设置显示最大行
  12. """
  13. def run():
  14. '''阻塞线程接收行情回调'''
  15. import time
  16. client = xtdata.get_client()
  17. while True:
  18. time.sleep(3)
  19. now_date = dt.now()
  20. if not client.is_connected() :
  21. raise Exception('行情服务连接断开')
  22. break
  23. return
  24. def trader(data):
  25. # print('callback',os.getpid())
  26. print(f'{dt.now()},len={len(data.keys())}')
  27. print(data)
  28. # stocks = xtdata.get_stock_list_in_sector("沪深债券")
  29. # print(len(stocks))
  30. stocks = ['110043.SH', '110044.SH', '128075.SZ', '128079.SZ', '113017.SH', '128119.SZ']
  31. # # stocks = ['110055.SZ', '110061.SZ']
  32. stock_code = '127045.SZ'
  33. # seq2 = xtdata.subscribe_quote(stock_code, period='tick', start_time='20230101', end_time='20230407', count=10000, callback=trader)
  34. # # print(seq2)
  35. # seq = xtdata.subscribe_whole_quote(['沪深债券'], callback=trader)
  36. sss = xtdata.subscribe_whole_quote(stocks, callback=trader)
  37. # aaa = xtdata.subscribe_quote('128130.SZ', period='tick', start_time='', end_time='', count=0, callback=trader)
  38. #
  39. xtdata.run()
  40. exit()
  41. """
  42. class MyXtQuantTraderCallback(XtQuantTraderCallback):
  43. def on_disconnected(self):
  44. """
  45. 连接断开
  46. :return:
  47. """
  48. print(datetime.datetime.now(), '连接断开回调')
  49. def on_stock_order(self, order):
  50. """
  51. 委托回报推送
  52. :param order: XtOrder对象
  53. :return:
  54. """
  55. print(datetime.datetime.now(), '委托回调', order.order_remark)
  56. def on_stock_trade(self, trade):
  57. """
  58. 成交变动推送
  59. :param trade: XtTrade对象
  60. :return:
  61. """
  62. print(datetime.datetime.now(), '成交回调', trade.order_remark)
  63. def on_order_error(self, order_error):
  64. """
  65. 委托失败推送
  66. :param order_error:XtOrderError 对象
  67. :return:
  68. """
  69. # print("on order_error callback")
  70. # print(order_error.order_id, order_error.error_id, order_error.error_msg)
  71. print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")
  72. def on_cancel_error(self, cancel_error):
  73. """
  74. 撤单失败推送
  75. :param cancel_error: XtCancelError 对象
  76. :return:
  77. """
  78. print(datetime.datetime.now(), sys._getframe().f_code.co_name)
  79. def on_order_stock_async_response(self, response):
  80. """
  81. 异步下单回报推送
  82. :param response: XtOrderResponse 对象
  83. :return:
  84. """
  85. print(f"异步委托回调 {response.order_remark}")
  86. def on_cancel_order_stock_async_response(self, response):
  87. """
  88. :param response: XtCancelOrderResponse 对象
  89. :return:
  90. """
  91. print(datetime.datetime.now(), sys._getframe().f_code.co_name)
  92. def on_account_status(self, status):
  93. """
  94. :param response: XtAccountStatus 对象
  95. :return:
  96. """
  97. print(datetime.datetime.now(), sys._getframe().f_code.co_name)
  98. def get_tick(code, start_time, end_time, period='tick'):
  99. from xtquant import xtdata
  100. xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
  101. data = xtdata.get_local_data(field_list=[], stock_code=[code], period=period)
  102. result_list = data[code]
  103. df = pd.DataFrame(result_list)
  104. df['time'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
  105. return df.iloc[-20:].loc[:, ['time', 'lastPrice', 'open', 'high','low','amount', 'volume']]
  106. # return df.iloc[-20:,:]
  107. def process_timestamp(df, filename):
  108. df = df.set_index('time_str')
  109. result = df.resample('3S').first().ffill()
  110. # result = result[(result.index >= '2022-07-20 09:30') & (result.index <= '2022-07-20 15:00')]
  111. result = result.reset_index()
  112. # result.to_csv(filename + '.csv')
  113. print(result)
  114. def get_macd_data(data, short=0, long1=0, mid=0):
  115. if short == 0:
  116. short = 12
  117. if long1 == 0:
  118. long1 = 26
  119. if mid == 0:
  120. mid = 9
  121. data['sema'] = pd.Series(data['close']).ewm(span=short).mean()
  122. data['lema'] = pd.Series(data['close']).ewm(span=long1).mean()
  123. data.fillna(0, inplace=True)
  124. data['dif'] = data['sema'] - data['lema']
  125. data['dea'] = pd.Series(data['dif']).ewm(span=mid).mean()
  126. data['macd'] = 2 * (data['dif'] - data['dea'])
  127. data.fillna(0, inplace=True)
  128. return data
  129. def get_hlfx(data):
  130. Trading_signals = 0
  131. data_temp = data[['time', 'open', 'close', 'high', 'low', 'dif', 'dea', 'macd']]
  132. data_temp.columns = ['time', 'open', 'close', 'high', 'low', 'dif', 'dea', 'macd']
  133. df_day = pd.DataFrame(columns=['time', 'open', 'close', 'high', 'low', 'volume', 'money', 'HL'])
  134. # 先处理去包含
  135. for i in data_temp.index:
  136. if i == 0 or i == 1:
  137. df_day = pd.concat([df_day, data_temp.iloc[[i]]], ignore_index=True)
  138. # 不包含
  139. elif (df_day.iloc[-1, 3] > data_temp.loc[i, 'high']
  140. and df_day.iloc[-1, 4] > data_temp.loc[i, 'low']) \
  141. or (df_day.iloc[-1, 3] < data_temp.loc[i, 'high']
  142. and df_day.iloc[-1, 4] < data_temp.loc[i, 'low']):
  143. df_day = pd.concat([df_day, data_temp.loc[[i]]], ignore_index=True)
  144. # 包含
  145. else:
  146. # 左高,下降
  147. if df_day.iloc[-2, 3] > df_day.iloc[-1, 3]:
  148. df_day.iloc[-1, 3] = min(df_day.iloc[-1, 3], data_temp.loc[i, 'high'])
  149. df_day.iloc[-1, 4] = min(df_day.iloc[-1, 4], data_temp.loc[i, 'low'])
  150. else:
  151. # 右高,上升
  152. df_day.iloc[-1, 3] = max(df_day.iloc[-1, 3], data_temp.loc[i, 'high'])
  153. df_day.iloc[-1, 4] = max(df_day.iloc[-1, 4], data_temp.loc[i, 'low'])
  154. # print('111', df_day, data_temp)
  155. if len(df_day.index) > 2:
  156. # 寻找顶底分型
  157. for x in range(2, len(df_day.index)):
  158. m = x - 1
  159. # 底
  160. # 符合底分型形态,且第2、3根k线是阳线
  161. if ((df_day.loc[x, 'high'] > df_day.loc[x - 1, 'high']) and
  162. (df_day.loc[x - 2, 'high'] > df_day.loc[x - 1, 'high'])) and \
  163. df_day.loc[x, 'close'] > df_day.loc[x, 'open'] and \
  164. df_day.loc[x - 1, 'close'] > df_day.loc[x - 1, 'open']:
  165. df_day.loc[x, 'HL'] = 'L*'
  166. while m:
  167. if df_day.loc[m, 'HL'] in ['H', 'HH', 'H*']:
  168. if (x - m) > 3:
  169. # 成笔——>L
  170. df_day.loc[x, 'HL'] = 'L'
  171. # 产生信号,进入hlfx_pool
  172. if x == len(df_day.index) - 1:
  173. Trading_signals = 1
  174. elif df_day.loc[m, 'HL'] == 'L':
  175. if df_day.loc[m - 1, 'low'] > df_day.loc[x - 1, 'low']:
  176. # 前一个为底更高,且中间不存在更低的底
  177. df_day.loc[x, 'HL'] = 'L'
  178. # 产生信号,进入hlfx_pool
  179. if x == len(df_day.index) - 1:
  180. Trading_signals = 1
  181. # 获得MACD,判断MACD判断背驰
  182. x_macd_dif, x_macd_dea, x_macd_macd = data_temp.loc[x, 'dif'], data_temp.loc[x, 'dea'], \
  183. data_temp.loc[x, 'macd']
  184. m_macd_dif, m_macd_dea, m_macd_macd = data_temp.loc[m, 'dif'], data_temp.loc[m, 'dea'], \
  185. data_temp.loc[m, 'macd']
  186. # MACD底背驰
  187. if m_macd_dif < x_macd_dif:
  188. # 背驰底->LL
  189. df_day.loc[x, 'HL'] = 'LL'
  190. break
  191. break
  192. m = m - 1
  193. if m == 0:
  194. df_day.loc[x, 'HL'] = 'L'
  195. # 顶
  196. elif ((df_day.loc[x, 'high'] < df_day.loc[x - 1, 'high']) and (
  197. df_day.loc[x - 2, 'high'] < df_day.loc[x - 1, 'high'])):
  198. df_day.loc[x, 'HL'] = 'H*'
  199. while m:
  200. if df_day.loc[m, 'HL'] in ['L', 'LL', 'L*']:
  201. if x - m > 3:
  202. # 成笔->H
  203. df_day.loc[x, 'HL'] = 'H'
  204. # 产生信号,进入hlfx_pool
  205. if x == len(df_day.index) - 1:
  206. Trading_signals = 2
  207. elif df_day.loc[m, 'HL'] == 'H':
  208. if df_day.loc[x - 1, 'high'] > df_day.loc[m - 1, 'high']:
  209. # 前一个为顶,且中间存在不包含 or 更高的顶
  210. df_day.loc[x, 'HL'] = 'H'
  211. # 产生信号,进入hlfx_pool
  212. if x == len(df_day.index) - 1:
  213. Trading_signals = 2
  214. # 获得MACD,判断MACD判断背驰
  215. x_macd_dif, x_macd_dea, x_macd_macd = data_temp.loc[x, 'dif'], data_temp.loc[x, 'dea'], \
  216. data_temp.loc[x, 'macd']
  217. m_macd_dif, m_macd_dea, m_macd_macd = data_temp.loc[m, 'dif'], data_temp.loc[m, 'dea'], \
  218. data_temp.loc[m, 'macd']
  219. # MACD顶背驰
  220. if x_macd_dif < m_macd_dif:
  221. df_day.loc[x, 'HL'] = 'HH'
  222. break
  223. break
  224. m = m - 1
  225. if m == 0:
  226. df_day.loc[x, 'HL'] = 'H'
  227. else:
  228. df_day.loc[x, 'HL'] = '-'
  229. df_temp = df_day[['time', 'HL']]
  230. return df_temp, Trading_signals
  231. def ma(df, num):
  232. i = -1 * (5 + num)
  233. try:
  234. if i == -5:
  235. ma_num = sum(df['close'][i:])/5
  236. else:
  237. ma_num = (sum(df['close'][i:(i+5)]))/5
  238. # print(df['close'][i:(i+5)])
  239. except:
  240. return 9999999
  241. else:
  242. return ma_num
  243. def cont(data):
  244. # print(dt.now())
  245. code = '127045.SZ'
  246. dd = xtdata.get_market_data(field_list=[], stock_list=[code], period='tick', start_time='20230101', end_time='',
  247. count=-1, dividend_type='none', fill_data=True)
  248. # print(dt.now(), type(dd), dd[code].shape)
  249. # print(dd[code]['time'][-10:-1], '\n', dd[code]['lastPrice'][-10:-1], '\n', dd[code]['open'][-10:-1], '\n', dd[code]['high'][-10:-1])
  250. # print(dd[code], '\n'*2)
  251. dic = {'time': dd[code]['time'],
  252. 'open': dd[code]['open'],
  253. 'close': dd[code]['lastPrice'],
  254. 'high': dd[code]['high'],
  255. 'low': dd[code]['low']}
  256. df_day = pd.DataFrame(dic)
  257. df_day['time'] = df_day['time'].apply(lambda x: dt.fromtimestamp(x / 1000.0))
  258. ma_now = ma(df_day, 0)
  259. ma_1 = ma(df_day, 1)
  260. ma_2 = ma(df_day, 2)
  261. ma_3 = ma(df_day,3)
  262. # print(ma_now,ma_1,ma_2)
  263. positions = xt_trader.query_stock_positions(acc)
  264. positions_dict = {positions[x].stock_code: positions[x].can_use_volume for x in range(0, len(positions))}
  265. # print(positions_dict)
  266. if code in positions_dict and positions_dict[code] != 0:
  267. if df_day['close'].iloc[-1] < ma_now or ma_now < ma_1:
  268. order_id = xt_trader.order_stock(acc, code, xtconstant.STOCK_SELL, positions_dict[code],
  269. xtconstant.LATEST_PRICE, 0, '可转债', '滞涨')
  270. print(f'可转债卖出_{order_id},成交价格:{xtconstant.LATEST_PRICE}')
  271. # if df_day['close'].iloc[-1] > ma_now > ma_1 and ma_1 < ma_2 <= ma_3 and df_day['close'].iloc[-2] < ma_1:
  272. # print('buy:', df_day['time'].iloc[-1], df_day['close'].iloc[-1], ma_now)
  273. # order_id = xt_trader.order_stock(acc, code, xtconstant.STOCK_BUY, 10, xtconstant.LATEST_PRICE,
  274. # 0, '可转债', '跳多MA5')
  275. # print(f'可转债Buy——{order_id},成交价格:{xtconstant.LATEST_PRICE}')
  276. if df_day['close'].iloc[-1] > df_day['close'].iloc[-2] and df_day['close'].iloc[-4] >df_day['close'].iloc[-3] > df_day['close'].iloc[-2]:
  277. print('buy:', df_day['time'].iloc[-1], df_day['close'].iloc[-1], ma_now)
  278. order_id = xt_trader.order_stock(acc, code, xtconstant.STOCK_BUY, 10, xtconstant.LATEST_PRICE, 0, '可转债', 'tick底分型')
  279. print(f'可转债Buy——{order_id},成交价格:{xtconstant.LATEST_PRICE}')
  280. # df_day = get_macd_data(df_day)
  281. # df_day, Trading_signals= get_hlfx(df_day)
  282. # print(df_day)
  283. if dic ==1:
  284. pass
  285. elif dic ==1:
  286. pass
  287. def dump_single_code_tick():
  288. # 导出单个转债的tick数据
  289. code='127045'
  290. start_date = '20230101'
  291. end_date = '202304010'
  292. post_fix = 'SZ' if code.startswith('12') else 'SH'
  293. code = '{}.{}'.format(code,post_fix)
  294. print(code)
  295. filename = '{}'.format(code)
  296. df = get_tick(code, start_date, end_date)
  297. print(df)
  298. if __name__ == '__main__':
  299. # 指定客户端所在路径
  300. path = r'c:\\qmt\\userdata_mini'
  301. # 生成session id 整数类型 同时运行的策略不能重复
  302. session_id = int(time.time())
  303. xt_trader = XtQuantTrader(path, session_id)
  304. # 创建资金账号为 800068 的证券账号对象
  305. acc = StockAccount('920000207040', 'SECURITY')
  306. # 创建交易回调类对象,并声明接收回调
  307. callback = MyXtQuantTraderCallback()
  308. xt_trader.register_callback(callback)
  309. # 启动交易线程
  310. xt_trader.start()
  311. # 建立交易连接,返回0表示连接成功
  312. connect_result = xt_trader.connect()
  313. print('建立交易连接,返回0表示连接成功', connect_result)
  314. # 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
  315. subscribe_result = xt_trader.subscribe(acc)
  316. print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)
  317. code = '127045.SZ'
  318. st = dt.now()
  319. stocks = xtdata.get_stock_list_in_sector('沪深A股')
  320. xtdata.subscribe_quote(code, 'tick', start_time='', end_time='', count=1000, callback=cont)
  321. # xtdata.subscribe_whole_quote(stocks,callback=cont)
  322. # dd = xtdata.get_market_data(field_list=[], stock_list=[code], period='tick', start_time='20230101', end_time='',
  323. # count=-1,
  324. # dividend_type='none', fill_data=True)
  325. # print(positions_dict[code])
  326. # print(type(dd), type(dd[code]), type(dd[code][-1]), dd[code], dd)
  327. # print(dd[code]['lastPrice'])
  328. # dd[code]['time'] = dd[code]['time'].apply(lambda x: dt.fromtimestamp(x / 1000.0))
  329. # print(type(dd[code]['time']), dd[code]['time'])
  330. # print('________','\n')
  331. # print(type(list(dd[code]['time'])))
  332. # print('________')
  333. # print(dd[code])
  334. xtdata.run()
  335. # dump_single_code_tick()
  336. et = dt.now()
  337. print(et-st)