improve MM
This commit is contained in:
parent
28c50d053b
commit
0d2b0e425d
38
bitbank.py
38
bitbank.py
@ -13,29 +13,38 @@ import util.ticker
|
||||
PUBLIC_API_ENTRYPOINT = "https://public.bitbank.cc"
|
||||
PRIVATE_API_ENTRYPOINT = "https://api.bitbank.cc/v1"
|
||||
|
||||
ORDER_UNITS = {
|
||||
"btc_jpy": 0.0001,
|
||||
"eth_jpy": 0.0001,
|
||||
}
|
||||
PRICE_UNITS = {
|
||||
"btc_jpy": 1,
|
||||
"eth_jpy": 1,
|
||||
}
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
_k = asyncio.Lock()
|
||||
|
||||
async def init(cli):
|
||||
pair = Pair(cli, "mona_jpy")
|
||||
logic.Hige(
|
||||
logging.getLogger("bitbank/mona/Hige"),
|
||||
pair, 4, 0.2)
|
||||
#pair = Pair(cli, "mona_jpy")
|
||||
#logic.Hige(
|
||||
# logging.getLogger("bitbank/mona/Hige"),
|
||||
# pair, 4, 0.2)
|
||||
|
||||
pair = Pair(cli, "btc_jpy")
|
||||
logic.EMA_Chicken(
|
||||
logging.getLogger("bitbank/btc/EMA_Chicken"),
|
||||
pair, pair.candlestick_1m, 0.001, 0.007)
|
||||
pair, pair.candlestick_1m, 0.001, 0.005)
|
||||
|
||||
pair = Pair(cli, "eth_jpy")
|
||||
logic.MM(
|
||||
logging.getLogger("bitbank/eth/MM"),
|
||||
pair, 0.01, 1)
|
||||
pair, 0.01, 1, 0.15)
|
||||
logic.EMA_Chicken(
|
||||
logging.getLogger("bitbank/eth/EMA_Chicken"),
|
||||
pair, pair.candlestick_1m, 0.01, 0.01)
|
||||
pair, pair.candlestick_1m, 0.01, 0.005)
|
||||
|
||||
|
||||
class Pair(util.pair.Pair):
|
||||
@ -46,14 +55,14 @@ class Pair(util.pair.Pair):
|
||||
|
||||
self.ticker = Ticker(self._store, name)
|
||||
|
||||
self.order_unit = 0.0001
|
||||
self.price_unit = 0.001 # TODO
|
||||
self.order_unit = ORDER_UNITS[name]
|
||||
self.price_unit = PRICE_UNITS[name]
|
||||
|
||||
#self.candlestick_1s = Candlestick(cli, self.ticker, None, 1)
|
||||
self.candlestick_1m = Candlestick(cli, self.ticker, "1min", 60)
|
||||
#self.candlestick_1h = Candlestick(cli, self.ticker, "1hour", 60*60)
|
||||
|
||||
self.depth = Depth(self._store)
|
||||
self.depth = Depth(self._store, self.order_unit)
|
||||
|
||||
asyncio.create_task(cli.ws_connect(
|
||||
'wss://stream.bitbank.cc/socket.io/?EIO=3&transport=websocket',
|
||||
@ -80,7 +89,10 @@ class Pair(util.pair.Pair):
|
||||
res = await self._cli.post(PRIVATE_API_ENTRYPOINT+"/user/spot/order", data=data)
|
||||
res = await res.json()
|
||||
_check_response(res)
|
||||
return Order(self._cli, self, res["data"]["order_id"])
|
||||
order = Order(self._cli, self, res["data"]["order_id"])
|
||||
order.amount = amount
|
||||
order.price = price
|
||||
return order
|
||||
|
||||
def buy_market(self, amount):
|
||||
return self._order(amount, "buy", "market")
|
||||
@ -244,8 +256,8 @@ class Candlestick(util.candlestick.Candlestick):
|
||||
|
||||
|
||||
class Depth(util.depth.Depth):
|
||||
def __init__(self, store):
|
||||
super().__init__()
|
||||
def __init__(self, store, order_unit):
|
||||
super().__init__(order_unit)
|
||||
self._store = store
|
||||
asyncio.create_task(self._main())
|
||||
|
||||
|
76
logic/mm.py
76
logic/mm.py
@ -2,18 +2,20 @@ import asyncio
|
||||
|
||||
|
||||
class MM:
|
||||
def __init__(self, logger, pair, lot, epsilon):
|
||||
def __init__(self, logger, pair, lot, spread_amount, spread_band):
|
||||
self._logger = logger
|
||||
self._pair = pair
|
||||
self._lot = lot
|
||||
self._remain = 0
|
||||
self._epsilon = epsilon
|
||||
|
||||
self._buy_price = None
|
||||
self._sell_price = None
|
||||
self._buy = None
|
||||
self._sell = None
|
||||
|
||||
self._spread_amount = spread_amount
|
||||
self._spread_band = spread_band
|
||||
|
||||
self._total = 0
|
||||
|
||||
asyncio.create_task(self._main())
|
||||
@ -28,24 +30,62 @@ class MM:
|
||||
if len(depth.bids) == 0 or len(depth.asks) == 0:
|
||||
continue
|
||||
|
||||
ask = depth.asks[0][0]
|
||||
bid = depth.bids[0][0]
|
||||
enough_spread = (ask-bid) > self._epsilon*2
|
||||
|
||||
# calculate best amount to buy/sell
|
||||
pos = self._remain / self._lot - 2
|
||||
buy_amount = _quad( pos) * self._lot
|
||||
sell_amount = _quad(-pos) * self._lot
|
||||
|
||||
# calculate ideal spread
|
||||
ask_delta_amount = self._spread_amount * (_quad( pos) + self._spread_band)
|
||||
bid_delta_amount = self._spread_amount * (_quad(-pos) + self._spread_band)
|
||||
|
||||
# calculate best sell price
|
||||
if self._sell is not None and self._sell.done:
|
||||
ask_delta_amount += self._sell.amount
|
||||
ask = 0
|
||||
prev = -1e100
|
||||
for i in range(len(depth.asks)):
|
||||
if (depth.asks[i][0]-prev) > pair.price_unit*1.5:
|
||||
ask = depth.asks[i][0] - pair.price_unit
|
||||
my_order = \
|
||||
self._sell is not None and \
|
||||
not self._sell.done and \
|
||||
abs(self._sell_price-depth.asks[i][0]) < pair.price_unit
|
||||
if my_order:
|
||||
ask_delta_amount -= depth.asks[i][1] - self._sell.amount
|
||||
prev = -1e100
|
||||
else:
|
||||
ask_delta_amount -= depth.asks[i][1]
|
||||
prev = depth.asks[i][0]
|
||||
if ask_delta_amount < 0:
|
||||
break
|
||||
|
||||
# calculate best buy price
|
||||
if self._buy is not None and self._buy.done:
|
||||
bid_delta_amount += self._buy.amount
|
||||
bid = 0
|
||||
prev = 1e100
|
||||
for i in range(len(depth.bids)):
|
||||
if (prev-depth.bids[i][0]) > pair.price_unit*1.5:
|
||||
bid = depth.bids[i][0] + pair.price_unit
|
||||
my_order = \
|
||||
self._buy is not None and \
|
||||
not self._buy.done and \
|
||||
abs(self._buy_price-depth.bids[i][0]) < pair.price_unit
|
||||
if my_order:
|
||||
bid_delta_amount -= depth.bids[i][1] - self._buy.amount
|
||||
prev = 1e100
|
||||
else:
|
||||
bid_delta_amount -= depth.bids[i][1]
|
||||
prev = depth.bids[i][0]
|
||||
if bid_delta_amount < 0:
|
||||
break
|
||||
|
||||
if self._sell is not None:
|
||||
# check current SELL order
|
||||
await asyncio.sleep(0.5)
|
||||
await self._sell.update()
|
||||
|
||||
# get highest ask
|
||||
if ask == self._sell_price and abs(depth.asks[0][1]-self._sell.remain) < pair.price_unit:
|
||||
ask = depth.asks[1][0]
|
||||
|
||||
if self._sell.done:
|
||||
amount = self._sell.amount - self._sell.remain
|
||||
self._remain -= amount
|
||||
@ -54,21 +94,17 @@ class MM:
|
||||
self._total += income
|
||||
self._logger.info(f"<SELL> {amount} / {income} ({self._remain} / {self._total})")
|
||||
self._sell = None
|
||||
elif abs(self._sell_price-(ask-self._epsilon)) >= pair.price_unit:
|
||||
elif abs(self._sell_price-ask) >= pair.price_unit:
|
||||
await self._sell.cancel()
|
||||
elif enough_spread and sell_amount >= pair.order_unit:
|
||||
elif sell_amount >= pair.order_unit:
|
||||
# order SELL
|
||||
self._sell_price = ask-self._epsilon
|
||||
self._sell_price = ask
|
||||
self._sell = await self._order_sell(sell_amount)
|
||||
|
||||
if self._buy is not None:
|
||||
# check current BUY order
|
||||
await self._buy.update()
|
||||
|
||||
# get lowest bid
|
||||
if bid == self._buy_price and abs(depth.bids[0][1]-self._buy.remain) < pair.price_unit:
|
||||
bid = depth.bids[1][0]
|
||||
|
||||
if self._buy.done:
|
||||
amount = self._buy.amount - self._buy.remain
|
||||
self._remain += amount
|
||||
@ -77,11 +113,11 @@ class MM:
|
||||
self._total -= outgo
|
||||
self._logger.info(f"<BUY> {amount} / {outgo} ({self._remain} / {self._total})")
|
||||
self._buy = None
|
||||
elif abs(self._buy_price-(bid+self._epsilon)) >= pair.price_unit:
|
||||
elif abs(self._buy_price-bid) >= pair.price_unit:
|
||||
await self._buy.cancel()
|
||||
elif enough_spread and buy_amount > pair.order_unit:
|
||||
elif buy_amount >= pair.order_unit:
|
||||
# order BUY
|
||||
self._buy_price = bid+self._epsilon
|
||||
self._buy_price = bid
|
||||
self._buy = await self._order_buy(buy_amount)
|
||||
|
||||
async def _order_sell(self, amount):
|
||||
|
@ -4,18 +4,12 @@ import asyncio
|
||||
MAX_ITEMS = 10
|
||||
|
||||
class Depth:
|
||||
def __init__(self):
|
||||
def __init__(self, order_unit):
|
||||
self.bids = []
|
||||
self.asks = []
|
||||
|
||||
self._event = asyncio.Event()
|
||||
self._event = asyncio.Event()
|
||||
self._order_unit = order_unit
|
||||
|
||||
async def wait(self):
|
||||
await self._event.wait()
|
||||
|
||||
def askVolumeUntil(self, price):
|
||||
ret = 0
|
||||
for i in range(len(self.asks)):
|
||||
if self.asks[i][0] > price: break
|
||||
ret += self.asks[i][1]
|
||||
return ret
|
||||
|
Loading…
Reference in New Issue
Block a user