diff --git a/bfxbot/bfxbot.py b/bfxbot/bfxbot.py
index 13a32f8..a48e277 100644
--- a/bfxbot/bfxbot.py
+++ b/bfxbot/bfxbot.py
@@ -1,13 +1,12 @@
from time import sleep
-from typing import Dict
-
+from typing import Dict, List
from bfxbot.bfxwrapper import BfxWrapper
from bfxbot.currency import Symbol
-from bfxbot.models import SymbolStatus, Ticker, EventHandler, Strategy
+from bfxbot.models import SymbolStatus, Ticker, EventHandler, Strategy, Event, EventKind
class BfxBot:
- def __init__(self, api_key: str, api_secret: str, tick_duration: int = 1):
+ def __init__(self, api_key: str, api_secret: str, symbols: List[Symbol], tick_duration: int = 1, ):
if api_key is None:
print("API_KEY is not set!")
raise ValueError
@@ -20,25 +19,41 @@ class BfxBot:
self.status: Dict[Symbol, SymbolStatus] = {}
self.ticker: Ticker = Ticker(tick_duration)
+ if isinstance(symbols, Symbol):
+ symbols = [symbols]
+
+ self.symbols: List[Symbol] = symbols
+
+ # init symbol statuses
+ for s in self.symbols:
+ self.status[s] = SymbolStatus(s)
+
async def __update_status__(self):
active_positions = await self.bfx.get_active_position()
- for p in active_positions:
- symbol = Symbol.from_str(p.symbol)
+ for symbol in self.status:
+ # updating tick
+ self.status[symbol].current_tick = self.ticker.current_tick
- if symbol not in self.status:
- self.status[symbol] = SymbolStatus(symbol)
+ # updating last price
+ last_price = await self.bfx.get_current_prices(symbol)
+ last_price = last_price[0]
- await self.status[symbol].add_position(p)
+ self.status[symbol].set_price(self.ticker.current_tick, last_price)
- for symbol in self.status.keys():
- active_orders = await self.bfx.get_active_orders(symbol)
+ # updating positions
+ for p in [x for x in active_positions if x.symbol == symbol]:
+ await self.status[p.symbol].add_position(p)
- for o in active_orders:
- if symbol not in self.status:
- self.status[symbol] = SymbolStatus(symbol)
+ # # updating orders
+ # active_orders = await self.bfx.get_active_orders(symbol)
+ #
+ # for o in active_orders:
+ # self.status[symbol].add_order(o)
+
+ # emitting event
+ await self.status[symbol].__add_event__(Event(EventKind.NEW_TICK, 0, self.ticker.current_tick))
- self.status[symbol].add_order(o)
def event_handler(self, symbol) -> EventHandler:
if symbol not in self.status:
diff --git a/bfxbot/models.py b/bfxbot/models.py
index eac4aa5..2db3d66 100644
--- a/bfxbot/models.py
+++ b/bfxbot/models.py
@@ -44,6 +44,7 @@ class EventKind(Enum):
TRAILING_STOP_SET = 9,
TRAILING_STOP_MOVED = 10,
ORDER_SUBMITTED = 11,
+ NEW_TICK = 12
class Ticker:
@@ -93,6 +94,7 @@ class SymbolStatus:
def __init__(self, symbol: Symbol, strategy=None):
self.symbol = symbol
self.eh = EventHandler()
+ self.prices: Dict[int, float] = {}
self.events: List[Event] = []
self.orders: Dict[int, List[Order]] = {}
self.positions: Dict[int, List[PositionWrapper]] = {}
@@ -143,6 +145,8 @@ class SymbolStatus:
pw.set_state(state)
await self.eh.call_state(self, pw)
+ def set_price(self, tick, price):
+ self.prices[tick] = price
class Strategy:
"""
@@ -167,8 +171,10 @@ class EventHandler:
self.any_events = []
self.any_state = []
- async def call_event(self, event: Event, status: SymbolStatus):
+ async def call_event(self, status: SymbolStatus, event: Event):
value = event.kind.value
+
+ # print("CALLING EVENT: {}".format(event))
if value in self.event_handlers:
for h in self.event_handlers[value]:
if inspect.iscoroutinefunction(h):
@@ -182,7 +188,9 @@ class EventHandler:
else:
h(event, status)
- async def call_state(self, state: PositionState, status: SymbolStatus):
+ async def call_state(self, status: SymbolStatus, pw: PositionWrapper):
+ state = pw.state
+
if state in self.state_handlers:
for h in self.state_handlers[state]:
if inspect.iscoroutinefunction(h):
diff --git a/main.py b/main.py
index 0b48b0c..10fa225 100755
--- a/main.py
+++ b/main.py
@@ -492,20 +492,18 @@ import dotenv
from bfxbot import BfxBot
from bfxbot.currency import Symbol
-from bfxbot.models import EventHandler, PositionState, SymbolStatus, Event
+from bfxbot.models import EventHandler, PositionState, SymbolStatus, Event, EventKind
from strategy import TrailingStopStrategy
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
-socketio = SocketIO(app)
+socketio = SocketIO(app, async_mode="threading")
dotenv.load_dotenv()
loop = asyncio.new_event_loop()
-bot: BfxBot = None
-eh: EventHandler = None
-
+bot = None
@app.route('/')
def entry():
@@ -531,6 +529,7 @@ def entry():
# while True:
# await bot.update()
+from flask import request
@socketio.on("close")
def on_message(message: dict):
@@ -540,29 +539,30 @@ def on_message(message: dict):
@socketio.on('connect')
def start_bot():
- asyncio.set_event_loop(loop)
-
global bot
- global eh
+
+ asyncio.set_event_loop(loop)
API_KEY = os.getenv("API_KEY")
API_SECRET = os.getenv("API_SECRET")
- bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET)
- strategy = TrailingStopStrategy()
- bot.set_strategy(Symbol.BTC, strategy)
- eh = bot.event_handler(Symbol.BTC)
-
- @eh.on_any_event()
- def on_any_event(event: Event, status: SymbolStatus):
- print("EMITTING")
- socketio.emit("event", {"kind": "a"})
-
- threading.Thread(target=lambda: asyncio.run(bot_loop())).start()
- print("Bot started.")
+ if not bot:
+ bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET, symbols=[Symbol.BTC], tick_duration=20)
+ strategy = TrailingStopStrategy()
+ bot.set_strategy(Symbol.BTC, strategy)
+ threading.Thread(target=lambda: asyncio.run(bot_loop())).start()
+ print("Bot started.")
async def bot_loop():
+ global bot
+
+ eh = bot.event_handler(Symbol.BTC)
+
+ @eh.on_event(EventKind.NEW_TICK)
+ def on_new_tick(event: Event, status: SymbolStatus):
+ socketio.emit("new_tick", {"tick": event.tick, "price": status.prices[event.tick]})
+
await bot.start()
while True:
diff --git a/static/js/rustico.js b/static/js/rustico.js
index 6632c5b..bbc18db 100644
--- a/static/js/rustico.js
+++ b/static/js/rustico.js
@@ -27,6 +27,12 @@ $(document).ready(function () {
})
})
- socket.on("event", () => {
- })
+ socket.on("connect", function(socket) {
+ console.log("Connected");
+ });
+
+ socket.on("new_tick", function(data) {
+ console.log("Tick " + data['tick'] + "| Price: " + data['price']);
+ });
+
});
\ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
index 1b08b8c..415e60f 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -9,7 +9,6 @@
-