Esempio n. 1
0
class Live(IB):
    def __init__(self,
                 symbol,
                 temp,
                 client,
                 verbose=False,
                 notification=False):
        self.symbol = symbol
        instruments = pd.read_csv('instruments.csv').set_index('symbol')
        params = instruments.loc[self.symbol]
        self.market = str(params.market)
        self.exchange = str(params.exchange)
        self.temp = temp
        self.tick_size = float(params.tick_size)
        self.digits = int(params.digits)
        self.leverage = int(params.leverage)
        self.client = client
        self.verbose = verbose
        self.notification = notification
        self.ib = IB()
        print(self.ib.connect('127.0.0.1', 7497, client))
        self.get_contract()
        self.data = self.download_data(tempo=self.temp, duration='1 D')
        self.current_date()
        self.pool = pd.DataFrame(columns=[
            'date', 'id', 'type', 'lots', 'price', 'S/L', 'T/P', 'commission',
            'comment', 'profit'
        ])
        self.history = pd.DataFrame(columns=[
            'date', 'id', 'type', 'lots', 'price', 'S/L', 'T/P', 'commission',
            'comment', 'profit'
        ])
        self.pending = pd.DataFrame(columns=[
            'date', 'id', 'type', 'lots', 'price', 'S/L', 'T/P', 'commission',
            'comment', 'profit'
        ])
        self.position = 0
        self.number = 0

    def get_contract(self):
        if self.market == 'futures':
            expiration = self.ib.reqContractDetails(
                Future(self.symbol,
                       self.exchange))[0].contract.lastTradeDateOrContractMonth
            self.contract = Future(symbol=self.symbol,
                                   exchange=self.exchange,
                                   lastTradeDateOrContractMonth=expiration)
        elif self.market == 'forex':
            self.contract = Forex(self.symbol)
        elif self.market == 'stocks':
            self.contract = Stock(symbol=self.symbol,
                                  exchange=self.exchange,
                                  currency='USD')

    def download_data(self, tempo, duration):
        pr = (lambda mark: 'TRADES' if mark == 'futures' else
              ('TRADES' if mark == 'stocks' else 'MIDPOINT'))(self.market)
        historical = self.ib.reqHistoricalData(self.contract,
                                               endDateTime='',
                                               durationStr=duration,
                                               barSizeSetting=tempo,
                                               whatToShow=pr,
                                               useRTH=True,
                                               keepUpToDate=True)
        return historical

    def data_to_df(self, data):
        df = util.df(data)[['date', 'open', 'high', 'low', 'close',
                            'volume']].set_index('date')
        df.index = pd.to_datetime(df.index)
        return df

    def send_telegram_message(self, msg):
        '''Sends a telegram message
        '''
        requests.post(
            'https://api.telegram.org/bot804823606:AAFq-YMKr4hIjQ4N5M8GYCGa5w9JJ1kIunk/sendMessage',
            data={
                'chat_id': '@ranguito_channel',
                'text': msg
            })

    def current_date(self):
        self.date = datetime.now().strftime('%Y-%m-%d')
        self.weekday = datetime.now().weekday()
        self.hour = datetime.now().strftime('%H:%M:%S')

    def pool_check(self):
        '''Check pool trades'''
        if self.position == 0:
            self.pool = pd.DataFrame(columns=[
                'date', 'type', 'lots', 'price', 'S/L', 'T/P', 'commission',
                'comment', 'profit'
            ])

    def calculate_profit(self, type, price, lots):
        '''Calculates profit'''
        if type == 'BUY':
            profit = (lambda pos: 0
                      if pos >= 0 else (self.pool[self.pool.type == 'SELL'])[
                          'price'].iloc[0] - price)(self.position)
        else:
            profit = (lambda pos: 0 if pos <= 0 else price -
                      (self.pool[self.pool.type == 'BUY'])['price'].iloc[0])(
                          self.position)
        return profit * self.leverage * lots

    def order_values(self, order_id):
        price = 0
        commission = 0
        if len(self.ib.fills()) > 0:
            for trade in util.tree(self.ib.fills()):
                if ('OrderId' and 'clientId') in trade[1]['Execution']:
                    if ((nested_lookup('orderId', trade)[0] == order_id) and
                        (nested_lookup('clientId', trade)[0] == self.client)):
                        commission = nested_lookup('commission', trade)[0]
                        price = nested_lookup('price', trade)[0]
        return (price, commission)

    def order_send(self, type, lots, sl=0, tp=0, comment=''):
        market_order = MarketOrder(type, lots)
        #initial_margin, maintenance_margin = self.get_margins(market_order)
        self.ib.placeOrder(self.contract, market_order)
        id = market_order.orderId

        self.number += 1
        price = 0
        while price == 0:
            self.ib.sleep(1)
            price, commission = self.order_values(id)
        profit = self.calculate_profit(type, price, lots)
        trade = {
            'date': str(self.date) + ' ' + str(self.hour),
            'id': id,
            'type': type,
            'lots': lots,
            'price': price,
            'S/L': sl,
            'T/P': tp,
            'commission': commission,
            'comment': comment,
            'profit': profit
        }
        self.save_trade(trade)
        self.pool = pd.concat(
            [self.pool, pd.DataFrame(trade, index=[self.number])], sort=False)
        self.history = pd.concat(
            [self.history,
             pd.DataFrame(trade, index=[self.number])],
            sort=False)
        mult = (lambda dir: 1 if dir == 'BUY' else -1)(type)
        self.position += (mult * lots)
        self.pool_check()
        if self.verbose:
            print('%s %s | %sING %d units at %5.2f in %s' % (str(
                self.date), str(self.hour), type, lots, price, self.symbol))
        if self.notification:
            if self.position != 0:
                self.send_message_in(type, price, sl, tp, lots)
            else:
                self.send_message_out(type, price, lots, profit, commission,
                                      commission)

    def bracket_stop_order(self,
                           type,
                           lots,
                           entry_price,
                           sl=0,
                           tp=0,
                           comment=''):
        bracket_order = self.ib.bracketStopOrder(type, lots, entry_price, tp,
                                                 sl)
        #initial_margin, maintenance_margin = self.get_margins(bracket_order[0])
        for order in bracket_order:
            self.ib.placeOrder(self.contract, order)
        id_entry = bracket_order[0].orderId
        id_tp = bracket_order[1].orderId
        id_sl = bracket_order[2].orderId

        trade = {
            'date': str(self.date) + ' ' + str(self.hour),
            'id': id_entry,
            'type': bracket_order[0].action,
            'lots': lots,
            'price': entry_price,
            'S/L': sl,
            'T/P': tp,
            'commission': 0,
            'comment': comment,
            'profit': 0
        }
        self.pending = pd.concat(
            [self.pending, pd.DataFrame(trade, index=[id_entry])], sort=False)
        trade = {
            'date': str(self.date) + ' ' + str(self.hour),
            'id': id_tp,
            'type': bracket_order[1].action,
            'lots': lots,
            'price': tp,
            'S/L': 0,
            'T/P': 0,
            'commission': 0,
            'comment': comment,
            'profit': 0
        }
        self.pending = pd.concat(
            [self.pending, pd.DataFrame(trade, index=[id_entry])], sort=False)
        trade = {
            'date': str(self.date) + ' ' + str(self.hour),
            'id': id_sl,
            'type': bracket_order[2].action,
            'lots': lots,
            'price': sl,
            'S/L': 0,
            'T/P': 0,
            'commission': 0,
            'comment': comment,
            'profit': 0
        }
        self.pending = pd.concat(
            [self.pending, pd.DataFrame(trade, index=[id_entry])], sort=False)
        return (bracket_order[0], bracket_order[1], bracket_order[2])

    def pending_check(self, order):
        id = order.orderId
        if len(self.pending) > 0:
            price, commission = self.order_values(id)
            if price > 0:
                self.number += 1
                order_select = self.pending[self.pending.id == id]
                profit = self.calculate_profit(order_select.type.iloc[0],
                                               price,
                                               order_select.lots.iloc[0])
                trade = {
                    'date': str(self.date) + ' ' + str(self.hour),
                    'id': id,
                    'type': order_select.type.iloc[0],
                    'lots': order_select.lots.iloc[0],
                    'price': price,
                    'S/L': order_select['S/L'].iloc[0],
                    'T/P': order_select['T/P'].iloc[0],
                    'commission': commission,
                    'comment': '',
                    'profit': profit
                }
                self.save_trade(trade)
                self.pool = pd.concat(
                    [self.pool,
                     pd.DataFrame(trade, index=[self.number])],
                    sort=False)
                self.history = pd.concat(
                    [self.history,
                     pd.DataFrame(trade, index=[self.number])],
                    sort=False)
                mult = (lambda dir: 1
                        if dir == 'BUY' else -1)(order_select.type.iloc[0])
                self.position += (mult * order_select.lots.iloc[0])
                self.pool_check()
                if self.verbose:
                    print('%s %s | %sING %d units at %5.2f in %s' %
                          (str(self.date), str(
                              self.hour), order_select.type.iloc[0],
                           order_select.lots.iloc[0], price, self.symbol))
                if self.notification:
                    if self.position != 0:
                        self.send_message_in(order_select.type.iloc[0], price,
                                             order_select['S/L'].iloc[0],
                                             order_select['T/P'].iloc[0],
                                             order_select.lots.iloc[0])
                    else:
                        self.send_message_out(order_select.type.iloc[0], price,
                                              order_select.lots.iloc[0],
                                              profit, commission, commission)
                return True
            else:
                return False

    def get_margins(self, order):
        init_margin = float(
            self.ib.whatIfOrder(self.contract, order).initMarginChange)
        maint_margin = float(
            self.ib.whatIfOrder(self.contract, order).maintMarginChange)
        return (init_margin, maint_margin)

    def send_message_in(self, type, price_in, sl, tp, lots):
        msg_in = '%s Opened in %s \nPrice: %5.2f \nS/L: %5.2f \nT/P: %5.2f \nLots: %d \nAt: %s' % (
            type, self.symbol, price_in, sl, tp, lots, self.hour)
        self.send_telegram_message(msg_in)

    def send_message_out(self, type, price_out, lots, profit, comm_in,
                         comm_out):
        msg_out = '%s Closed in %s \nPrice: %5.2f \nProfit(USD): %5.2f \nCommissions(USD): %5.2f \nAt: %s' % \
                    (type, self.symbol, price_out, profit, (comm_in+comm_out),self.hour)
        self.send_telegram_message(msg_out)

    def save_trade(self, trade):
        if not path.exists('history_trades_%s.csv' % self.symbol):
            initial = pd.DataFrame(columns=[
                'date', 'id', 'type', 'lots', 'price', 'S/L', 'T/P',
                'commission', 'comment', 'profit'
            ]).set_index('date')
            initial.to_csv('history_trades_%s.csv' % self.symbol)
        history = pd.read_csv('history_trades_%s.csv' % self.symbol)
        trade = pd.DataFrame(trade, index=[0])
        history = pd.concat([history, trade], sort=False)
        history['net profit'] = history['profit'] - history['commission']
        history['accumulated profit'] = history['net profit'].cumsum()
        history['max profit'] = history['accumulated profit'].cummax()
        history.set_index('date').to_csv('history_trades_%s.csv' % self.symbol)
