This commit is contained in:
2022-07-15 19:17:55 +09:00
parent 37840311e0
commit 729e88957a
11 changed files with 692 additions and 0 deletions

2
logic/__init__.py Normal file
View File

@@ -0,0 +1,2 @@
from logic.ma_cross import MA_Cross
from logic.mm import MM

84
logic/ma_cross.py Normal file
View File

@@ -0,0 +1,84 @@
import asyncio
SHORT_PERIOD = 13
LONG_PERIOD = 200
EXPECT_CYCLE_DUR_IN_CANDLE_INTERVALS = 5
class MA_Cross:
def __init__(self, logger, pair, candlestick, lot, limit_rate, stop_rate):
self._logger = logger
self._pair = pair
self._candlestick = candlestick
self._lot = lot
self._limit_rate = limit_rate
self._stop_rate = stop_rate
asyncio.create_task(self._main())
async def _main(self):
self._logger.info("started")
while True:
await self._candlestick.wait()
if len(self._candlestick.values) < LONG_PERIOD:
continue
short = self._candlestick.SMA(SHORT_PERIOD)
long = self._candlestick.SMA(LONG_PERIOD)
plong = self._candlestick.SMA(LONG_PERIOD, 1)
expect_sell = self._pair.ticker.buy * (1+self._limit_rate)
ask_volume = self._pair.depth.askVolumeUntil(expect_sell)
interval_volume = self._pair.ticker.volume / 24 / 3600 * self._candlestick.interval
if plong < long and short > long:
if ask_volume < interval_volume * EXPECT_CYCLE_DUR_IN_CANDLE_INTERVALS:
await self._buy()
async def _buy(self):
self._logger.info("buy signal received")
# buy (market) and sell (limit)
amount = self._lot/self._pair.ticker.buy
try:
buy = await self._pair.buy_market(amount)
except Exception as e:
self._logger.warn("failed to buy", e)
return
while not buy.done:
await asyncio.sleep(0.1)
await buy.update()
self._logger.info(f"BUY confirmed (+{amount} / -{buy.price*amount})")
limit_price = buy.price*(1+self._limit_rate)
stop_price = buy.price*(1-self._stop_rate)
try:
stop = await self._pair.sell_stop(amount, stop_price)
limit = await self._pair.sell_limit(amount, limit_price)
except Exception as e:
print("failed to order", e.message)
self._logger.error("FAILED TO ORDER for STOPPING and LIMITATION!!")
return
self._logger.debug("waiting for STOP or LIMIT")
while (not stop.done) and (not limit.done):
await asyncio.sleep(2)
try:
await asyncio.gather(limit.update(), stop.update())
except Exception:
continue
if stop.done:
self._logger.info(f"STOP confirmed (-{amount} / +{stop.price*amount})")
# cancel limit and cooldown
await asyncio.gather(asycio.sleep(5), limit.cancel())
return
if limit.done:
self._logger.info(f"LIMIT confirmed (-{amount} / +{limit.price*amount})")
await stop.cancel()
return

83
logic/mm.py Normal file
View File

@@ -0,0 +1,83 @@
import asyncio
class MM:
def __init__(self, logger, pair, lot, epsilon):
self._logger = logger
self._pair = pair
self._lot = lot
self._remain = 0
self._epsilon = epsilon
asyncio.create_task(self._main())
async def _main(self):
self._logger.info("started")
while True:
depth = self._pair.depth
await depth.wait()
if len(depth.bids) == 0 or len(depth.asks) == 0:
continue
spread = depth.asks[0][0] - depth.bids[0][0]
if spread > self._epsilon*2:
sell_price = depth.asks[0][0]-self._epsilon
buy_price = depth.bids[0][0]+self._epsilon
await self._make(sell_price, buy_price)
async def _make(self, sell_price, buy_price):
if self._remain < self._epsilon/buy_price:
amount = self._lot/buy_price
try:
buy = await self._pair.buy_limit(amount, buy_price, True)
except Exception:
buy = None
try:
sell = await self._pair.sell_limit(amount, sell_price, True)
except Exception:
sell = None
else:
buy = None
sell = await self._pair.sell_limit(self._remain, sell_price, True)
while (sell is not None) or (buy is not None):
await asyncio.sleep(1)
try:
coro = []
if buy is not None: coro.append(buy .update())
if sell is not None: coro.append(sell.update())
await asyncio.gather(*coro)
except Exception as e:
continue
depth = self._pair.depth
if sell is not None:
if sell.done:
self._remain -= sell.amount-sell.remain
sell = None
elif sell_price > depth.asks[0][0]:
break
if buy is not None:
if buy.done:
self._remain += buy.amount-buy.remain
buy = None
elif buy_price < depth.bids[0][0]:
break
async def cancel(self, order, flag):
while True:
try:
await order.cancel()
await order.update()
break
except Exception:
continue
self._remain += flag*(order.amount-order.remain)
coro = []
if sell is not None:
coro.append(cancel(self, sell, -1))
if buy is not None:
coro.append(cancel(self, buy, 1))
await asyncio.gather(*coro)