Daniel 1 рік тому
батько
коміт
e0c8dd3cdf
1 змінених файлів з 375 додано та 8 видалено
  1. 375 8
      QMT/chongxie_run.py

+ 375 - 8
QMT/chongxie_run.py

@@ -1,10 +1,16 @@
+# coding:utf-8
 from xtquant.xttrader import XtQuantTrader, XtQuantTraderCallback
 from xtquant.xttype import StockAccount
 from xtquant import xtdata, xtconstant
 from datetime import datetime as dt
+import pandas as pd
+import time
+import datetime
+import sys
+import os
 
-
-
+pd.set_option('display.max_columns', None) # 设置显示最大行
+"""
 def run():
     '''阻塞线程接收行情回调'''
     import time
@@ -12,15 +18,376 @@ def run():
     while True:
         time.sleep(3)
         now_date = dt.now()
-        if not client.is_connected() or dt.now() > now_date.replace(hour=11, minute=30, second=0):
+        if not client.is_connected() :
             raise Exception('行情服务连接断开')
             break
     return
 
+
 def trader(data):
-    print(dt.now(), len(data.keys()), data.keys())
+    # print('callback',os.getpid())
+    print(f'{dt.now()},len={len(data.keys())}')
+    print(data)
+
+
+# stocks = xtdata.get_stock_list_in_sector("沪深债券")
+# print(len(stocks))
+stocks = ['110043.SH', '110044.SH', '128075.SZ', '128079.SZ', '113017.SH', '128119.SZ']
+# # stocks = ['110055.SZ', '110061.SZ']
+stock_code = '127045.SZ'
+# seq2 = xtdata.subscribe_quote(stock_code, period='tick', start_time='20230101', end_time='20230407', count=10000, callback=trader)
+# # print(seq2)
+# seq = xtdata.subscribe_whole_quote(['沪深债券'], callback=trader)
+sss = xtdata.subscribe_whole_quote(stocks, callback=trader)
+# aaa = xtdata.subscribe_quote('128130.SZ', period='tick', start_time='', end_time='', count=0, callback=trader)
+#
+xtdata.run()
+exit()
+"""
+
+
+class MyXtQuantTraderCallback(XtQuantTraderCallback):
+    def on_disconnected(self):
+        """
+        连接断开
+        :return:
+        """
+        print(datetime.datetime.now(), '连接断开回调')
+
+    def on_stock_order(self, order):
+        """
+        委托回报推送
+        :param order: XtOrder对象
+        :return:
+        """
+        print(datetime.datetime.now(), '委托回调', order.order_remark)
+
+    def on_stock_trade(self, trade):
+        """
+        成交变动推送
+        :param trade: XtTrade对象
+        :return:
+        """
+        print(datetime.datetime.now(), '成交回调', trade.order_remark)
+
+    def on_order_error(self, order_error):
+        """
+        委托失败推送
+        :param order_error:XtOrderError 对象
+        :return:
+        """
+        # print("on order_error callback")
+        # print(order_error.order_id, order_error.error_id, order_error.error_msg)
+        print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")
+
+    def on_cancel_error(self, cancel_error):
+        """
+        撤单失败推送
+        :param cancel_error: XtCancelError 对象
+        :return:
+        """
+        print(datetime.datetime.now(), sys._getframe().f_code.co_name)
+
+    def on_order_stock_async_response(self, response):
+        """
+        异步下单回报推送
+        :param response: XtOrderResponse 对象
+        :return:
+        """
+        print(f"异步委托回调 {response.order_remark}")
+
+    def on_cancel_order_stock_async_response(self, response):
+        """
+        :param response: XtCancelOrderResponse 对象
+        :return:
+        """
+        print(datetime.datetime.now(), sys._getframe().f_code.co_name)
+
+    def on_account_status(self, status):
+        """
+        :param response: XtAccountStatus 对象
+        :return:
+        """
+        print(datetime.datetime.now(), sys._getframe().f_code.co_name)
+
+
+def get_tick(code, start_time, end_time, period='tick'):
+    from xtquant import xtdata
+
+    xtdata.download_history_data(code, period=period, start_time=start_time, end_time=end_time)
+    data = xtdata.get_local_data(field_list=[], stock_code=[code], period=period)
+    result_list = data[code]
+    df = pd.DataFrame(result_list)
+
+    df['time'] = df['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0))
+    return df.iloc[-20:].loc[:, ['time', 'lastPrice', 'open', 'high','low','amount', 'volume']]
+    # return df.iloc[-20:,:]
+
+
+def process_timestamp(df, filename):
+    df = df.set_index('time_str')
+    result = df.resample('3S').first().ffill()
+    # result = result[(result.index >= '2022-07-20 09:30') & (result.index <= '2022-07-20 15:00')]
+    result = result.reset_index()
+    # result.to_csv(filename + '.csv')
+    print(result)
+
+
+def get_macd_data(data, short=0, long1=0, mid=0):
+    if short == 0:
+        short = 12
+    if long1 == 0:
+        long1 = 26
+    if mid == 0:
+        mid = 9
+    data['sema'] = pd.Series(data['close']).ewm(span=short).mean()
+    data['lema'] = pd.Series(data['close']).ewm(span=long1).mean()
+    data.fillna(0, inplace=True)
+    data['dif'] = data['sema'] - data['lema']
+    data['dea'] = pd.Series(data['dif']).ewm(span=mid).mean()
+    data['macd'] = 2 * (data['dif'] - data['dea'])
+    data.fillna(0, inplace=True)
+    return data
+
+
+def get_hlfx(data):
+    Trading_signals = 0
+    data_temp = data[['time', 'open', 'close', 'high', 'low', 'dif', 'dea', 'macd']]
+    data_temp.columns = ['time', 'open', 'close', 'high', 'low', 'dif', 'dea', 'macd']
+    df_day = pd.DataFrame(columns=['time', 'open', 'close', 'high', 'low', 'volume', 'money', 'HL'])
+    # 先处理去包含
+    for i in data_temp.index:
+        if i == 0 or i == 1:
+            df_day = pd.concat([df_day, data_temp.iloc[[i]]], ignore_index=True)
+        # 不包含
+        elif (df_day.iloc[-1, 3] > data_temp.loc[i, 'high']
+              and df_day.iloc[-1, 4] > data_temp.loc[i, 'low']) \
+                or (df_day.iloc[-1, 3] < data_temp.loc[i, 'high']
+                    and df_day.iloc[-1, 4] < data_temp.loc[i, 'low']):
+            df_day = pd.concat([df_day, data_temp.loc[[i]]], ignore_index=True)
+        # 包含
+        else:
+            # 左高,下降
+            if df_day.iloc[-2, 3] > df_day.iloc[-1, 3]:
+                df_day.iloc[-1, 3] = min(df_day.iloc[-1, 3], data_temp.loc[i, 'high'])
+                df_day.iloc[-1, 4] = min(df_day.iloc[-1, 4], data_temp.loc[i, 'low'])
+            else:
+                # 右高,上升
+                df_day.iloc[-1, 3] = max(df_day.iloc[-1, 3], data_temp.loc[i, 'high'])
+                df_day.iloc[-1, 4] = max(df_day.iloc[-1, 4], data_temp.loc[i, 'low'])
+    # print('111', df_day, data_temp)
+
+    if len(df_day.index) > 2:
+        # 寻找顶底分型
+        for x in range(2, len(df_day.index)):
+            m = x - 1
+            # 底
+            # 符合底分型形态,且第2、3根k线是阳线
+            if ((df_day.loc[x, 'high'] > df_day.loc[x - 1, 'high']) and
+                (df_day.loc[x - 2, 'high'] > df_day.loc[x - 1, 'high'])) and \
+                    df_day.loc[x, 'close'] > df_day.loc[x, 'open'] and \
+                    df_day.loc[x - 1, 'close'] > df_day.loc[x - 1, 'open']:
+
+                df_day.loc[x, 'HL'] = 'L*'
+                while m:
+                    if df_day.loc[m, 'HL'] in ['H', 'HH', 'H*']:
+                        if (x - m) > 3:
+                            # 成笔——>L
+                            df_day.loc[x, 'HL'] = 'L'
+                            # 产生信号,进入hlfx_pool
+                            if x == len(df_day.index) - 1:
+                                Trading_signals = 1
+
+                    elif df_day.loc[m, 'HL'] == 'L':
+                        if df_day.loc[m - 1, 'low'] > df_day.loc[x - 1, 'low']:
+                            # 前一个为底更高,且中间不存在更低的底
+                            df_day.loc[x, 'HL'] = 'L'
+
+                            # 产生信号,进入hlfx_pool
+                            if x == len(df_day.index) - 1:
+                                Trading_signals = 1
+
+                            # 获得MACD,判断MACD判断背驰
+                            x_macd_dif, x_macd_dea, x_macd_macd = data_temp.loc[x, 'dif'], data_temp.loc[x, 'dea'], \
+                            data_temp.loc[x, 'macd']
+                            m_macd_dif, m_macd_dea, m_macd_macd = data_temp.loc[m, 'dif'], data_temp.loc[m, 'dea'], \
+                            data_temp.loc[m, 'macd']
+
+                            # MACD底背驰
+                            if m_macd_dif < x_macd_dif:
+                                # 背驰底->LL
+                                df_day.loc[x, 'HL'] = 'LL'
+                            break
+                        break
+                    m = m - 1
+                    if m == 0:
+                        df_day.loc[x, 'HL'] = 'L'
+
+            # 顶
+            elif ((df_day.loc[x, 'high'] < df_day.loc[x - 1, 'high']) and (
+                    df_day.loc[x - 2, 'high'] < df_day.loc[x - 1, 'high'])):
+
+                df_day.loc[x, 'HL'] = 'H*'
+                while m:
+                    if df_day.loc[m, 'HL'] in ['L', 'LL', 'L*']:
+                        if x - m > 3:
+                            # 成笔->H
+                            df_day.loc[x, 'HL'] = 'H'
+                            # 产生信号,进入hlfx_pool
+                            if x == len(df_day.index) - 1:
+                                Trading_signals = 2
+
+                    elif df_day.loc[m, 'HL'] == 'H':
+                        if df_day.loc[x - 1, 'high'] > df_day.loc[m - 1, 'high']:
+                            # 前一个为顶,且中间存在不包含 or 更高的顶
+                            df_day.loc[x, 'HL'] = 'H'
+                            # 产生信号,进入hlfx_pool
+                            if x == len(df_day.index) - 1:
+                                Trading_signals = 2
+
+                            # 获得MACD,判断MACD判断背驰
+                            x_macd_dif, x_macd_dea, x_macd_macd = data_temp.loc[x, 'dif'], data_temp.loc[x, 'dea'], \
+                            data_temp.loc[x, 'macd']
+                            m_macd_dif, m_macd_dea, m_macd_macd = data_temp.loc[m, 'dif'], data_temp.loc[m, 'dea'], \
+                            data_temp.loc[m, 'macd']
+
+                            # MACD顶背驰
+                            if x_macd_dif < m_macd_dif:
+                                df_day.loc[x, 'HL'] = 'HH'
+                            break
+                        break
+                    m = m - 1
+                    if m == 0:
+                        df_day.loc[x, 'HL'] = 'H'
+
+            else:
+                df_day.loc[x, 'HL'] = '-'
+    df_temp = df_day[['time', 'HL']]
+
+    return df_temp, Trading_signals
+
+
+def ma(df, num):
+    i = -1 * (5 + num)
+    try:
+        if i == -5:
+            ma_num = sum(df['close'][i:])/5
+        else:
+            ma_num = (sum(df['close'][i:(i+5)]))/5
+        # print(df['close'][i:(i+5)])
+    except:
+        return 9999999
+    else:
+        return ma_num
+
+
+def cont(data):
+    code = '127045.SZ'
+    dd = xtdata.get_market_data(field_list=[], stock_list=[code], period='tick', start_time='20230101', end_time='',
+                                count=-1, dividend_type='none', fill_data=True)
+    # print(dt.now(), type(dd), dd[code].shape)
+    # print(dd[code]['time'][-10:-1], '\n', dd[code]['lastPrice'][-10:-1], '\n', dd[code]['open'][-10:-1], '\n', dd[code]['high'][-10:-1])
+    # print(dd[code], '\n'*2)
+    dic = {'time': dd[code]['time'],
+           'open': dd[code]['open'],
+           'close': dd[code]['lastPrice'],
+           'high': dd[code]['high'],
+           'low': dd[code]['low']}
+    df_day = pd.DataFrame(dic)
+    df_day['time'] = df_day['time'].apply(lambda x: dt.fromtimestamp(x / 1000.0))
+    ma_now = ma(df_day, 0)
+    ma_1 = ma(df_day, 1)
+    ma_2 = ma(df_day, 2)
+    ma_3 = ma(df_day,3)
+    # print(ma_now,ma_1,ma_2)
+
+    positions = xt_trader.query_stock_positions(acc)
+    positions_dict = {positions[x].stock_code: positions[x].can_use_volume for x in range(0, len(positions))}
+    # print(positions_dict)
+
+    if code in positions_dict and positions_dict[code] != 0:
+        if df_day['close'].iloc[-1] < ma_now or ma_now < ma_1:
+            order_id = xt_trader.order_stock(acc, code, xtconstant.STOCK_SELL, positions_dict[code],
+                                             xtconstant.LATEST_PRICE, 0, '可转债', '滞涨')
+            print(f'可转债卖出_{order_id},成交价格:{xtconstant.LATEST_PRICE}')
+    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:
+        print('buy:',  df_day['time'].iloc[-1], df_day['close'].iloc[-1], ma_now)
+        order_id = xt_trader.order_stock(acc, code, xtconstant.STOCK_BUY, 10, xtconstant.LATEST_PRICE,
+                                         0, '可转债', '跳多MA5')
+        print(f'可转债Buy——{order_id},成交价格:{xtconstant.LATEST_PRICE}')
+    elif 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]:
+        print('buy:', df_day['time'].iloc[-1], df_day['close'].iloc[-1], ma_now)
+        order_id = xt_trader.order_stock(acc, code, xtconstant.STOCK_BUY, 10, xtconstant.LATEST_PRICE, 0, '可转债', 'tick底分型')
+        print(f'可转债Buy——{order_id},成交价格:{xtconstant.LATEST_PRICE}')
+    # df_day = get_macd_data(df_day)
+    # df_day, Trading_signals= get_hlfx(df_day)
+    # print(df_day)
+    if dic ==1:
+        pass
+    elif dic ==1:
+        pass
+
+
+def dump_single_code_tick():
+    # 导出单个转债的tick数据
+    code='127045'
+    start_date = '20230101'
+    end_date = '202304010'
+
+    post_fix = 'SZ' if code.startswith('12') else 'SH'
+    code = '{}.{}'.format(code,post_fix)
+    print(code)
+    filename = '{}'.format(code)
+    df = get_tick(code, start_date, end_date)
+    print(df)
+
+
+if __name__ == '__main__':
+    # 指定客户端所在路径
+    path = r'c:\\qmt\\userdata_mini'
+    # 生成session id 整数类型 同时运行的策略不能重复
+    session_id = int(time.time())
+    xt_trader = XtQuantTrader(path, session_id)
+    # 创建资金账号为 800068 的证券账号对象
+    acc = StockAccount('920000207040', 'SECURITY')
+    # 创建交易回调类对象,并声明接收回调
+    callback = MyXtQuantTraderCallback()
+    xt_trader.register_callback(callback)
+    # 启动交易线程
+    xt_trader.start()
+    # 建立交易连接,返回0表示连接成功
+    connect_result = xt_trader.connect()
+    print('建立交易连接,返回0表示连接成功', connect_result)
+    # 对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功
+    subscribe_result = xt_trader.subscribe(acc)
+    print('对交易回调进行订阅,订阅后可以收到交易主推,返回0表示订阅成功', subscribe_result)
+
+    code = '127045.SZ'
+    st = dt.now()
+    stocks = xtdata.get_stock_list_in_sector('沪深A股')
+    xtdata.subscribe_quote(code, 'tick', start_time='', end_time='', count=1000, callback=cont)
+    # xtdata.subscribe_whole_quote(stocks,callback=cont)
+    # dd = xtdata.get_market_data(field_list=[], stock_list=[code], period='tick', start_time='20230101', end_time='',
+    #                             count=-1,
+    #                             dividend_type='none', fill_data=True)
+
+    # print(positions_dict[code])
+    # print(type(dd), type(dd[code]), type(dd[code][-1]), dd[code], dd)
+    # print(dd[code]['lastPrice'])
+    # dd[code]['time'] = dd[code]['time'].apply(lambda x: dt.fromtimestamp(x / 1000.0))
+    # print(type(dd[code]['time']), dd[code]['time'])
+    # print('________','\n')
+    # print(type(list(dd[code]['time'])))
+    # print('________')
+    # print(dd[code])
+    xtdata.run()
+    # dump_single_code_tick()
+
+    et = dt.now()
+    print(et-st)
+
+
+
+
+
 
-# stocks = stocks = xtdata.get_stock_list_in_sector('沪深A股')
-stocks = ['000001.SZ', '600000.SH', '300389.SZ', '001229.SZ', '600674.SH', '000895.SZ']
-xtdata.subscribe_whole_quote(stocks, callback=trader)
-run()