Esempio n. 2
0
class Hsi(object):
    '''HTISEC to Web Trade'''

    _singleton = None
    ib = None

    def __new__(cls, *args, **kwargs):
        if not cls._singleton:
            cls._singleton = super(Hsi, cls).__new__(cls, *args, **kwargs)
        return cls._singleton

    def __init__(self):
        urllib3.disable_warnings()
        self.status = 0
        self.error = 0

        #允许不止损的交易单数
        self.nostop = 0
        #默认止损的点数
        self.stop_point = 50

        # 是否去除不对应不全的交易记录
        self.is_clear = False

    def verify_error(self, html):
        '''检验是否有错误提示 '''
        reg = re.search(self.reg['error'], html.encode('utf-8'))
        if reg:
            self.error = reg.group(1).decode('utf-8')
            return 1
        else:
            return 0

    # auto login
    def login_a(self):
        self.login(self.account['user'], self.account['pwd'])

    #log in
    # def login(self,user,pwd):
    #     '''auto login for htisec'''
    #     self.account={'user':user,'pwd':pwd}
    #     self._s.cookies.clear()
    #     try:
    #         get1=self._s.get(self.url['login_jsp'] ,verify=False)
    #         #print('Login Request Status:',get1.status_code)
    #         jid1=get1.cookies['JSESSIONID']
    #         self._headers['Cookie']="JSESSIONID="+jid1
    #         login_data = {'login_id': user, 'pwd': pwd}
    #         post1 = self._s.post(self.url['login_do'] , data=login_data,verify=False,timeout=5)
    #         if self.verify_error(post1.text):
    #             self.status=0
    #             print("Login Error:",self.error)
    #             return 0
    #         self._jid=post1.cookies.values()[0]
    #         self._headers['Cookie']="JSESSIONID="+self._jid
    #         print("Login OK,JSESSIONID:", self._jid)
    #         self.status=1
    #         self.login_time=time.time()
    #         print("Login Time:",time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
    #         return self._jid
    #     except Exception as e:
    #         self.status=0
    #         print("Login Try_Error:",e)

    def login_1(self, user, pwd, clientId):
        ''' 登陆 '''
        # self.account={'user':user,'pwd':pwd}
        # self._s.cookies.clear()
        # #login jsp
        # get1 = self._s.get(self.url['login_jsp'], verify=False)
        # # print('Login Request Status:',get1.status_code)
        # jid1 = get1.cookies['JSESSIONID']
        # self._headers['Cookie'] = "JSESSIONID=" + jid1
        # login_data = {'login_id': user, 'pwd': pwd}
        # post1 = self._s.post(self.url['login_do'], data=login_data, verify=False, timeout=20)
        # print(post1.status_code)
        # self.login1_post=post1.text
        # return post1.text
        try:
            if self.ib is None:
                self.ib = IB()
                # self.ib.connect('192.168.2.117', 7496, clientId=8, timeout=3)
                self.ib.connect(user, pwd, clientId=clientId, timeout=3)
        except Exception as exc:
            self.ib = None
            # raise Exception(exc)
        return self.ib

    def get_tradelist(self):
        """ 获取交易记录 """
        if self.ib is None:
            return None

        # ib.trades()
        # ib.orders()
        # ib.fills()
        # util.startLoop()
        # hsi = Future?
        # hsi = Future('HSI', '201901')
        # ib.qualifyContracts(hsi)
        # hsi
        # ticker = ib.reqMktData(hsi)

        data = self.ib.fills()

        df = [[
            i.execution.shares if i.execution.side == 'BOT' else
            -i.execution.shares, i.execution.price,
            str(i.execution.time + datetime.timedelta(hours=8))[:19],
            i.contract.localSymbol, i.commissionReport.commission,
            int(i.contract.multiplier), i.execution.orderRef
        ] for i in data]

        df = pd.DataFrame(df,
                          columns=[
                              'bs', 'price', 'time', 'code', 'sxf', 'hy',
                              'operationPeople'
                          ])
        df = df.sort_values('time')

        # 去除信息不全的单
        if self.is_clear:
            ccs = [[i.contract.localSymbol, i.position]
                   for i in self.ib.portfolio()]
            codes = defaultdict(int)
            for i in ccs:
                codes[i[0]] += i[1]
            _s = []
            for code in set(df.code):
                k = df[df.code == code]
                ints = int(k.bs.sum() - codes[code])
                try:
                    for ind in k.index:
                        ind_bs = k.iloc[ind]['bs']
                        if (ints < 0 and ind_bs < 0
                                and ind_bs >= ints) or (ints > 0 and ind_bs > 0
                                                        and ind_bs <= ints):
                            ints -= ind_bs
                            _s.append(ind)
                            if ints == 0:
                                break
                except:
                    pass
            df = df.drop(_s)

        return df

    def get_gd(self):
        """ 获取当前挂单的记录 """

        if self.ib is None:
            return []

        data = self.ib.openTrades()
        gd = [[
            i.contract.localSymbol,
            str(i.log[0].time + datetime.timedelta(hours=8))[:19],
            i.order.lmtPrice, i.order.action, i.order.totalQuantity
            if i.order.action == 'BUY' else -i.order.totalQuantity,
            i.order.orderType, i.order.ocaGroup, i.order.orderRef
        ] for i in data]

        gd = pd.DataFrame(
            gd,
            columns=['合约', '时间', '价格', '买卖', '数量', '订单类型', '分组名称', '订单发起人'])

        return gd

    def get_cc(self):
        """ 获取当前持仓的记录 """

        if self.ib is None:
            return []

        data = self.ib.portfolio()
        cc = [[
            i.contract.conId, i.contract.localSymbol, i.contract.currency,
            i.contract.multiplier, i.position, i.marketPrice, i.account,
            i.contract.lastTradeDateOrContractMonth
        ] for i in data]

        cc = pd.DataFrame(cc,
                          columns=[
                              '合约ID', '合约代码', '货币', '合约乘数', '数量', '价格', '账户',
                              ' 合约过期时间'
                          ])

        return cc

    def get_lots(self, types):
        """ 获取当前持仓与挂单的占比
            types: LMT, STP LMT """

        cc = self.get_cc()
        gd = self.get_gd()
        res = defaultdict(list)
        # groupID = set()
        # for i in gd.values:
        #     if i[6] not in groupID:
        #         res[i[0]].append(i[4])
        #         groupID.add(i[6])
        [res[i[0]].append(i[4]) for i in gd.values if i[5] == types]
        [res[i[1]].append(i[4]) for i in cc.values]
        res = {i: -sum(j) for i, j in res.items()}
        return res

    def _post_order(self):
        try:
            orderHtml = self._s.post(self.url['confirmBS'],
                                     data=self.orderdata,
                                     verify=False,
                                     timeout=5)
            if self.verify_out(orderHtml):
                self._post_order()
            #print("_Post_Order  Status:",orderHtml.status_code)
            self.ptext = orderHtml.text
            forms = self.get_forms(orderHtml.text)
            forms['login_pwd'] = self.account['pwd']
            #print("taken:",forms['token'])
            orderHtml = self._s.post(self.url['order'],
                                     data=forms,
                                     verify=False,
                                     timeout=5)
            print("Order Request Status:", orderHtml.status_code)
            if self.verify_error(orderHtml.text):
                self.status = 2
                print("_Post_order MSG:", self.error)
        except Exception as e:
            print("System Error:", e)
            self.error = "There was an error in post_order"
            self.status = 2

    def order_buy(self, price, qty=1, prod_code='HSI'):
        if not prod_code:
            prod_code = self.orderdata['prod_code']
        self.orderdata['price'] = str(price)
        self.orderdata['qty'] = str(qty)
        self.orderdata['prod_code'] = prod_code
        self.orderdata['valid_type'] = '0'
        self.orderdata['buy_sell'] = 'B'
        self.orderdata['stop_type'] = ''
        self.orderdata['stop_price'] = ''
        self.orderdata['cond_text'] = ''
        self._post_order()

    def order_sell(self, price, qty=1, prod_code='HSI'):
        print('prod code:', prod_code)
        if not prod_code:
            prod_code = self.orderdata['prod_code']
        self.orderdata['price'] = str(price)
        self.orderdata['qty'] = str(qty)
        self.orderdata['prod_code'] = prod_code
        self.orderdata['valid_type'] = '0'
        self.orderdata['buy_sell'] = 'S'
        self.orderdata['stop_type'] = ''
        self.orderdata['stop_price'] = ''
        self.orderdata['cond_text'] = ''
        self._post_order()

    def order_stopB(self, stop_price, qty, product, add=0):
        '''限价多单止损,跌破止损价->触发空单'''
        price = stop_price - add
        prod_code = product[0:3]
        prod_month = product[3:5]
        self.orderdata['prod_code'] = prod_code
        self.orderdata['contract_mth'] = prod_month
        self.orderdata['price'] = str(price)
        self.orderdata['qty'] = str(qty)
        self.orderdata['valid_type'] = '0'
        self.orderdata['buy_sell'] = 'S'
        self.orderdata['stop_type'] = 'L'
        self.orderdata['stop_price'] = str(stop_price)
        self.orderdata['cond_text'] = ''
        self._post_order()

    def order_stopS(self, stop_price, qty, product, add=0):
        '''限价空单止损,升破止损价->触发多单'''
        price = stop_price + add
        prod_code = product[0:3]
        prod_month = product[3:5]
        self.orderdata['prod_code'] = prod_code
        self.orderdata['contract_mth'] = prod_month
        self.orderdata['price'] = str(price)
        self.orderdata['qty'] = str(qty)
        self.orderdata['valid_type'] = '0'
        self.orderdata['buy_sell'] = 'B'
        self.orderdata['stop_type'] = 'L'
        self.orderdata['stop_price'] = str(stop_price)
        self.orderdata['cond_text'] = ''
        self._post_order()

    def get_forms(self, html):
        '''获得提交表单数据'''
        d = pq(html)
        s = d('INPUT')
        para = {}
        for i in s.items():
            if i.attr('type') == 'hidden':
                para[i.attr('name')] = i.attr('value')
        return para

    #del all
    def order_delAll(self):
        """ 取消所有订单 """
        self.ib.reqGlobalCancel()

    #del order ref
    def order_del(self, orderid):
        '''del order'''
        try:
            gethtml = self.get_url(self.url['orderdetail'] % orderid)
            forms = self.get_forms(gethtml)
            #print("Orderdetail Status:",gethtml.status_code)
            forms['login_pwd'] = self.account['pwd']
            posthtml = self._s.post(self.url['cancelorder'],
                                    data=forms,
                                    verify=False,
                                    timeout=5)
            print("Cancel Order Status:", posthtml.status_code)
            if self.verify_error(posthtml.text):
                self.status = 2
                print("Order_del MSG:", self.error)
        except Exception as e:
            print("Order del Try_Error:", e)

    def get_hold(self, hh):
        '''得到最新执仓'''
        dfList = self.get_tradelist(hh)
        df2 = dfList.groupby('product').trade_qty.sum()
        dictH = {x[0]: 0 for x in df2.iteritems()}
        dfH = pd.DataFrame(columns=[
            'refno', 'product', 'trade_price', 'trade_qty', 'order_time',
            'filled_qty', 'price', 'trade_time'
        ])
        for index, row in dfList.iterrows():
            product = row['product']
            trade_qty = row.trade_qty
            if (dictH[product] >= 0 and trade_qty > 0) or (dictH[product] <= 0
                                                           and trade_qty < 0):
                dfH = dfH.append(row)
                dictH[product] += trade_qty
                #print("go add %d %d" %(row.refno,trade_qty))
            else:
                #print("go calc %d %d" %(row.refno,trade_qty))
                dfH = self.calc_hold(dfH, row, dictH)
            #print("len dfH:",len(dfH),dictH)
        print(dictH)
        self.dictHold = dictH
        return dfH

    def calc_hold(self, dfHold, row1, dict1):
        '''for ge hold'''
        if not len(dfHold):
            return dfHold
        proc = row1['product']
        calc_qty = row1.trade_qty
        # print("func hold record:%d close:%d" %(len(dfHold),calc_qty))
        for index, row in dfHold[dfHold['product'] == proc].sort_index(
                ascending=False).iterrows():
            hold_qty = row.trade_qty
            if abs(hold_qty) == abs(calc_qty):
                dict1[proc] += calc_qty
                dfHold.drop(row.name, axis=0, inplace=True)
                # print("a Proc:%s Hold: %s %d,Close:%s %d" %(proc,row.refno,hold_qty,row1.refno,calc_qty))
                return dfHold
            elif abs(hold_qty) > abs(calc_qty):
                dict1[proc] += calc_qty
                dfHold.loc[row.name, 'trade_qty'] = hold_qty + calc_qty
                # print("b Proc:%s Hold: %s %d,Close:%s %d" %(proc,row.refno,hold_qty,row1.refno,calc_qty))
                return dfHold
            elif abs(hold_qty) < abs(calc_qty):
                dfHold.drop(row.name, axis=0, inplace=True)
                dict1[proc] += -hold_qty
                calc_qty += hold_qty
                # print("c Proc:%s Hold: %s %d,Close:%s %d | calc:%d,hold:%d"
                #         %(proc,row.refno,hold_qty,row1.refno,-hold_qty,calc_qty,dict1[proc]))
                if abs(calc_qty) > 0 and dict1[proc] == 0:
                    row1.trade_qty = calc_qty
                    dict1[proc] = calc_qty
                    dfHold = dfHold.append(row1)
                    # print("d go add %d %d %d" %(row1.refno,calc_qty,len(dfHold)))
                    return dfHold

    def gostop(self):
        # self.login_a()
        orderlist = self.get_orderlist()
        if self.status == 999:
            print("没有正常反回数据!")
            return -1
        #tradelist=self.get_tradelist(orderlist)
        holdlist = self.get_hold(orderlist)
        for hh in self.dictHold:
            self._gostop(orderlist, holdlist, hh)

    def _gostop(self, orderlist, holdlist, proc):
        '''auto stop'''
        nostop = self.nostop
        stop_point = self.stop_point
        hh = orderlist[orderlist['product'] == proc]
        holdlist = holdlist[holdlist['product'] == proc]
        holdlist = holdlist.sort_values("trade_time", ascending=False)
        s_stop = hh.loc[(hh.status == '等待中') & (hh.cond.str.find('SL>=') > -1),
                        'r_qty'].sum()
        b_stop = hh.loc[(hh.status == '等待中') & (hh.cond.str.find('SL<=') > -1),
                        'r_qty'].sum()
        holdQty = self.dictHold[proc]
        if holdQty < 0:
            add_lots = -holdQty - s_stop - nostop
        else:
            add_lots = holdQty + b_stop - nostop
        print("%s@%d hold stop:%d@SL>=price,%d@SL<=price,Add Stop---%d@price" %
              (proc, holdQty, s_stop, b_stop, add_lots))
        if holdQty == 0 or add_lots <= 0:
            return
        cnt = 0
        for index, row in holdlist.iterrows():
            qty = row['trade_qty']
            price = row['trade_price']
            if qty < 0 and cnt <= add_lots:
                print("%s:%d@SL>=%d" % (proc, qty, price + stop_point))
                self.order_stopS(price + stop_point,
                                 qty=int(-qty),
                                 product=proc,
                                 add=0)
            elif qty > 0 and cnt <= add_lots:
                print("%s:%d@SL<=%d" % (proc, qty, price - stop_point))
                self.order_stopB(price - stop_point,
                                 qty=int(qty),
                                 product=proc,
                                 add=0)
            cnt += abs(qty)
            if cnt >= add_lots: return

    def get_prod(self, txt):
        '''Get the New Product List'''
        r1 = re.search(self.reg['prodNameF'], txt)
        #print(r1)
        self.prodNameF = eval(r1.group(1))
        r2 = re.search(self.reg['prodMonthF'], txt)
        self.prodMonthF = eval(r2.group(1))
        #print(r2)

    #del 多余的止损
    def del_stop(self):
        """ 删除多余的止损单 """
        data = self.ib.openOrders()
        [
            self.ib.cancelOrder(data[j]) for j, i in enumerate(data)
            if 'STP' in i.orderType
        ]

    # del指定品种多余的止损单
    def _delstop(self, hh, proc):
        nostop = self.nostop
        stoplist = hh.loc[(hh['product'] == proc)
                          & (hh.cond.str.find("SL") > -1) &
                          (hh.status == '等待中')]
        stop_S = stoplist.loc[stoplist.r_qty > 0, 'r_qty'].sum()
        stop_B = stoplist.loc[stoplist.r_qty < 0, 'r_qty'].sum()
        if proc in self.dictHold:
            holdQty = self.dictHold[proc]
            stopQty = holdQty - nostop if holdQty >= nostop else 0
            if holdQty > 0:
                delQty = abs(stop_B) - stopQty
                self.del_stopB(delQty, stoplist)
                self.del_stopAll('S', stoplist)
            elif holdQty < 0:
                delQty = stop_S - stopQty
                self.del_stopS(delQty, stoplist)
                self.del_stopAll('B', stoplist)
            else:
                self.del_stopAll('B', stoplist)
                self.del_stopAll('S', stoplist)
        else:
            self.del_stopAll('B', stoplist)
            self.del_stopAll('S', stoplist)

    #del stop order
    def del_stopB(self, delqty, hh):
        cont = "SL<="
        delpd = hh.loc[(hh.status == '等待中')
                       & (hh.cond.str.find(cont) > -1)].copy()
        if delqty <= 0 or not len(delpd): return
        delpd = delpd.sort_index(ascending=True)
        for index, rows in delpd.iterrows():
            if rows.sqty <= delqty:
                print("del order %s refno:%d %d" %
                      (rows['product'], rows.refno, rows.sqty))
                self.order_del(rows.refno)
            elif rows.sqty > delqty:
                self.order_del(rows.refno)
                print("del order refno:", rows.refno, delqty)
                stop_price = int(rows.cond[4:].replace(',', ''))
                qty = rows.sqty - delqty
                product = rows['product']
                add = stop_price - rows.price
                self.order_stopB(stop_price, qty, product, add=add)
                print('add  stopB:stop_price=%d,qty=%d,product=%s,add=%d' %
                      (stop_price, qty, product, add))
            delqty = delqty - rows.sqty
            if delqty <= 0: break

    #del stop order
    def del_stopS(self, delqty, hh):
        cont = "SL>="
        delpd = hh.loc[(hh.status == '等待中')
                       & (hh.cond.str.find(cont) > -1)].copy()
        if delqty <= 0 or not len(delpd): return
        delpd = delpd.sort_index(ascending=True)
        for index, rows in delpd.iterrows():
            if rows.bqty <= delqty:
                print("del order refno:", rows.refno, rows.bqty)
                self.order_del(rows.refno)
            elif rows.bqty > delqty:
                self.order_del(rows.refno)
                print("del order refno:", rows.refno, delqty)
                stop_price = int(rows.cond[4:].replace(',', ''))
                qty = rows.bqty - delqty
                product = rows['product']
                add = rows.price - stop_price
                self.order_stopS(stop_price, qty, product, add=add)
                print('add  stopB:stop_price=%d,qty=%d,product=%s,add=%d' %
                      (stop_price, qty, product, add))
            delqty = delqty - rows.bqty
            if delqty <= 0: break

    # del stop all
    def del_stopAll(self, buy_sell):
        data = self.ib.openOrders()
        if buy_sell == 'B':
            cont = 'SELL'
        else:
            cont = 'BUY'
        [
            self.ib.cancelOrder(data[j]) for j, i in enumerate(data)
            if i.action == cont and 'STP' in i.orderType
        ]