基础网格交易策略实现
目前这个不是最优的版本,我自己目前跑的是币安的websocket版本。 如果大家有需要,我再把币安的websocket版本改成适合在发明者上跑的版本。
'''backtest start: 2021-08-01 00:00:00 end: 2021-09-01 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT","balance":1000000,"stocks":0,"fee":[0.06,0.075]}] args: [["lower_price",30000],["upper_price",50000],["grid_num",200],["trading_per_grid",0.1]] ''' grid = dict() interval = 0 class GridItem: def __init__(self, order_id, status, price): self.order_id = order_id self.status = status # -1:此点为空白点; -2:此点未下过单 self.side = 0 # 1:买入;2:卖出;0:未知 self.price = price def create_grid(ticker_price): global grid global interval exchange.SetCurrency(trading_pair) exchange.SetPrecision(price_precision, amount_precision) interval = _N((upper_price - lower_price) / grid_num, price_precision) grid[lower_price] = GridItem(-1, -2, lower_price) grid[upper_price] = GridItem(-1, -2, upper_price) for i in range(1, grid_num): price = lower_price + interval * i grid[price] = GridItem(-1, -2, price) buy_stocks = (grid_num - int((ticker_price - lower_price) / interval) - 1) * trading_per_grid buy_2_sell(buy_stocks) def buy_2_sell(buy_stocks): while True: account = exchange.GetAccount() stocks = _N(account['Stocks'], amount_precision) if stocks < buy_stocks: depth = exchange.GetDepth() price = depth['Asks'][0]['Price'] vol = _N(price * trading_per_grid, price_precision) min_vol = 1.0 / (10 ** price_precision) exchange.Buy(-1, vol if vol > min_vol else min_vol) else: break Sleep(1000) def set_blank(price): grid[price].order_id = -1 grid[price].status = -1 grid[price].side = 0 def update_order(): last_blank_price = -1 close_price_list = set() for grid_item in grid.values(): if grid_item.status == -1: last_blank_price = grid_item.price elif grid_item.status == -2: close_price_list.add(grid_item.price) else: order = exchange.GetOrder(grid_item.order_id) grid_item.status = order["Status"] if grid_item.status == 1: close_price_list.add(grid_item.price) return close_price_list, last_blank_price def remove_blank(close_price_list, last_blank_price): if last_blank_price != -1: close_price_list.discard(last_blank_price) def set_left_blank(close_price_list, left_side_grid, last_blank_price): set_blank(left_side_grid) close_price_list.discard(left_side_grid) if last_blank_price != -1: close_price_list.add(last_blank_price) def set_right_blank(close_price_list, right_side_grid, last_blank_price): set_blank(right_side_grid) close_price_list.discard(right_side_grid) if last_blank_price != -1: close_price_list.add(last_blank_price) def trace(): close_price_list, last_blank_price = update_order() has_buy_order = False for price in close_price_list: if grid[price].side == 1: has_buy_order = True break if has_buy_order: ticker_price = min(close_price_list) - interval / 2.0 else: ticker = exchange.GetTicker() ticker_price = ticker['Last'] if not grid: create_grid(ticker_price) left_side_grid = int((ticker_price - lower_price) / interval) * interval + lower_price right_side_grid = left_side_grid + interval # 设置空白点 # 当前价格左侧未成交,当前价格右侧未成交,不存在 # 当前价格左侧空白点,当前价格右侧空白点,不存在 # 左侧和右侧任何一个为空白点,不需要更新空白点 if left_side_grid >= upper_price or right_side_grid <= lower_price: # 在区间外,不需要空白点 remove_blank(close_price_list, last_blank_price) elif grid[left_side_grid].status == 0 and grid[right_side_grid].status == 1: set_right_blank(close_price_list, right_side_grid, last_blank_price) elif grid[left_side_grid].status == 1 and grid[right_side_grid].status == 0: set_left_blank(close_price_list, left_side_grid, last_blank_price) elif grid[left_side_grid].status == 1 and grid[right_side_grid].status == 1: set_right_blank(close_price_list, right_side_grid, last_blank_price) elif grid[left_side_grid].status == -2 and grid[right_side_grid].status == -2: set_right_blank(close_price_list, right_side_grid, last_blank_price) # 重新下单 for price in close_price_list: if price <= ticker_price: order_id = exchange.Buy(price, trading_per_grid) side = 1 else: buy_2_sell(trading_per_grid) order_id = exchange.Sell(price, trading_per_grid) side = 2 if order_id: grid[price].order_id = order_id grid[price].status = 0 grid[price].side = side def main(): while True: trace() Sleep(1000)
梦想身价八位数 老哥,这个怎么不能运行啊?有错误
tangtang2020 这个可以定制吗
SissiFeng 。。。ZeroDivisionError: float division by zero 把网格设置成6可以,为什么做成20都显示错误呢?
xh5888 这个可以用在okex交易所吗
xl9211 大家使用后,有什么问题可以及时在下面反馈给我。
SissiFeng 可以