tailwind #9
@ -1,5 +1,6 @@
|
||||
from time import sleep
|
||||
from typing import Dict, List
|
||||
|
||||
from bfxbot.bfxwrapper import BfxWrapper
|
||||
from bfxbot.currency import Symbol
|
||||
from bfxbot.models import SymbolStatus, Ticker, EventHandler, Strategy, Event, EventKind
|
||||
@ -15,9 +16,9 @@ class BfxBot:
|
||||
print("API_SECRET is not set!")
|
||||
raise ValueError
|
||||
|
||||
self.bfx: BfxWrapper = BfxWrapper(api_key, api_secret)
|
||||
self.status: Dict[Symbol, SymbolStatus] = {}
|
||||
self.ticker: Ticker = Ticker(tick_duration)
|
||||
self.__bfx: BfxWrapper = BfxWrapper(api_key, api_secret)
|
||||
self.__ticker: Ticker = Ticker(tick_duration)
|
||||
self.__status: Dict[Symbol, SymbolStatus] = {}
|
||||
|
||||
if isinstance(symbols, Symbol):
|
||||
symbols = [symbols]
|
||||
@ -26,57 +27,57 @@ class BfxBot:
|
||||
|
||||
# init symbol statuses
|
||||
for s in self.symbols:
|
||||
self.status[s] = SymbolStatus(s)
|
||||
self.__status[s] = SymbolStatus(s)
|
||||
|
||||
async def __update_status__(self):
|
||||
active_positions = await self.bfx.get_active_position()
|
||||
active_positions = await self.__bfx.get_active_position()
|
||||
|
||||
for symbol in self.status:
|
||||
for symbol in self.__status:
|
||||
# updating tick
|
||||
self.status[symbol].current_tick = self.ticker.current_tick
|
||||
self.__status[symbol].current_tick = self.__ticker.current_tick
|
||||
|
||||
# updating last price
|
||||
last_price = await self.bfx.get_current_prices(symbol)
|
||||
last_price = await self.__bfx.get_current_prices(symbol)
|
||||
last_price = last_price[0]
|
||||
|
||||
self.status[symbol].set_price(self.ticker.current_tick, last_price)
|
||||
self.__status[symbol].set_tick_price(self.__ticker.current_tick, last_price)
|
||||
|
||||
# updating positions
|
||||
for p in [x for x in active_positions if x.symbol == str(symbol)]:
|
||||
await self.status[Symbol.from_str(p.symbol)].add_position(p)
|
||||
symbol_positions = [x for x in active_positions if x.symbol == str(symbol)]
|
||||
for p in symbol_positions:
|
||||
await self.__status[Symbol.from_str(p.symbol)].add_position(p)
|
||||
|
||||
# # updating orders
|
||||
# active_orders = await self.bfx.get_active_orders(symbol)
|
||||
#
|
||||
# for o in active_orders:
|
||||
# self.status[symbol].add_order(o)
|
||||
# updating orders
|
||||
active_orders = await self.__bfx.get_active_orders(str(symbol))
|
||||
|
||||
# emitting event
|
||||
await self.status[symbol].__add_event__(Event(EventKind.NEW_TICK, 0, self.ticker.current_tick))
|
||||
for o in active_orders:
|
||||
self.__status[symbol].add_order(o)
|
||||
|
||||
# emitting new tick event
|
||||
await self.__status[symbol].__add_event__(Event(EventKind.NEW_TICK, self.__ticker.current_tick))
|
||||
|
||||
def event_handler(self, symbol) -> EventHandler:
|
||||
if symbol not in self.status:
|
||||
def symbol_event_handler(self, symbol) -> EventHandler:
|
||||
if symbol not in self.__status:
|
||||
return None
|
||||
|
||||
return self.status[symbol].eh
|
||||
return self.__status[symbol].eh
|
||||
|
||||
def status(self, symbol: Symbol) -> SymbolStatus:
|
||||
if symbol not in self.status:
|
||||
def symbol_status(self, symbol: Symbol) -> SymbolStatus:
|
||||
if symbol not in self.__status:
|
||||
return None
|
||||
|
||||
return self.status[symbol]
|
||||
return self.__status[symbol]
|
||||
|
||||
async def start(self):
|
||||
await self.__update_status__()
|
||||
|
||||
async def update(self):
|
||||
self.ticker.inc()
|
||||
sleep(self.ticker.seconds)
|
||||
sleep(self.__ticker.seconds)
|
||||
self.__ticker.inc()
|
||||
await self.__update_status__()
|
||||
|
||||
def set_strategy(self, symbol, strategy: Strategy):
|
||||
if symbol in self.status:
|
||||
self.status[symbol].strategy = strategy
|
||||
if symbol in self.__status:
|
||||
self.__status[symbol].strategy = strategy
|
||||
else:
|
||||
self.status[symbol] = SymbolStatus(symbol, strategy)
|
||||
self.__status[symbol] = SymbolStatus(symbol, strategy)
|
||||
|
@ -58,14 +58,12 @@ class Ticker:
|
||||
|
||||
|
||||
class Event:
|
||||
def __init__(self, kind: EventKind, pid: int, tick: int) -> None:
|
||||
def __init__(self, kind: EventKind, tick: int) -> None:
|
||||
self.kind: EventKind = kind
|
||||
self.tick: int = tick
|
||||
# position ID
|
||||
self.pid: int = pid
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"[{self.pid}]: {self.kind.name} @ Tick {self.tick}"
|
||||
return f"{self.kind.name} @ Tick {self.tick}"
|
||||
|
||||
|
||||
class PositionWrapper:
|
||||
@ -151,9 +149,10 @@ class SymbolStatus:
|
||||
pw.set_state(state)
|
||||
await self.eh.call_state(self, pw)
|
||||
|
||||
def set_price(self, tick, price):
|
||||
def set_tick_price(self, tick, price):
|
||||
self.prices[tick] = price
|
||||
|
||||
|
||||
class Strategy:
|
||||
"""
|
||||
Defines new position state and events after tick.
|
||||
@ -236,10 +235,12 @@ class EventHandler:
|
||||
def registerhandle(handler):
|
||||
self.any_events.append(handler)
|
||||
return handler
|
||||
|
||||
return registerhandle
|
||||
|
||||
def on_any_state(self):
|
||||
def registerhandle(handler):
|
||||
self.any_state.append(handler)
|
||||
return handler
|
||||
|
||||
return registerhandle
|
||||
|
17
main.py
17
main.py
@ -3,6 +3,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
import threading
|
||||
from time import sleep
|
||||
from typing import List
|
||||
|
||||
import dotenv
|
||||
@ -34,7 +35,7 @@ socketio = SocketIO(app, async_mode="threading")
|
||||
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET,
|
||||
symbols=[Symbol.BTC], tick_duration=20)
|
||||
bot.set_strategy(Symbol.BTC, TrailingStopStrategy())
|
||||
btc_eh = bot.event_handler(Symbol.BTC)
|
||||
btc_eh = bot.symbol_event_handler(Symbol.BTC)
|
||||
|
||||
# initializing and starting bot on other thread
|
||||
threading.Thread(target=lambda: asyncio.run(bot_loop())).start()
|
||||
@ -62,9 +63,19 @@ def on_message(message: dict):
|
||||
|
||||
@socketio.on('connect')
|
||||
def on_connect():
|
||||
# sleeping on exception to avoid race condition
|
||||
ticks, prices = [], []
|
||||
|
||||
while not ticks or not prices:
|
||||
try:
|
||||
ticks = bot.symbol_status(Symbol.BTC).all_ticks()
|
||||
prices = bot.symbol_status(Symbol.BTC).all_prices()
|
||||
except KeyError:
|
||||
sleep(1)
|
||||
|
||||
socketio.emit("first_connect",
|
||||
{"ticks": bot.status[Symbol.BTC].all_ticks(),
|
||||
"prices": bot.status[Symbol.BTC].all_prices()})
|
||||
{"ticks": ticks,
|
||||
"prices": prices})
|
||||
|
||||
|
||||
###################################
|
||||
|
@ -1,2 +1,4 @@
|
||||
python-dotenv~=0.15.0
|
||||
sympy~=1.7
|
||||
sympy~=1.7
|
||||
asyncio~=3.4.3
|
||||
Flask~=1.1.2
|
Loading…
Reference in New Issue
Block a user