from indicator import Indicator ib = IB() ib.connect(config.HOST, config.PORT, clientId=config.CLIENTID) buyPrice = '2770.75' contContract = ib.reqContractDetails( ContFuture(symbol=config.SYMBOL, exchange=config.EXCHANGE)) tradeContract = contContract[0].contract print("tradecontract ", tradeContract) print("") #contract = ib.Future(symbol = contract.symbol) #print("contract for symbol",contract) print("") openOrdersList = ib.openOrders() #print("contract",contract) print("open orders", openOrdersList) print("open orders", ib.openTrades()) print("open trades ", ib.trades()) print("orders ", ib.orders()) print("length of orders ", len(openOrdersList)) x = 0 # not sure we need to differentiate between buy or sell stop orders below while x < len(openOrdersList): #symbol, orderId, orderType, action, quantity, status, date_order, faProfile, parentId, avgFillPrice, account = parseTradeString(ib,openOrdersList[x]) #validatedOpenOrders = validateOpenOrdersCSV(ib, orderId, status) #log.info("closeOpenOrder: - we have open order records: opendOrderId: {ooi} orderType: {ot} ".format(ooi=orderId, ot=orderType)) print(" blank ") #print("closeOpenOrder: closing all open orders - currently working on: ",openOrdersList[x]) #trademkt = ib.cancelOrder(openOrdersList[x]) # don't need to place order when cancelling
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 ]