def fetch_postion(self, acct_name): all_pos = self.brokers[acct_name].fapiPrivate_get_positionrisk() all_trade_pos = [] valid_pos = [] for pos in all_pos: bn_syms = [coin + 'USDT' for coin in Settings['coins']] if pos['symbol'] in bn_syms: all_trade_pos.append(pos) psd = pos['positionSide'] amt = float(pos['positionAmt']) if pos['symbol'] in bn_syms and psd != 'BOTH' and amt != 0: if pos['marginType'] == 'cross': Lgr.log('bnews', f"账户: {acct_name}, {pos['symbol']} 是全仓模式") print(pos) continue del pos['markPrice'] del pos['liquidationPrice'] del pos['maxNotionalValue'] del pos['isAutoAddMargin'] pnlr = float(pos['unRealizedProfit']) / float( pos['isolatedMargin']) pos['浮盈'] = f'{round(pnlr*100,2)}%' pos['账户'] = acct_name valid_pos.append(pos) self.all_valid_pos[acct_name] = valid_pos self.all_trade_pos[acct_name] = all_trade_pos return valid_pos
def cancel_porders(self, porder_df, idxs): for idx in idxs.split(' '): order = porder_df.iloc[int(idx)] param = {"symbol": order['symbol'], "orderId": order['orderId']} res = brkrs.cancel_porder(order['账户'], param) if res and res['orderId']: Lgr.log('SUCCESS', f"撤销订单 {res['symbol']} {res['clientOrderId']} 成功")
def print_pos(self): Lgr.log('alert', '获取所有账户仓位:') all_valid_pos = [] for acct in Settings['accts']: all_valid_pos += brkrs.fetch_postion(acct['name']) pos_df = pd.DataFrame(all_valid_pos) print(pos_df) print( '-------------------------------------------------------------------------------' )
def print_forders(self): Lgr.log('os', f"获取所有账户最近{Settings['filled_cnt']}笔成交单:") all_forders = [] for acct in Settings['accts']: all_forders += brkrs.fetch_forders(acct['name']) forder_df = pd.DataFrame(all_forders) forder_df = forder_df.sort_values(by=['updateTime'], ascending=False) forder_df = forder_df.drop(columns=['orderId', 'updateTime', 'status']) print(forder_df.head(Settings['filled_cnt']))
def print_porders(self): Lgr.log('ol', '获取所有账户挂单:') all_porders = [] for acct in Settings['accts']: all_porders += brkrs.fetch_porders(acct['name']) self.curr_showing_porder_df = pd.DataFrame(all_porders) print(self.curr_showing_porder_df) print( '********************************************************************************' )
def print_lev(self): for acct in Settings['accts']: an = acct['name'] self.levs[an] = {} all_pos = brkrs.all_trade_pos[an] for pos in all_pos: self.levs[an][pos['symbol']] = pos['leverage'] Lgr.log('status', f"{an} 杠杆: {self.levs[an]}") print( '-------------------------------------------------------------------------------' )
def place_order(self, acct_name, param): try: if not Settings['trading']['order_allowed']: msg = f'({data}) bn order is not allowed in config.' Lgr.log('bnews', msg) return {'clientOrderId': None, 'orderId': None} brkr = self.brokers[acct_name] return brkr.fapiPrivate_post_order(param) except Exception as e: Lgr.log('ERROR', e) return {'clientOrderId': None, 'orderId': None}
def _set_lev(self, acct_name, data): sym = data['symbol'] for pos in brkrs.all_trade_pos[acct_name]: if pos['symbol'] == sym: if data['lev'] and float(pos['leverage']) != data['lev']: brkrs.brokers[acct_name].fapiPrivate_post_leverage({ 'symbol': sym, 'leverage': data['lev'] }) Lgr.log( 'gnews', f"账户 {acct_name} {sym} 杠杆从 {pos['leverage']} 变更为 {data['lev']}" ) return
def __init__(self): self._bn = ccxt.binance({'timeout': 6000, 'enableRateLimit': True}) self.sym_infos = {} # sym format: BTCUSDT self.all_equ = {} self.all_valid_pos = {} self.all_trade_pos = {} self.brokers = {} self._fetch_symbol_info() for acct in Settings['accts']: self.brokers[acct['name']] = ccxt.binance({ 'apiKey': acct['apiKey'], 'secret': acct['secret'], 'timeout': 6000, 'enableRateLimit': True }) Lgr.log('update', 'bn brokers inited')
def create_stop_order(self, data): sym = data['symbol'] for an in data['vas']: rstr = base62.encode(int(datetime.now().timestamp())) param = { 'symbol': sym, 'side': data['side'], 'positionSide': data['positionSide'], 'type': 'STOP_MARKET', 'newClientOrderId': f"{app}_stplos_{rstr}", 'stopPrice': data['price'], 'closePosition': True, 'workingType': 'MARK_PRICE' } res = brkrs.place_order(an, param) if res['orderId']: op_ch = get_op(data['op']) Lgr.log(data['op'], f"账户:{an} {op_ch}: {param}") else: Lgr.log('ERROR', 'place order has error')
def print_sym_porders(self, sym): Lgr.log('ol', f'获取所有账户 {sym} 挂单:') all_porders = [] for acct in Settings['accts']: porders = brkrs.brokers[acct['name']].fapiPrivate_get_openorders( {'symbol': sym}) for order in porders: del order['workingType'] del order['priceProtect'] del order['time'] del order['updateTime'] del order['timeInForce'] del order['cumQuote'] del order['closePosition'] order['账户'] = acct['name'] all_porders.append(order) self.curr_showing_porder_df = pd.DataFrame(all_porders) print(self.curr_showing_porder_df) print( '********************************************************************************' )
def get_plan_order_param(event,values): estrs = event.split('-') coin = estrs[1] op_ch = get_op(estrs[2]) # operation: ol,os,cl,cs vas = get_valid_accts(values) # acct list price = values[f"{coin}-stp"] if not price: Lgr.log('bnews','必须设置止损价') return None,None pstr = f"操作账户: {vas} \n\n币: {coin} \n\n方向: {op_ch} \n\n止损价格: {price}\n" param = { 'symbol': f"{coin}USDT", 'side': 'SELL' if event[-1]=='l' else 'BUY', 'positionSide': 'LONG' if event[-1]=='l' else 'SHORT', 'vas': vas, 'op': estrs[2], 'price': price } return pstr,param
def create_pos(self, data): sym = data['symbol'] if data['price'] == '市价': res = brkrs.fetch_symbol_price(sym) price = float(res['price']) order_type = 'MARKET' else: price = float(data['price']) #fix price order_type = 'LIMIT' for an in data['vas']: self._set_lev(an, data) acct_equ = brkrs.all_equ[an] margin_rate = float(data['mr'][:-1]) / 100 margin = acct_equ * margin_rate quote = margin * float(data['lev']) qp = brkrs.sym_infos[sym]['qp'] qty = round(quote / price, qp) qty = max(qty, 1 / pow(10, qp)) rstr = base62.encode(int(datetime.now().timestamp())) param = { 'symbol': sym, 'side': data['side'], 'positionSide': data['positionSide'], 'type': order_type, 'quantity': qty, 'newClientOrderId': f"{app}_{data['op']}_{rstr}", } if order_type == 'LIMIT': param['price'] = price param['timeInForce'] = 'GTC' res = brkrs.place_order(an, param) if res['orderId']: op_ch = get_op(data['op']) Lgr.log(data['op'], f"账户:{an} {op_ch}: {param}") else: Lgr.log('ERROR', 'place order has error')
def create_pfhl_order(self, data): stp_p = float(data['price']) sym = data['symbol'] pside = data['positionSide'] for an in data['vas']: pp = brkrs.sym_infos[sym]['pp'] qp = brkrs.sym_infos[sym]['qp'] close_rate = 0.5 pos_amt = 0 brkrs.fetch_postion(an) for pos in brkrs.all_valid_pos[an]: if pos['symbol'] == sym and pos['positionSide'] == pside: pos_amt = float(pos['positionAmt']) entry_p = float(pos['entryPrice']) if not pos_amt: Lgr.log('bnews', f"账户 {an} {sym} 没有 {pside} 仓位") continue if pside == 'LONG': price = round( abs(entry_p - stp_p) + entry_p * (1 + Settings['slippage']), pp) else: price = round( entry_p * (1 - Settings['slippage']) - abs(entry_p - stp_p), pp) qty = round(abs(pos_amt) * close_rate, qp) qty = max(qty, 1 / pow(10, qp)) rstr = base62.encode(int(datetime.now().timestamp())) param = { 'symbol': sym, 'side': data['side'], 'positionSide': pside, 'price': price, 'type': 'LIMIT', 'timeInForce': 'GTC', 'quantity': qty, 'newClientOrderId': f"{app}_{data['op']}_{rstr}", } res = brkrs.place_order(an, param) if res['orderId']: op_ch = get_op(data['op']) Lgr.log(data['op'], f"账户:{an} {op_ch}: {param}") else: Lgr.log('ERROR', 'place order has error')
def close_pos(self, data): sym = data['symbol'] if data['price'] == '市价': res = brkrs.fetch_symbol_price(sym) price = float(res['price']) order_type = 'MARKET' else: price = float(data['price']) #fix price order_type = 'LIMIT' for an in data['vas']: qp = brkrs.sym_infos[sym]['qp'] close_rate = float(data['cr'][:-1]) / 100 pos_amt = 0 for pos in brkrs.all_valid_pos[an]: if pos['symbol'] == sym and pos['positionSide'] == data[ 'positionSide']: pos_amt = float(pos['positionAmt']) if not pos_amt: Lgr.log('bnews', f'账户 {an} 没有找到对应仓位') return qty = round(abs(pos_amt) * close_rate, qp) qty = max(qty, 1 / pow(10, qp)) rstr = base62.encode(int(datetime.now().timestamp())) param = { 'symbol': sym, 'side': data['side'], 'positionSide': data['positionSide'], 'type': order_type, 'quantity': qty, 'newClientOrderId': f"{app}_{data['op']}_{rstr}", } if order_type == 'LIMIT': param['price'] = price param['timeInForce'] = 'GTC' res = brkrs.place_order(an, param) if res['orderId']: op_ch = get_op(data['op']) Lgr.log(data['op'], f"账户:{an} {op_ch}: {param}") else: Lgr.log('ERROR', 'place order has error')
def cancel_porder(self, acct_name, param): brkr = self.brokers[acct_name] try: return brkr.fapiPrivate_delete_order(param) except Exception as e: Lgr.log('ERROR', e)
def fetch_symbol_price(self, symbol): try: return self._bn.fapiPublic_get_ticker_price({'symbol': symbol}) except Exception as e: Lgr.log('ERROR', f"fetch price err:{e}")
sg.B('打印余额',size=(8,1),font=sml_font,key='print_bal'), sg.Text(' ',font=sml_font), sg.B('打印仓位',size=(8,1),font=sml_font,key='print_pos'), sg.Text(' ',font=sml_font), sg.B('仓位&杠杆',size=(9,1),font=sml_font,key='print_lev'), sg.Text(' ',font=sml_font), sg.B('打印挂单',size=(8,1),font=sml_font,key='print_porders'), sg.Text(' ',font=sml_font), sg.B('打印已成交单',size=(10,1),font=sml_font,key='print_forders') ], [sg.Text(' ',font=sml_font)] ] #################################################################################### # 主线程循环 Lgr.log('status', f"version: {Settings['v']}") output.print_bal() output.print_pos() output.print_lev() window = sg.Window('超级下单王', layout) while True: event, values = window.read() ########## print info ######### if event == 'print_bal': output.print_bal() if event == 'print_pos': output.print_pos() if event == 'print_lev': output.print_pos() output.print_lev() if event == 'print_porders':
def print_bal(self): brkrs.fetch_all_equ() Lgr.log('status', f"账户资金: {brkrs.all_equ}") print( '-------------------------------------------------------------------------------' )