core/main.py

110 lines
2.8 KiB
Python
Raw Normal View History

2020-11-30 14:38:28 +00:00
# #!/usr/bin/env python
import asyncio
import os
2020-12-08 19:33:55 +00:00
import threading
from time import sleep
from typing import List
2020-11-30 14:38:28 +00:00
import dotenv
from flask import Flask, render_template
from flask_socketio import SocketIO
2020-11-30 14:38:46 +00:00
from bfxbot import BfxBot
2020-11-30 14:38:46 +00:00
from bfxbot.currency import Symbol
from bfxbot.models import PositionWrapper, SymbolStatus, Event, EventKind
from strategy import TrailingStopStrategy
2020-11-30 14:38:28 +00:00
2020-12-15 15:31:09 +00:00
async def bot_loop():
await bot.start()
while True:
await bot.update()
asyncio.new_event_loop()
dotenv.load_dotenv()
API_KEY = os.getenv("API_KEY")
API_SECRET = os.getenv("API_SECRET")
2020-12-07 21:52:47 +00:00
app = Flask(__name__)
2020-12-10 16:29:26 +00:00
socketio = SocketIO(app, async_mode="threading")
2020-12-15 15:31:09 +00:00
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.symbol_event_handler(Symbol.BTC)
2020-12-08 19:33:55 +00:00
2020-12-15 15:31:09 +00:00
# initializing and starting bot on other thread
threading.Thread(target=lambda: asyncio.run(bot_loop())).start()
2020-11-30 14:38:46 +00:00
2020-12-15 15:31:09 +00:00
###################################
# Flask callbacks
###################################
2020-12-07 21:52:47 +00:00
@app.route('/')
def entry():
return render_template('index.html')
2020-11-30 14:38:46 +00:00
2020-12-15 15:31:09 +00:00
###################################
# Socker.IO callbacks
###################################
2020-12-08 19:33:55 +00:00
@socketio.on("close")
def on_message(message: dict):
position_id = message['id']
print("I would close position {}".format(position_id))
2020-12-08 19:33:55 +00:00
@socketio.on('connect')
2020-12-15 15:31:09 +00:00
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": ticks,
"prices": prices})
2020-12-15 15:31:09 +00:00
###################################
# Bot callbacks
###################################
2020-12-15 15:31:09 +00:00
@btc_eh.on_event(EventKind.NEW_TICK)
def on_new_tick(event: Event, status: SymbolStatus):
# TODO: finalize JSON structure
def pos_to_json(pw: PositionWrapper):
return {
"id": pw.position.id,
"base_price": pw.position.base_price,
"state": str(pw.state()),
2020-12-15 15:31:09 +00:00
"symbol": pw.position.symbol,
"profit_loss": pw.net_profit_loss(),
"profit_loss_percentage": pw.net_profit_loss_percentage()
2020-12-15 15:31:09 +00:00
}
2020-12-15 15:31:09 +00:00
tick = event.tick
price = status.prices[event.tick]
2020-12-08 19:33:55 +00:00
2020-12-15 15:31:09 +00:00
positions: List[PositionWrapper] = status.positions[event.tick] if event.tick in status.positions else []
2020-12-08 19:33:55 +00:00
2020-12-15 15:31:09 +00:00
socketio.emit("new_tick", {"tick": tick,
"price": price,
"positions": list(map(pos_to_json, positions))})
2020-12-08 19:33:55 +00:00
2020-11-30 14:38:28 +00:00
if __name__ == '__main__':
2020-12-08 19:33:55 +00:00
socketio.run(app, debug=True)