def run(self): """ ˜ Botを起動する関数。 """ logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") if self.hyperopt: logger.info(f"Bot Mode : Hyperopt") self.params_search() return elif self.stub_test: logger.info(f"Bot Mode : Stub") self.exchange = BitMexStub() elif self.back_test: logger.info(f"Bot Mode : Back test") self.exchange = BitMexBackTest() else: logger.info(f"Bot Mode : Trade") self.exchange = BitMex(demo=self.test_net) self.exchange.ohlcv_len = self.ohlcv_len() self.exchange.on_update(self.bin_size, self.strategy) self.exchange.show_result()
def objective(args): logger.info(f"Params : {args}") try: if self.exchange_arg == "bitmex": self.params = args self.exchange = BitMexBackTest(account=self.account, pair=self.pair) self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit/self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = { 'status': STATUS_OK, 'loss': 1/profit_factor } if self.exchange_arg == 'binance': self.params = args self.exchange = BinanceFuturesBackTest(account=self.account, pair=self.pair) self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit/self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = { 'status': STATUS_OK, 'loss': 1/profit_factor } except Exception as e: ret = { 'status': STATUS_FAIL } return ret
def autorelay_download_save(conn, table, bin_size, ohlcv_len, append): cur = conn.cursor() startd = time.time() bitmex = BitMex(threading=True) sql = str("select ROWID, * from '%s_%s' order by ROWID desc limit 1" % (table, bin_size)) cur.execute(sql) item_list = cur.fetchall() end_time = datetime.now(timezone.utc) start_time = end_time - ohlcv_len * delta(bin_size) # 데이터가 있으면 릴레이 다운로드 자동으로 기간설정 if item_list: lasttime = item_list[0][1] # print(lasttime) # print(lasttime[0:16]) last_time = datetime.strptime(lasttime[0:16], '%Y-%m-%d %H:%M') start_time = last_time + timedelta(minutes=1) else: # 데이터가 없으면, print('No data and will start from ', start_time) pass # print('start_time:', start_time) # print('end_time:', end_time) # relay download 디폴트 기간 설정만큼 다운로드 한다. df = bitmex.fetch_ohlcv(bin_size, start_time, end_time) print('download_df_ohlcv time: ', time.time() - startd) # insert to database df.to_sql(table+'_'+bin_size, conn, if_exists=append) show_table(conn, table, bin_size, 1)
def run(self): """ ˜ Bot 기동 """ if self.hyperopt: logger.info(f"Bot Mode : Hyperopt") self.params_search() return elif self.stub_test: logger.info(f"Bot Mode : Stub") self.exchange = BitMexStub() elif self.back_test: logger.info(f"Bot Mode : Back test") self.exchange = BitMexBackTest() else: logger.info(f"Bot Mode : Trade") self.exchange = BitMex(demo=self.test_net) self.exchange.ohlcv_len = self.ohlcv_len() self.exchange.on_update(self.bin_size, self.strategy) logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") logger.info(f"Resolution : {self.resolution()}") logger.info(f"Balance : {self.exchange.get_balance()}") notify(f"Starting Bot\n" f"Strategy : {type(self).__name__}\n" f"Resolution : {self.resolution()}\n" f"Balance : {self.exchange.get_balance()/100000000} XBT") self.exchange.show_result()
def __init__(self, account, pair, threading=True): """ constructor :account: :pair: :param threading: """ self.pair = pair BitMex.__init__(self, account, pair, threading=threading)
def test_fetch_ohlcv_11m(self): ohlcv_len = 100 bin_size = '11m' bitmex = BitMex(threading=False) end_time = datetime.now(timezone.utc) start_time = end_time - ohlcv_len * delta(bin_size) d1 = bitmex.fetch_ohlcv(bin_size, start_time, end_time) print(f"{d1}")
def on_update(self, bin_size, strategy): """ Register function of strategy. :param strategy: """ def __override_strategy(open, close, high, low, volume): new_open_orders = [] if self.get_position_size() > 0 and low[-1] > self.get_trail_price( ): self.set_trail_price(low[-1]) if self.get_position_size( ) < 0 and high[-1] < self.get_trail_price(): self.set_trail_price(high[-1]) for _, order in enumerate(self.open_orders): id = order["id"] long = order["long"] qty = order["qty"] limit = order["limit"] stop = order["stop"] post_only = order["post_only"] if limit > 0 and stop > 0: if (long and high[-1] > stop and close[-1] < limit) or ( not long and low[-1] < stop and close[-1] > limit): self.commit(id, long, qty, limit, False) continue elif (long and high[-1] > stop) or (not long and low[-1] < stop): new_open_orders.append({ "id": id, "long": long, "qty": qty, "limit": limit, "stop": 0 }) continue elif limit > 0: if (long and low[-1] < limit) or (not long and high[-1] > limit): self.commit(id, long, qty, limit, False) continue elif stop > 0: if (long and high[-1] > stop) or (not long and low[-1] < stop): self.commit(id, long, qty, stop, False) continue new_open_orders.append(order) self.open_orders = new_open_orders strategy(open, close, high, low, volume) self.eval_exit() BitMex.on_update(self, bin_size, __override_strategy)
def test_fetch_ohlcv_1m(mins): ''' source => DataFrame Type ------------------------------------------------------------------ open high low close volume 2019-06-15 14:29:00+00:00 8669.5 8670.0 8667.0 8667.0 1454667 2019-06-15 14:30:00+00:00 8667.0 8667.5 8667.0 8667.5 424940 :return: ''' # bitmex = BitMex(threading=False) bitmex = BitMex(threading=True) end_time = datetime.now(timezone.utc) start_time = end_time - 1 * timedelta(minutes=mins) source = bitmex.fetch_ohlcv('1m', start_time, end_time) return source
def run(self): if self.hyperopt: raise Exception( "Trading View Strategy dose not support hyperopt Mode.") elif self.back_test: raise Exception( "Trading View Strategy dose not support backtest Mode.") elif self.stub_test: self.exchange = BitMexStub() logger.info(f"Bot Mode : Stub") else: self.exchange = BitMex(demo=self.test_net) logger.info(f"Bot Mode : Trade") logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") logger.info(f"Resolution : {self.resolution()}") logger.info(f"Balance : {self.exchange.get_balance()}") notify(f"Starting Bot\n" f"Strategy : {type(self).__name__}\n" f"Resolution : {self.resolution()}\n" f"Balance : {self.exchange.get_balance()/100000000} XBT") self.subscriber.on_message(self.__on_message)
def run(self): if self.hyperopt: raise Exception( "Trading View Strategy dose not support hyperopt Mode.") elif self.back_test: raise Exception( "Trading View Strategy dose not support backtest Mode.") elif self.stub_test: # if you want to use binance futures # self.exchange = BinanceFuturesStub(account=self.account, pair=self.pair) self.exchange = BitMexStub(account=self.account, pair=self.pair) logger.info(f"Bot Mode : Stub") else: # if you want to use binance #self.exchange = BinanceFutures(account=self.account, pair=self.pair, demo=self.test_net) self.exchange = BitMex(account=self.account, pair=self.pair, demo=self.test_net) logger.info(f"Bot Mode : Trade") logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") logger.info(f"Balance : {self.exchange.get_balance()}") notify(f"Starting Bot\n" f"Strategy : {type(self).__name__}\n" f"Balance : {self.exchange.get_balance()/100000000} XBT") self.subscriber.on_message(self.__on_message)
def download_df_ohlcv(bin_size, ohlcv_len, **kwargs): ''' df => DataFrame Type ------------------------------------------------------------------ open high low close volume 2019-06-15 14:29:00+00:00 8669.5 8670.0 8667.0 8667.0 1454667 2019-06-15 14:30:00+00:00 8667.0 8667.5 8667.0 8667.5 424940 :return: ''' print('download data from server') start = time.time() # bitmex = BitMex(threading=False) bitmex = BitMex(threading=True) end_time = datetime.now(timezone.utc) start_time = end_time - ohlcv_len * delta(bin_size) df = bitmex.fetch_ohlcv(bin_size, start_time, end_time) print('download_df_ohlcv time:', time.time() - start) return df
def objective(args): logger.info(f"Params : {args}") try: self.params = args self.exchange = BitMexBackTest() self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit / self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = {'status': STATUS_OK, 'loss': 1 / profit_factor} except Exception as e: ret = {'status': STATUS_FAIL} return ret
def run(self): """ ˜ Function to run the bot """ if self.hyperopt: logger.info(f"Bot Mode : Hyperopt") self.params_search() return elif self.stub_test: logger.info(f"Bot Mode : Stub") if self.exchange_arg == "binance": self.exchange = BinanceFuturesStub(account=self.account, pair=self.pair) elif self.exchange_arg == "bitmex": self.exchange = BitMexStub(account=self.account, pair=self.pair) else: logger.info(f"--exchange argument missing or invalid") return elif self.back_test: logger.info(f"Bot Mode : Back test") if self.exchange_arg == "binance": self.exchange = BinanceFuturesBackTest(account=self.account, pair=self.pair) elif self.exchange_arg == "bitmex": self.exchange = BitMexBackTest(account=self.account, pair=self.pair) else: logger.info(f"--exchange argument missing or invalid") return else: logger.info(f"Bot Mode : Trade") if self.exchange_arg == "binance": self.exchange = BinanceFutures(account=self.account, pair=self.pair, demo=self.test_net) elif self.exchange_arg == "bitmex": self.exchange = BitMex(account=self.account, pair=self.pair, demo=self.test_net) else: logger.info(f"--exchange argument missing or invalid") return self.exchange.ohlcv_len = self.ohlcv_len() self.exchange.on_update(self.bin_size, self.strategy) logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") logger.info(f"Balance : {self.exchange.get_balance()}") notify(f"Starting Bot\n" f"Strategy : {type(self).__name__}\n" f"Balance : {self.exchange.get_balance()}") self.exchange.show_result()
def test_entry_cancel(self): bitmex = BitMex() bitmex.demo = False # 전처리 모든 포지션 시장가 해제 # bitmex.close_all() price = bitmex.get_market_price() id = "Long" # bitmex.entry(id, True, 1, limit=price) get_position_size = bitmex.get_position_size() print('get_position_size: %s' % get_position_size) get_position_avg_price = bitmex.get_position_avg_price() print('get_position_avg_price: %s' % get_position_avg_price) get_position = bitmex.get_position() print('get_position: %s' % get_position) get_margin = bitmex.get_margin() print('get_margin: %s' % get_margin)
def run_loop(): while True: sys.stdout.write("-----\n") sys.stdout.flush() try: logging.info("Starting up trader...") logging.info('Symbol: ' + symbol) # initialize first kalman row if it doesn't exist try: KalmanTbl.get() except peewee.DoesNotExist: logging.info("Initializing first kalman row.") KalmanTbl.create(ts=int(time.time() * 1000), C=0, V=0, e=0, yhat=0, m=0, Q=0, K=0, P=0, R=0, Ve=0, max_vol=0) Util.update_balances(client, symbol) # TODO: Use is_time_horizon() to guarantee optimal kalman times for a given pair # if Util.is_time_horizon(launchtime, freq = datetime.timedelta(hours=4)): k = Kalman() kalman_mean, Q = k.kalman(symbol, client) # else: # print('Not updating () for this time: '.format(symbol), launchtime) # kalman_mean, Q = None, None # Pull/Write Orderbooks try: df_buy, df_sell = BitMex.pull_bitmex_orderbooks(symbol, 30) except: start_ts = time.time() req_log = [ start_ts, start_ts, start_ts, sys.exc_info(), symbol, 'orders fail' ] logging.info(req_log) # Trade logic # Execute trade as long as order books are passed on if ((df_buy is not None) and (kalman_mean is not None)): try: # TODO: use time horizon # if Util.is_time_horizon(launchtime, freq = datetime.timedelta(hours=4)): logic = Logic(symbol=symbol, client=client, m=kalman_mean, Q=Q, trade_alloc=40.0, mode='live', df_buy=df_buy, df_sell=df_sell) logic.trade_logic() # else: # logging.info('Not trading {} for this time: '.format(symbol) + str(launchtime)) except Exception as e: logging.error(e) else: logging.info( 'Cannot trade. kalman_mean = {}'.format(kalman_mean)) ## TODO: we should log and store dealt orders to DB # Script loop success log end_ts = time.time() req_log = [ s_ts, int(end_ts), int(end_ts), 'Success', 'all_kucoin', 'Full Script Run' ] logging.info(req_log) logging.info('SUCCESS - Done in {}'.format(end_ts - s_ts)) time.sleep(30) except: logging.error('Failed: ' + str(sys.exc_info())) end_ts = time.time() req_log = [ s_ts, end_ts, end_ts, 'Fail', 'all_kucoin', 'Script fail' ] logging.info(req_log) sys.exit()
def __init__(self, threading=True): """ コンストラクタ :param threading: """ BitMex.__init__(self, threading=threading)
class Bot: # Parameters params = {} # Account account = None # Exchange exchange_arg = None # Time Frame bin_size = '1h' # Pair pair = 'BTCUSDT' # periods periods = 20 # run on test net? test_net = False # Back test? back_test = False # Stub Test? stub_test = False # parameter search? hyperopt = False def __init__(self, bin_size): """ constructor :param bin_size: time_frame :param periods: period """ self.bin_size = bin_size def options(self): """ Function to obtain value for searching for a parameter. """ pass def ohlcv_len(self): """ The length of the OHLC to the strategy """ return 100 def input(self, title, type, defval): """ function to get param :param title: title of the parm :param defval: default value :return value """ p = {} if self.params is None else self.params if title in p: return type(p[title]) else: return defval def strategy(self, open, close, high, low, volume): """ Strategy function, when creating a bot please inherit this and implement this fn. :param open: open price :param close: close price :param high: high price :param low: low price :param volume: volume """ pass def params_search(self): """ ˜ function to search params """ def objective(args): logger.info(f"Params : {args}") try: if self.exchange_arg == "bitmex": self.params = args self.exchange = BitMexBackTest(account=self.account, pair=self.pair) self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit/self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = { 'status': STATUS_OK, 'loss': 1/profit_factor } if self.exchange_arg == 'binance': self.params = args self.exchange = BinanceFuturesBackTest(account=self.account, pair=self.pair) self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit/self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = { 'status': STATUS_OK, 'loss': 1/profit_factor } except Exception as e: ret = { 'status': STATUS_FAIL } return ret trials = Trials() best_params = fmin(objective, self.options(), algo=tpe.suggest, trials=trials, max_evals=200) logger.info(f"Best params is {best_params}") logger.info(f"Best profit factor is {1/trials.best_trial['result']['loss']}") def run(self): """ ˜ Function to run the bot """ if self.hyperopt: logger.info(f"Bot Mode : Hyperopt") self.params_search() return elif self.stub_test: logger.info(f"Bot Mode : Stub") if self.exchange_arg == "binance": self.exchange = BinanceFuturesStub(account=self.account, pair=self.pair) elif self.exchange_arg == "bitmex": self.exchange = BitMexStub(account=self.account, pair=self.pair) else: logger.info(f"--exchange argument missing or invalid") return elif self.back_test: logger.info(f"Bot Mode : Back test") if self.exchange_arg == "binance": self.exchange = BinanceFuturesBackTest(account=self.account, pair=self.pair) elif self.exchange_arg == "bitmex": self.exchange = BitMexBackTest(account=self.account, pair=self.pair) else: logger.info(f"--exchange argument missing or invalid") return else: logger.info(f"Bot Mode : Trade") if self.exchange_arg == "binance": self.exchange = BinanceFutures(account=self.account, pair=self.pair, demo=self.test_net) elif self.exchange_arg == "bitmex": self.exchange = BitMex(account=self.account, pair=self.pair, demo=self.test_net) else: logger.info(f"--exchange argument missing or invalid") return self.exchange.ohlcv_len = self.ohlcv_len() self.exchange.on_update(self.bin_size, self.strategy) logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") logger.info(f"Balance : {self.exchange.get_balance()}") notify(f"Starting Bot\n" f"Strategy : {type(self).__name__}\n" f"Balance : {self.exchange.get_balance()}") self.exchange.show_result() def stop(self): """ ˜ Function that stops the bot and cancel all trades. """ if self.exchange is None: return logger.info(f"Stopping Bot") self.exchange.stop() self.exchange.cancel_all() sys.exit()
class Bot: # パラメータ params = {} # 取引所 exchange = None # 時間足 bin_size = '1h' # 足の期間 periods = 20 # テストネットを利用するか test_net = False # バックテストか back_test = False # スタブ取引か stub_test = False # パラメータ探索か hyperopt = False def __init__(self, bin_size): """ コンストラクタ。 :param bin_size: 時間足 :param periods: 期間 """ self.bin_size = bin_size def options(self): """ パレメータ探索用の値を取得する関数。 """ pass def ohlcv_len(self): """ 戦略にわたすOHLCの長さ """ return 100 def input(self, title, type, defval): """ パレメータを取得する関数。 :param title: パレメータ名 :param defval: デフォルト値 :return: 値 """ p = {} if self.params is None else self.params if title in p: return type(p[title]) else: return defval def strategy(self, open, close, high, low): """ 戦略関数。Botを作成する際は、この関数を継承して実装してください。 :param open: 始値 :param close: 終値 :param high: 高値 :param low: 安値 """ pass def params_search(self): """ ˜ パラメータ検索を行う関数。 """ def objective(args): logger.info(f"Params : {args}") try: self.params = args self.exchange = BitMexBackTest() self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit / self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = {'status': STATUS_OK, 'loss': 1 / profit_factor} except Exception as e: ret = {'status': STATUS_FAIL} return ret trials = Trials() best_params = fmin(objective, self.options(), algo=tpe.suggest, trials=trials, max_evals=200) logger.info(f"Best params is {best_params}") logger.info( f"Best profit factor is {1/trials.best_trial['result']['loss']}") def run(self): """ ˜ Botを起動する関数。 """ logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") if self.hyperopt: logger.info(f"Bot Mode : Hyperopt") self.params_search() return elif self.stub_test: logger.info(f"Bot Mode : Stub") self.exchange = BitMexStub() elif self.back_test: logger.info(f"Bot Mode : Back test") self.exchange = BitMexBackTest() else: logger.info(f"Bot Mode : Trade") self.exchange = BitMex(demo=self.test_net) self.exchange.ohlcv_len = self.ohlcv_len() self.exchange.on_update(self.bin_size, self.strategy) self.exchange.show_result() def stop(self): """ ˜ Botを停止する関数。Openしている注文は、キャンセルする。 """ if self.exchange is None: return logger.info(f"Stopping Bot") self.exchange.stop() self.exchange.cancel_all() sys.exit()
def __init__(self, threading=True): """ 컨스트럭터 :param threading: """ BitMex.__init__(self, threading=threading)
class Bot: # 파라메타 params = {} # 거래소 exchange = None # 봉단위 bin_size = '1h' # 봉기간 periods = 20 # ohlcv = 1440 ohlcv = 8000 # 테스트넷 옵션 test_net = False # 벡테스트 옵션 back_test = False # 스터브 옵션 stub_test = False # 하이퍼 옵션 hyperopt = False def __init__(self, bin_size): """ 컨스트럭터 :param bin_size: 봉단위 :param periods: 봉기간 """ self.bin_size = bin_size def options(self): """ 하이퍼옵션 파라메타탐색 값 취득 함수 """ pass def resolution(self): """ 봉기간 사이즈 """ return self.bin_size def ohlcv_len(self): """ strategy 전략함수에 넘기는 OHLC 길이 """ # return 100 return self.ohlcv def input(self, title, type, defval): """ 하이퍼옵션에 넘겨지는 파라메타 및 속성설정 :param title: 파라메타명 :param defval: 디폴트값 :return: 値 """ p = {} if self.params is None else self.params if title in p: return type(p[title]) else: return defval def strategy(self, open, close, high, low, volume): """ 전략함수로 봇을 작성할때 이 함수를 오버라이드해서 사용 :param open: 시가 :param close: 종가 :param high: 고가 :param low: 저가 :param volume: 거래량 """ pass def params_search(self): """ ˜ 파라메타 탐색 함수 """ def objective(args): logger.info(f"Params : {args}") try: self.params = args self.exchange = BitMexBackTest() self.exchange.on_update(self.bin_size, self.strategy) profit_factor = self.exchange.win_profit / self.exchange.lose_loss logger.info(f"Profit Factor : {profit_factor}") ret = {'status': STATUS_OK, 'loss': 1 / profit_factor} except Exception as e: ret = {'status': STATUS_FAIL} return ret trials = Trials() best_params = fmin(objective, self.options(), algo=tpe.suggest, trials=trials, max_evals=200) logger.info(f"Best params is {best_params}") logger.info( f"Best profit factor is {1/trials.best_trial['result']['loss']}") def run(self): """ ˜ Bot 기동 """ if self.hyperopt: logger.info(f"Bot Mode : Hyperopt") self.params_search() return elif self.stub_test: logger.info(f"Bot Mode : Stub") self.exchange = BitMexStub() elif self.back_test: logger.info(f"Bot Mode : Back test") self.exchange = BitMexBackTest() else: logger.info(f"Bot Mode : Trade") self.exchange = BitMex(demo=self.test_net) self.exchange.ohlcv_len = self.ohlcv_len() self.exchange.on_update(self.bin_size, self.strategy) logger.info(f"Starting Bot") logger.info(f"Strategy : {type(self).__name__}") logger.info(f"Resolution : {self.resolution()}") logger.info(f"Balance : {self.exchange.get_balance()}") notify(f"Starting Bot\n" f"Strategy : {type(self).__name__}\n" f"Resolution : {self.resolution()}\n" f"Balance : {self.exchange.get_balance()/100000000} XBT") self.exchange.show_result() def stop(self): """ ˜ Bot 정지 및 Open되어 있는 주문을 취소 """ if self.exchange is None: return logger.info(f"Stopping Bot") self.exchange.stop() self.exchange.cancel_all() sys.exit()
def strategy(self, open, close, high, low, volume): lot = self.exchange.get_lot() # for test lot lot = int(round(lot / 50)) bitmex = BitMex(threading=False) price = bitmex.get_market_price() # variants settings rsi2_len = self.input('length', int, 2) rsi50_len = self.input('length', int, 50) rsi2 = rsi(close, rsi2_len) rsi50 = rsi(close, rsi50_len) factor = self.input('factor', int, 20) period = self.input('period', int, 7) resolution = self.input(defval=1, title="resolution", type=int) # defval 변경, 예) 5분 --> 5 source = self.exchange.security(str(resolution) + 'm') # def __init__ 비교 supertrenddf = supertrend(source, factor, period) fast_len = self.input('fast_len', int, 5) half_len = self.input('half_len', int, 5) slow_len = self.input('slow_len', int, 200) fast_sma = sma(close, fast_len) half_sma = sma(close, half_len) slow_sma = sma(close, slow_len) # conditions sma_long = over(fast_sma[-1], slow_sma[-1]) sma_short = under(fast_sma[-1], slow_sma[-1]) super_long = over(close[-1], supertrenddf['TSL'][-1]) super_short = under(close[-1], supertrenddf['TSL'][-1]) super_stoploss = supertrenddf['TSL'][-1] supertrendtrend = supertrenddf['Trend'][-1] rsi2_overbought = over(rsi2[-1], 95) rsi2_oversold = under(rsi2[-1], 5) rsi50_over = over(rsi50[-1], 50) rsi50_under = under(rsi50[-1], 50) price_under = under(price, half_sma[-1]) price_over = over(price, half_sma[-1]) half_before = over(close[-1], half_sma[-1]) half_after = under(close[-1], half_sma[-1]) # show infomations logger.info('price: %s' % price) logger.info('fast_sma[-1]: %s' % fast_sma[-1]) logger.info('slow_sma[-1]: %s' % slow_sma[-1]) logger.info('sma_long: %s' % sma_long) logger.info('sma_short: %s' % sma_short) logger.info('super_long: %s' % super_long) logger.info('super_short: %s' % super_short) logger.info('super_stoploss: %s' % super_stoploss) logger.info('sma_trend: %s' % supertrendtrend) logger.info('rsi2[-1 ]%s' % rsi2[-1]) logger.info('rsi50[-1 ]%s' % rsi50[-1]) logger.info('rsi2_oversold: %s' % rsi2_oversold) logger.info('rsi2_overbought: %s' % rsi2_overbought) logger.info('price_under: %s' % price_under) logger.info('price_over: %s' % price_over) logger.info('half_before: %s' % half_before) logger.info('half_after: %s' % half_after) logger.info('get_whichpositon(): %s' % bitmex.get_whichpositon()) logger.info('position_size(): %s' % bitmex.get_position_size()) # entry if super_long: #long trend logger.info( '+ + + + + LONG + + + + + LONG + + + + + LONG + + + + + ') if bitmex.get_whichpositon() is None: if sma_long and rsi2_oversold or price_under: logger.info( 'postion condition > None > and all short condition order' ) self.exchange.entry("Long", True, lot, limit=price - 0.5, post_only=True) else: logger.info( 'postion condition > None > default long order') self.exchange.entry("Long", True, lot, limit=math.ceil(super_stoploss), post_only=True) elif bitmex.get_whichpositon() == 'LONG': logger.info('postion condition > LONG') if price_over: # closing logger.info('postion condition > LONG > Closing') self.exchange.order("Long", False, abs(bitmex.get_position_size()), limit=price + 1.5, post_only=True) elif rsi2_overbought: # add more entry logger.info( 'postion condition > LONG > Rsi2 overbougt add more entry' ) self.exchange.entry("LongAdd", True, lot, limit=price - 0.5, post_only=True) elif super_short: # stop loss logger.info( 'postion condition > LONG > super_short(stop loss)') self.exchange.entry("Long", True, lot) self.exchange.entry("LongAdd", True, lot) elif bitmex.get_whichpositon() == 'SHORT': logger.info('cancel SHORT on long trend') # self.exchange.cancel_all() self.exchange.close_all() else: # self.exchange.cancel_all() logger.info('Super Long --> Else') if super_short: # short trend logger.info( '- - - - - SHORT - - - - - SHORT - - - - - SHORT - - - - - ') if bitmex.get_whichpositon() is None: if sma_short and rsi2_overbought or price_over: logger.info( 'postion condition > None > and all short condition order' ) self.exchange.entry("Short", False, lot, limit=price + 0.5, post_only=True) else: logger.info( 'postion condition > None > default short order') self.exchange.entry("Short", False, lot, limit=math.floor(super_stoploss), post_only=True) elif bitmex.get_whichpositon() == 'SHORT': logger.info('postion condition > SHORT') if price_under: # closing logger.info( 'postion condition > SHORT > price_under(closing)') self.exchange.order("Short", True, abs(bitmex.get_position_size()), limit=price - 1.5, post_only=True) elif rsi2_oversold: # add more entry logger.info( 'postion condition > SHORT > rsi2_oversold(add more entry)' ) self.exchange.entry("ShortAdd", False, lot, limit=price - 0.5, post_only=True) elif super_long: # stop loss logger.info( 'postion condition > SHORT > super_short(stop loss)') self.exchange.entry("Short", True, lot) self.exchange.entry("ShortAdd", True, lot) elif bitmex.get_whichpositon() == 'LONG': logger.info('cancel LONG on short trend') self.exchange.close_all() else: logger.info('Super Shot --> Else') self.dealcount += 1 diff = (abs(bitmex.get_balance() - abs(self.prebalance))) realised_pnl = bitmex.get_margin()['realisedPnl'] logger.info('dealcount:%s' % self.dealcount) logger.info('prebalance():%s' % self.prebalance) logger.info('bitmex.get_balance():%s' % bitmex.get_balance()) logger.info('diff:%s' % diff) logger.info('realised_pnl:%s' % realised_pnl) logger.info('--------------------------------------------------')
def strategy(self, open, close, high, low, volume): self.start += 1 lot = self.exchange.get_lot() # for test lot lot = int(round(lot / 10)) bitmex = BitMex(threading=False) price = bitmex.get_market_price() sma_base_l = self.input('sma_short_len', int, 200) resolution = self.input( defval=1, title="resolution", type=int ) # defval 변경, 예) 5분 --> 5, 'm' or 1시간 1, 'h', 1Day 1, 'd' source = self.exchange.security(str(resolution) + 'h') # def __init__ 비교 logger.info('source: %s' % source) series_high = source['high'].values series_low = source['low'].values fb100 = last(highest(series_high, 1)) # 1시간 1, 1D의 경우는 resolution도 변경 fb0 = last(lowest(series_low, 1)) logger.info('resolution: %s' % resolution) logger.info('fb100_resol: %s' % fb100) logger.info('fb0_resol: %s' % fb0) # for test # fb100 = price + 15 # fb0 = price - 15 # 최근 1시간을 본봉단위로 획득 # fibo_l = self.input('length', int, 1440) # 1Day = 60min * 24hr # fibo_l = self.input('length', int, 60) # 1Day = 60min * 24hr # fibo100 = last(highest(high, fibo_l)) # fibo0 = last(lowest(low, fibo_l)) fb62 = math.ceil((fb100 - fb0) * 0.618 + fb0) fb38 = math.ceil((fb100 - fb0) * 0.382 + fb0) fb50 = math.ceil((fb100 - fb0) / 2 + fb0) fb200 = math.ceil((fb100 - fb0) * 1.0 + fb100) fb162 = math.ceil((fb100 - fb0) * 0.618 + fb100) fb138 = math.ceil((fb100 - fb0) * 0.382 + fb100) fb038 = math.ceil(fb0 - (fb100 - fb0) * 0.382) fb062 = math.ceil(fb0 - (fb100 - fb0) * 0.618) fb0100 = math.ceil(fb0 - (fb100 - fb0) * 1.00) logger.info('self.start: %s' % self.start) if self.start == 1: # short position self.exchange.order("Short200", False, lot * 3, limit=fb200, post_only=True) self.exchange.order("Short162", False, lot * 2, limit=fb162, post_only=True) self.exchange.order("Short138", False, lot * 1, limit=fb138, post_only=True) self.exchange.order("Short100", False, lot * 1, limit=fb100, post_only=True) # long position self.exchange.order("Long0", True, lot * 1, limit=fb0, post_only=True) self.exchange.order("Long038", True, lot * 1, limit=fb038, post_only=True) self.exchange.order("Long062", True, lot * 2, limit=fb062, post_only=True) self.exchange.order("Long0100", True, lot * 3, limit=fb0100, post_only=True) Long0 = bitmex.get_open_order("Long0") Long038 = bitmex.get_open_order("Long038") Long062 = bitmex.get_open_order("Long062") Long0100 = bitmex.get_open_order("Long0100") Short200 = bitmex.get_open_order("Short200") Short162 = bitmex.get_open_order("Short162") Short138 = bitmex.get_open_order("Short138") Short100 = bitmex.get_open_order("Short100") # # # logger.info('Long0: %s' % Long0) # logger.info('Long038: %s' % Long038) # logger.info('Long062: %s' % Long062) # logger.info('Long0100: %s' % Long0100) # logger.info('Short200: %s' % Short200) # logger.info('Short162: %s' % Short162) # logger.info('Short138: %s' % Short138) # logger.info('Short100: %s' % Short100) # # logger.info('(Long0 is None): %s' % (Long0 is None)) # entry order # long position self.exchange.order("Long0", True, lot * 1, limit=fb0, when=(Long0 is None), post_only=True) self.exchange.order("Long038", True, lot * 1, limit=fb038, when=(Long038 is None), post_only=True) self.exchange.order("Long062", True, lot * 2, limit=fb062, when=(Long0100 is None), post_only=True) self.exchange.order("Long0100", True, lot * 3, limit=fb0100, when=(Long0100 is None), post_only=True) # short position self.exchange.order("Short200", False, lot * 3, limit=fb200, when=(Short200 is None), post_only=True) self.exchange.order("Short162", False, lot * 2, limit=fb162, when=(Short162 is None), post_only=True) self.exchange.order("Short138", False, lot * 1, limit=fb138, when=(Short138 is None), post_only=True) self.exchange.order("Short100", False, lot * 1, limit=fb100, when=(Short100 is None), post_only=True) # win order if price <= fb0: self.exchange.order("Long0_w", False, lot * 1, limit=fb38, stop=fb0) logger.info('rice <= fb0: %s' % fb0) if price <= fb038: self.exchange.order("Long038_w", False, lot * 1, limit=fb0, stop=fb038) if price <= fb062: self.exchange.order("Long062_w", False, lot * 2, limit=fb038, stop=fb062) if price <= fb0100: self.exchange.order("Long0100_w", False, lot * 3, limit=fb062, stop=fb0100) if price >= fb100: logger.info('price >= fb100: %s' % fb100) self.exchange.order("Short100_w", True, lot * 1, limit=fb62, stop=fb100) if price >= fb138: self.exchange.order("Short138_w", True, lot * 1, limit=fb100, stop=fb138) if price >= fb162: self.exchange.order("Short162_w", True, lot * 2, limit=fb138, stop=fb162) if price >= fb200: self.exchange.order("Short200_w", True, lot * 3, limit=fb162, stop=fb200) # logger.info('bitmex.get_margin():%s' % bitmex.get_margin()) # logger.info('bitmex.get_position():%s' % bitmex.get_position()) # for debug # logger.info('fb200: %s' % fb200) # logger.info('fb162: %s' % fb162) # logger.info('fb138: %s' % fb138) # logger.info('fb100: %s' % fb100) # logger.info('fb62: %s' % fb62) # logger.info('fb50: %s' % fb50) # logger.info('fb38: %s' % fb38) # logger.info('fb0: %s' % fb0) # logger.info('fb038: %s' % fb038) # logger.info('fb062: %s' % fb062) # logger.info('fb0100: %s' % fb0100) diff = (abs(bitmex.get_balance() - abs(self.prebalance))) realised_pnl = bitmex.get_margin()['realisedPnl'] logger.info('prebalance():%s' % self.prebalance) logger.info('bitmex.get_balance():%s' % bitmex.get_balance()) logger.info('diff:%s' % diff) logger.info('realised_pnl:%s' % realised_pnl) logger.info('--------------------------------------------------')
def test_fetch_ohlc_2h(self): bitmex = BitMex(threading=False) end_time = datetime.now(timezone.utc) start_time = end_time - 5 * timedelta(hours=2) source = bitmex.fetch_ohlcv('2h', start_time, end_time) assert len(source) > 1
def strategy(self, open, close, high, low, volume): lot = self.exchange.get_lot() # for test # lot = int(round(lot / 100)) bitmex = BitMex(threading=False) price = bitmex.get_market_price() factor = self.input('factor', int, 3) period = self.input('period', int, 7) atrvar = atr(high, low, close, period=period) # up = (high + low) / 2 - (factor * atr(high, low, close, period=period)) # logger.info('up:%s\n' % up) # dn = (high + low) / 2 + (factor * atr(high, low, close, period=period)) # logger.info('atrvar: %s' % atrvar[-1]) resolution = self.input(defval=15, title="resolution", type=int) # defval 변경, 예) 5분 --> 5 source = self.exchange.security(str(resolution) + 'm') # init 참고 supertrenddf = supertrend(source, factor, period) # logger.info('supertrend:%s' % supertrenddf.describe()) # logger.info('supertrend:%s' % supertrenddf.columns) logger.info('price:%s\n' % price) # logger.info('source:%s\n' % source[-1]) logger.info('supertrend value:%s' % supertrenddf['SuperTrend'][-1]) logger.info('supertrend Upper Band:%s' % supertrenddf['Upper Band'][-1]) logger.info('supertrend Lower Band:%s' % supertrenddf['Lower Band'][-1]) logger.info('supertrenddf[Trend][-1]:%s' % supertrenddf['Trend'][-1]) logger.info('supertrenddf[TSL][-1]:%s' % supertrenddf['TSL'][-1]) logger.info('supertrenddf[ATR][-1]:%s' % supertrenddf['ATR'][-1]) longCondition_supertrend = crossover( close, supertrenddf['SuperTrend'] ) and close[-1] > supertrenddf['SuperTrend'][-1] shortCondition_supertrend = crossunder( close, supertrenddf['SuperTrend'] ) and close[-1] < supertrenddf['SuperTrend'][-1] if longCondition_supertrend: self.exchange.entry("Long", True, lot) logger.info('longCondition_supertrend:%s\n' % longCondition_supertrend) elif shortCondition_supertrend: self.exchange.entry("Short", False, lot) logger.info('shortCondition_supertrend:%s\n' % shortCondition_supertrend) else: # self.exchange.close_all() logger.info('Condition_supertrend:%s\n' % 'else') self.dealcount += 1 diff = (abs(bitmex.get_balance() - abs(self.prebalance))) realised_pnl = bitmex.get_margin()['realisedPnl'] logger.info('dealcount:%s' % self.dealcount) logger.info('prebalance():%s' % self.prebalance) logger.info('bitmex.get_balance():%s' % bitmex.get_balance()) logger.info('diff:%s' % diff) logger.info('realised_pnl:%s' % realised_pnl) # logger.info('bitmex.get_margin():%s' % bitmex.get_margin()) # logger.info('bitmex.get_position():%s' % bitmex.get_position()) # logger.info('bitmex.get_balance():%s' % bitmex.get_balance()) # logger.info('get_pre_prebalance:%s' % get_pre_prebalance(self.prebalance, bitmex.get_balance())) # # self.exchange.close_all() # # self.exchange.cancel_all() logger.info('--------------------------------------------------')
def test_fetch_ohlcv_5m(self): bitmex = BitMex(threading=False) end_time = datetime.now(timezone.utc) start_time = end_time - 5 * timedelta(minutes=5) source = bitmex.fetch_ohlcv('5m', start_time, end_time) assert len(source) > 1
def __init__(self, threading=True): """ constructor :param threading: """ BitMex.__init__(self, threading=threading)
def test_entry_cancel(self): bitmex = BitMex() bitmex.demo = True # 前処理 bitmex.close_all() price = bitmex.get_market_price() # 注文、キャンセルの試験 id = "Long" bitmex.entry(id, True, 1, limit=price-1000) assert bitmex.get_open_order(id) is not None bitmex.cancel(id) assert bitmex.get_open_order(id) is None # 注文の更新 id = "Long" bitmex.entry(id, True, 1, limit=price-1000) order = bitmex.get_open_order(id) assert order["orderQty"] == 1 assert order["price"] == price-1000 bitmex.entry(id, True, 2, limit=price-900) order = bitmex.get_open_order(id) assert order["orderQty"] == 2 assert order["price"] == price-900 bitmex.cancel(id) assert bitmex.get_open_order(id) is None
def strategy(self, open, close, high, low, volume): lot = self.exchange.get_lot() # for test lot lot = int(round(lot / 50)) bitmex = BitMex(threading=False) price = bitmex.get_market_price() position_avg_price = bitmex.get_position_avg_price() # variants settings rsi2_len = self.input('length', int, 2) rsi50_len = self.input('length50', int, 50) rsi2 = rsi(close, rsi2_len) rsi50 = rsi(close, rsi50_len) factor = self.input('factor', int, 3) period = self.input('period', int, 7) factor2 = self.input('factor2', int, 20) period2 = self.input('period2', int, 7) resolution = self.input(defval=1, title="resolution", type=int) # defval 변경, 예) 5분 --> 5 source = self.exchange.security(str(resolution) + 'm') # def __init__ 비교 supertrenddf = supertrend(source, factor, period) supertrenddf2 = supertrend(source, factor2, period2) print('supertrenddf:%s' % supertrenddf) print('supertrenddf2:%s' % supertrenddf2) fast_len = self.input('fast_len', int, 5) half_len = self.input('half_len', int, 50) slow_len = self.input('slow_len', int, 200) fast_sma = sma(close, fast_len) half_sma = sma(close, half_len) slow_sma = sma(close, slow_len) # conditions sma_long = over(fast_sma[-1], slow_sma[-1]) sma_short = under(fast_sma[-1], slow_sma[-1]) super_long = over(close[-1], supertrenddf['SuperTrend'][-1]) super_short = under(close[-1], supertrenddf['SuperTrend'][-1]) supertrendtrend = supertrenddf['Trend'][-1] super2_long = over(close[-1], supertrenddf2['SuperTrend'][-1]) super2_short = under(close[-1], supertrenddf2['SuperTrend'][-1]) supertrendtrend2 = supertrenddf2['Trend'][-1] super_centerline = (supertrenddf['SuperTrend'][-1] + supertrenddf2['SuperTrend'][-1]) / 2 rsi2_overbought = over(rsi2[-1], 95) rsi2_oversold = under(rsi2[-1], 5) rsi50_over = over(rsi50[-1], 50) rsi50_under = under(rsi50[-1], 50) price_under = under(price, half_sma[-1]) price_over = over(price, half_sma[-1]) half_before = over(close[-1], half_sma[-1]) half_after = under(close[-1], half_sma[-1]) # show infomations logger.info('price: %s' % price) logger.info('fast_sma[-1]: %s' % fast_sma[-1]) logger.info('slow_sma[-1]: %s' % slow_sma[-1]) logger.info('sma_long: %s' % sma_long) logger.info('sma_short: %s' % sma_short) logger.info('super_long: %s' % super_long) logger.info('super_short: %s' % super_short) logger.info('sma_trend: %s\n' % supertrendtrend) logger.info('supertrend value:%s' % supertrenddf['SuperTrend'][-1]) logger.info('supertrend Upper Band:%s' % supertrenddf['Upper Band'][-1]) logger.info('supertrend Lower Band:%s' % supertrenddf['Lower Band'][-1]) logger.info('supertrenddf[Trend][-1]:%s' % supertrenddf['Trend'][-1]) logger.info('supertrenddf[TSL][-1]:%s' % supertrenddf['TSL'][-1]) logger.info('supertrenddf[ATR][-1]:%s\n' % supertrenddf['ATR'][-1]) logger.info('supertrend2 value:%s' % supertrenddf2['SuperTrend'][-1]) logger.info('supertrend2 Upper Band:%s' % supertrenddf2['Upper Band'][-1]) logger.info('supertrend2 Lower Band:%s' % supertrenddf2['Lower Band'][-1]) logger.info('supertrenddf2[Trend][-1]:%s' % supertrenddf2['Trend'][-1]) logger.info('supertrenddf2[TSL][-1]:%s' % supertrenddf2['TSL'][-1]) logger.info('supertrenddf2[ATR][-1]:%s\n' % supertrenddf2['ATR'][-1]) logger.info( 'supertrenddf[SuperTrend][-1]:%s + supertrenddf2[SuperTrend][-1]:%s ' % (supertrenddf['SuperTrend'][-1], supertrenddf2['SuperTrend'][-1])) logger.info('super_centerline: %s' % super_centerline) logger.info('rsi2[-1 ]%s' % rsi2[-1]) logger.info('rsi50[-1 ]%s' % rsi50[-1]) logger.info('rsi2_oversold: %s' % rsi2_oversold) logger.info('rsi2_overbought: %s' % rsi2_overbought) logger.info('price_under: %s' % price_under) logger.info('price_over: %s' % price_over) logger.info('half_before: %s' % half_before) logger.info('half_after: %s' % half_after) logger.info('get_whichpositon(): %s' % bitmex.get_whichpositon()) logger.info('position_size(): %s' % bitmex.get_position_size()) # entry if super2_long: logger.info( '+ + + + + LONG + + + + + LONG + + + + + LONG + + + + + ') if bitmex.get_whichpositon( ) is None: # and (not supertrendtrend and supertrendtrend2) and rsi2_overbought: logger.info('postion condition > None') if bitmex.get_open_order('Short'): self.exchange.cancel('Short') self.exchange.entry("Long", True, lot, limit=math.ceil(super_centerline), post_only=True) elif bitmex.get_whichpositon() == 'LONG': logger.info('postion condition > LONG') if supertrendtrend and supertrendtrend2 and rsi2_oversold: # closing logger.info('postion condition > LONG > Closing') self.exchange.order("Long", False, abs(bitmex.get_position_size()), limit=price + 2.5, post_only=True) elif rsi2_overbought: # add more entry logger.info('postion condition > LONG > Rsi2 overbout') self.exchange.entry("LongAdd", True, lot, limit=price - 0.5, post_only=True) elif super_short: # stop loss logger.info( 'postion condition > LONG > super_short(stop loss)') self.exchange.entry("Long", True, lot) self.exchange.entry("LongAdd", True, lot) else: logger.info('postion condition > LONG > else') self.exchange.order("Long", False, abs(bitmex.get_position_size()), limit=price + 10, post_only=True) elif bitmex.get_whichpositon() == 'SHORT': logger.info('cancel SHORT on long trend') # self.exchange.cancel_all() self.exchange.close_all() self.exchange.close_all() else: logger.info('Super Shot --> Else') if super2_short: logger.info( '- - - - - SHORT - - - - - SHORT - - - - - SHORT - - - - - ') if bitmex.get_whichpositon( ) is None: #and rsi2_overbought and price_over: logger.info('postion condition > None') if bitmex.get_open_order('Long'): self.exchange.cancel('Long') self.exchange.entry("Short", False, lot, limit=math.floor(super_centerline), post_only=True) elif bitmex.get_whichpositon() == 'SHORT': logger.info('postion condition > SHORT') if price_under: # closing logger.info( 'postion condition > SHORT > price_under(closing)') self.exchange.order("Short", True, abs(bitmex.get_position_size()), limit=price - 2.5, when=price_under, post_only=True) elif rsi2_oversold: # add more entry logger.info( 'postion condition > SHORT > rsi2_oversold(add more entry)' ) self.exchange.entry("ShortAdd", False, lot, limit=price - 0.5, post_only=True) elif super_long: # stop loss logger.info( 'postion condition > SHORT > super_short(stop loss)') self.exchange.entry("Short", True, lot) self.exchange.entry("ShortAdd", True, lot) else: logger.info('postion condition > SHORT > else') self.exchange.order("Short", True, abs(bitmex.get_position_size()), limit=price - 10, post_only=True) elif bitmex.get_whichpositon() == 'LONG': logger.info('cancel LONG on short trend') self.exchange.close_all() else: logger.info('Super Shot --> Else') self.dealcount += 1 diff = (abs(bitmex.get_balance() - abs(self.prebalance))) realised_pnl = bitmex.get_margin()['realisedPnl'] logger.info('dealcount:%s' % self.dealcount) logger.info('prebalance():%s' % self.prebalance) logger.info('bitmex.get_balance():%s' % bitmex.get_balance()) logger.info('diff:%s' % diff) logger.info('realised_pnl:%s' % realised_pnl) logger.info('--------------------------------------------------')