tmm/util/candlestick.py
2022-07-17 02:43:05 +09:00

75 lines
1.9 KiB
Python

import asyncio
import datetime
MAX_CANDLES = 200
OPEN = 0
HIGH = 0
LOW = 0
CLOSE = 0
class Candlestick:
def __init__(self, ticker, interval):
self.values = []
self.latest = None
self.interval = interval
self._ticker = ticker
self._event = asyncio.Event()
asyncio.create_task(self._refresh_and_start())
async def _refresh_and_start(self):
self.values = await self._fetch(datetime.datetime.now(tz=datetime.timezone.utc))
asyncio.create_task(self._ticker_watcher())
asyncio.create_task(self._main())
async def _fetch(self, data, depth = 0, rem = MAX_CANDLES):
assert(False)
async def _ticker_watcher(self):
while True:
await self._ticker.wait()
v = self._ticker.price
if self.latest is None:
self.latest = [v, -1e100, 1e100, None]
self.latest[1] = max(self.latest[1], v)
self.latest[2] = min(self.latest[2], v)
self.latest[3] = v
async def _main(self):
while True:
await asyncio.sleep(self.interval)
if self.latest is None:
if len(self.values) == 0:
continue
self.latest = self.values[0]
n = min(MAX_CANDLES-1, len(self.values))
self.values = [self.latest, *self.values[0:n]]
self.latest = None
self._event.set()
self._event.clear()
async def wait(self):
await self._event.wait()
def SMA(self, period, offset=0, type = CLOSE):
sum = 0
end = min(period+offset, len(self.values))
for i in range(offset, end):
sum += self.values[i][type]
return sum / (end - offset)
def EMA(self, period, offset=0, type = CLOSE):
end = min(period+offset, len(self.values))
n = end - offset
ret = 0
for i in range(offset, end):
ret += self.values[i][type]
ret /= n
for i in range(offset, end):
ret += (2/(n+1)) * (self.values[i][type] - ret)
return ret