sending new_ticks event
This commit is contained in:
parent
11bba57343
commit
9955ddf08e
@ -1,13 +1,12 @@
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from typing import Dict
|
from typing import Dict, List
|
||||||
|
|
||||||
from bfxbot.bfxwrapper import BfxWrapper
|
from bfxbot.bfxwrapper import BfxWrapper
|
||||||
from bfxbot.currency import Symbol
|
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:
|
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:
|
if api_key is None:
|
||||||
print("API_KEY is not set!")
|
print("API_KEY is not set!")
|
||||||
raise ValueError
|
raise ValueError
|
||||||
@ -20,25 +19,41 @@ class BfxBot:
|
|||||||
self.status: Dict[Symbol, SymbolStatus] = {}
|
self.status: Dict[Symbol, SymbolStatus] = {}
|
||||||
self.ticker: Ticker = Ticker(tick_duration)
|
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):
|
async def __update_status__(self):
|
||||||
active_positions = await self.bfx.get_active_position()
|
active_positions = await self.bfx.get_active_position()
|
||||||
|
|
||||||
for p in active_positions:
|
for symbol in self.status:
|
||||||
symbol = Symbol.from_str(p.symbol)
|
# updating tick
|
||||||
|
self.status[symbol].current_tick = self.ticker.current_tick
|
||||||
|
|
||||||
if symbol not in self.status:
|
# updating last price
|
||||||
self.status[symbol] = SymbolStatus(symbol)
|
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():
|
# updating positions
|
||||||
active_orders = await self.bfx.get_active_orders(symbol)
|
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:
|
# # updating orders
|
||||||
if symbol not in self.status:
|
# active_orders = await self.bfx.get_active_orders(symbol)
|
||||||
self.status[symbol] = SymbolStatus(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:
|
def event_handler(self, symbol) -> EventHandler:
|
||||||
if symbol not in self.status:
|
if symbol not in self.status:
|
||||||
|
@ -44,6 +44,7 @@ class EventKind(Enum):
|
|||||||
TRAILING_STOP_SET = 9,
|
TRAILING_STOP_SET = 9,
|
||||||
TRAILING_STOP_MOVED = 10,
|
TRAILING_STOP_MOVED = 10,
|
||||||
ORDER_SUBMITTED = 11,
|
ORDER_SUBMITTED = 11,
|
||||||
|
NEW_TICK = 12
|
||||||
|
|
||||||
|
|
||||||
class Ticker:
|
class Ticker:
|
||||||
@ -93,6 +94,7 @@ class SymbolStatus:
|
|||||||
def __init__(self, symbol: Symbol, strategy=None):
|
def __init__(self, symbol: Symbol, strategy=None):
|
||||||
self.symbol = symbol
|
self.symbol = symbol
|
||||||
self.eh = EventHandler()
|
self.eh = EventHandler()
|
||||||
|
self.prices: Dict[int, float] = {}
|
||||||
self.events: List[Event] = []
|
self.events: List[Event] = []
|
||||||
self.orders: Dict[int, List[Order]] = {}
|
self.orders: Dict[int, List[Order]] = {}
|
||||||
self.positions: Dict[int, List[PositionWrapper]] = {}
|
self.positions: Dict[int, List[PositionWrapper]] = {}
|
||||||
@ -143,6 +145,8 @@ class SymbolStatus:
|
|||||||
pw.set_state(state)
|
pw.set_state(state)
|
||||||
await self.eh.call_state(self, pw)
|
await self.eh.call_state(self, pw)
|
||||||
|
|
||||||
|
def set_price(self, tick, price):
|
||||||
|
self.prices[tick] = price
|
||||||
|
|
||||||
class Strategy:
|
class Strategy:
|
||||||
"""
|
"""
|
||||||
@ -167,8 +171,10 @@ class EventHandler:
|
|||||||
self.any_events = []
|
self.any_events = []
|
||||||
self.any_state = []
|
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
|
value = event.kind.value
|
||||||
|
|
||||||
|
# print("CALLING EVENT: {}".format(event))
|
||||||
if value in self.event_handlers:
|
if value in self.event_handlers:
|
||||||
for h in self.event_handlers[value]:
|
for h in self.event_handlers[value]:
|
||||||
if inspect.iscoroutinefunction(h):
|
if inspect.iscoroutinefunction(h):
|
||||||
@ -182,7 +188,9 @@ class EventHandler:
|
|||||||
else:
|
else:
|
||||||
h(event, status)
|
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:
|
if state in self.state_handlers:
|
||||||
for h in self.state_handlers[state]:
|
for h in self.state_handlers[state]:
|
||||||
if inspect.iscoroutinefunction(h):
|
if inspect.iscoroutinefunction(h):
|
||||||
|
40
main.py
40
main.py
@ -492,20 +492,18 @@ import dotenv
|
|||||||
|
|
||||||
from bfxbot import BfxBot
|
from bfxbot import BfxBot
|
||||||
from bfxbot.currency import Symbol
|
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 strategy import TrailingStopStrategy
|
||||||
|
|
||||||
from flask import Flask, render_template
|
from flask import Flask, render_template
|
||||||
from flask_socketio import SocketIO
|
from flask_socketio import SocketIO
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
socketio = SocketIO(app)
|
socketio = SocketIO(app, async_mode="threading")
|
||||||
dotenv.load_dotenv()
|
dotenv.load_dotenv()
|
||||||
loop = asyncio.new_event_loop()
|
loop = asyncio.new_event_loop()
|
||||||
|
|
||||||
bot: BfxBot = None
|
bot = None
|
||||||
eh: EventHandler = None
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def entry():
|
def entry():
|
||||||
@ -531,6 +529,7 @@ def entry():
|
|||||||
|
|
||||||
# while True:
|
# while True:
|
||||||
# await bot.update()
|
# await bot.update()
|
||||||
|
from flask import request
|
||||||
|
|
||||||
@socketio.on("close")
|
@socketio.on("close")
|
||||||
def on_message(message: dict):
|
def on_message(message: dict):
|
||||||
@ -540,29 +539,30 @@ def on_message(message: dict):
|
|||||||
|
|
||||||
@socketio.on('connect')
|
@socketio.on('connect')
|
||||||
def start_bot():
|
def start_bot():
|
||||||
asyncio.set_event_loop(loop)
|
|
||||||
|
|
||||||
global bot
|
global bot
|
||||||
global eh
|
|
||||||
|
asyncio.set_event_loop(loop)
|
||||||
|
|
||||||
API_KEY = os.getenv("API_KEY")
|
API_KEY = os.getenv("API_KEY")
|
||||||
API_SECRET = os.getenv("API_SECRET")
|
API_SECRET = os.getenv("API_SECRET")
|
||||||
|
|
||||||
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET)
|
if not bot:
|
||||||
strategy = TrailingStopStrategy()
|
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET, symbols=[Symbol.BTC], tick_duration=20)
|
||||||
bot.set_strategy(Symbol.BTC, strategy)
|
strategy = TrailingStopStrategy()
|
||||||
eh = bot.event_handler(Symbol.BTC)
|
bot.set_strategy(Symbol.BTC, strategy)
|
||||||
|
|
||||||
@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.")
|
|
||||||
|
|
||||||
|
threading.Thread(target=lambda: asyncio.run(bot_loop())).start()
|
||||||
|
print("Bot started.")
|
||||||
|
|
||||||
async def bot_loop():
|
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()
|
await bot.start()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -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']);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -9,7 +9,6 @@
|
|||||||
<script src="{{ url_for('static', filename='js/jquery-3.5.1.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/jquery-3.5.1.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/plotly-latest.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/plotly-latest.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/socket.io.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/socket.io.min.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/toast.js') }}"></script>
|
|
||||||
<script src="{{ url_for('static', filename='js/rustico.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/rustico.js') }}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user