update
This commit is contained in:
2
logic/__init__.py
Normal file
2
logic/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from logic.ma_cross import MA_Cross
|
||||
from logic.mm import MM
|
84
logic/ma_cross.py
Normal file
84
logic/ma_cross.py
Normal 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
83
logic/mm.py
Normal 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)
|
Reference in New Issue
Block a user