From 96f0e2afea1b947f8f5924950ee5fc37c8fa5022 Mon Sep 17 00:00:00 2001 From: Giulio De Pasquale Date: Thu, 26 Nov 2020 21:45:32 +0000 Subject: [PATCH] initial commit --- .gitignore | 156 ++++++++++++++++++++++++ main.py | 315 ++++++++++++++++++++++++++++++++++++++++++++++++ sounds/coin.mp3 | Bin 0 -> 31973 bytes 3 files changed, 471 insertions(+) create mode 100644 .gitignore create mode 100644 main.py create mode 100644 sounds/coin.mp3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3108c2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,156 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/python,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=python,visualstudiocode + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +pytestdebug.log + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ +doc/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ +pythonenv* + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# profiling data +.prof + +### VisualStudioCode ### +.vscode/* +!.vscode/tasks.json +!.vscode/launch.json +*.code-workspace + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# End of https://www.toptal.com/developers/gitignore/api/python,visualstudiocode diff --git a/main.py b/main.py new file mode 100644 index 0000000..11a57b3 --- /dev/null +++ b/main.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python + +import asyncio +from asyncio import events +import time +from enum import Enum +from os import system, terminal_size +from time import sleep +from bfxapi import Client +from bfxapi.models.order import Order +from bfxapi.models.position import Position +from termcolor import colored +import shutil +import termplotlib +import numpy +from playsound import playsound +from asciimatics.screen import ManagedScreen, Screen +import dotenv + +dotenv.load() +API_KEY = dotenv.get('API_KEY', default='') +API_SECRET = dotenv.get('API_SECRET', default='') + +bfx = Client( + API_KEY=API_KEY, + API_SECRET=API_SECRET +).rest + +TAKER_FEE = 0.2 +MAKER_FEE = 0.1 + +BREAK_EVEN_PERC = TAKER_FEE +MIN_PROFIT_PERC = 0.65 +GOOD_PROFIT_PERC = MIN_PROFIT_PERC * 2.1 +MAX_LOSS_PERC = -4.0 + +TRAILING_GOOD_PROFIT_PERC = 0.2 + + +class Ticker(): + def __init__(self, sec) -> None: + self.seconds: int = sec + self.start_time = time.time() + self.current_tick: int = 1 + + +class EventKind(Enum): + NEW_MINIMUM = 1, + NEW_MAXIMUM = 2, + REACHED_LOSS = 3, + REACHED_BREAK_EVEN = 4, + REACHED_MIN_PROFIT = 5, + REACHED_GOOD_PROFIT = 6, + REACHED_MAX_LOSS = 7 + + +class Event(): + def __init__(self, kind: EventKind, tick: int) -> None: + self.kind: EventKind = kind + self.tick: int = tick + + def __repr__(self) -> str: + return f"{self.kind.name} @ Tick {self.tick}" + + +class PositionStatus(): + def __init__(self, position: Position) -> None: + self.position: Position = position + + +class State(Enum): + CRITICAL = -1, + LOSS = 0, + BREAK_EVEN = 1, + MINIMUM_PROFIT = 2, + PROFIT = 3 + + def color(self) -> str: + if self == self.LOSS or self == self.CRITICAL: + return "red" + elif self == self.BREAK_EVEN: + return "yellow" + else: + return "green" + + +class Printer(): + def __init__(self, screen: Screen): + self.screen: Screen = screen + self.current_line: int = 0 + (self.current_width, self.current_height) = shutil.get_terminal_size() + + def get_current_line(self) -> int: + return self.current_line + + def next(self) -> int: + # print("Current line: {}".format(self.current_line)) + line = self.current_line + self.current_line += 1 + return line + + def print_next_line(self, text): + for line in text.split("\n"): + self.screen.print_at(line, 0, self.next(), 1) + self.screen.refresh() + + def reset_current_line(self): + self.current_line = 0 + + def set_screen(self, screen: Screen): + self.screen = screen + + def has_screen_resized(self): + return (self.current_width, self.current_height) != shutil.get_terminal_size() + + def to_current_screen_size(self): + (self.current_width, self.current_height) = shutil.get_terminal_size() + +class Status(): + def __init__(self, tick_duration, symbol): + self.ticker: Ticker = Ticker(tick_duration) + self.events: list[Event] = [] + self.symbol = symbol + self.ticks: dict[int, float] = {} + self.current_state: State = State.LOSS + + async def wait(self) -> None: + sleep(self.ticker.seconds) + + self.ticks[self.ticker.current_tick] = await get_current_price(self.symbol) + self.ticker.current_tick += 1 + + def get_current_tick(self) -> int: + return self.ticker.current_tick + + def last_events(self, n): + return self.events[-n:] + + def add_event(self, event: Event): + self.events.append(event) + + async def last_price(self) -> float: + if self.get_current_tick() not in self.ticks.keys(): + return await get_current_price(self.symbol) + self.ticks[self.get_current_tick()] + + def set_state(self, state: State): + if self.current_state != state: + if state == State.CRITICAL: + self.add_event( + Event(EventKind.REACHED_MAX_LOSS, self.get_current_tick())) + elif state == State.LOSS: + self.add_event( + Event(EventKind.REACHED_LOSS, self.get_current_tick())) + elif state == State.BREAK_EVEN: + self.add_event( + Event(EventKind.REACHED_BREAK_EVEN, self.get_current_tick())) + elif state == State.MINIMUM_PROFIT: + self.add_event( + Event(EventKind.REACHED_MIN_PROFIT, self.get_current_tick())) + elif state == State.PROFIT: + self.add_event( + Event(EventKind.REACHED_GOOD_PROFIT, self.get_current_tick())) + + self.current_state = state + + def get_current_state(self) -> State: + return self.current_state + + +def net_pl_percentage(perc: float, reference_fee_perc: float): + return perc - reference_fee_perc + + +async def main(screen: Screen): + min_perc = 999.0 + max_perc = -999.0 + symbol = "tBTCUSD" + + printer = Printer(screen) + status = Status(20, symbol) + + while True: + positions = [p for p in await bfx.get_active_position() if p.symbol == status.symbol] + orders = await bfx.get_active_orders(symbol) + + last_price = await status.last_price() + + screen.clear() + printer.print_next_line("Current {} price: {} | Current tick ({} sec): {}".format(symbol, + colored_float( + last_price, "white", attrs=["bold"]), + status.ticker.seconds, + status.get_current_tick(), + )) + + if positions: + printer.print_next_line("") + printer.print_next_line("Open {}:".format( + colored("POSITIONS", attrs=["underline"]))) + + for p in [p for p in positions if p.symbol == status.symbol]: + plfees_percentage = net_pl_percentage( + p.profit_loss_percentage, TAKER_FEE) + + if plfees_percentage > GOOD_PROFIT_PERC: + status.set_state(State.PROFIT) + elif plfees_percentage >= MIN_PROFIT_PERC and plfees_percentage < GOOD_PROFIT_PERC: + status.set_state(State.MINIMUM_PROFIT) + elif plfees_percentage >= 0.0 and plfees_percentage < MIN_PROFIT_PERC: + status.set_state(State.BREAK_EVEN) + elif plfees_percentage < 0.0 and plfees_percentage > MAX_LOSS_PERC: + status.set_state(State.LOSS) + else: + status.set_state(State.CRITICAL) + + status_color = status.get_current_state().color() + + # + # min / max calculations + # + if plfees_percentage > max_perc: + max_perc = plfees_percentage + status.add_event(Event(EventKind.NEW_MAXIMUM, + status.get_current_tick())) + if plfees_percentage < min_perc: + min_perc = plfees_percentage + status.add_event(Event(EventKind.NEW_MINIMUM, + status.get_current_tick())) + + min_perc_colored = colored_percentage( + min_perc, "red") if min_perc < 0.0 else colored_percentage(min_perc, "green") + max_perc_colored = colored_percentage( + max_perc, "red") if max_perc < 0.0 else colored_percentage(max_perc, "green") + + # + # current status calculations + # + current_colored_format = "{} ({})".format(colored_percentage(plfees_percentage, status_color), + colored_float(p.profit_loss, status_color)) + + # + # Status bar + # + printer.print_next_line("{:1.5f} {} @ {} | {} | min: {}, MAX: {}".format( + p.amount, + p.symbol, + colored_float(p.base_price, "white", attrs=["underline"]), + current_colored_format, + min_perc_colored, + max_perc_colored)) + + # Separator + printer.print_next_line("") + + if orders: + printer.print_next_line("Open {}:".format( + colored("ORDERS", attrs=["underline"]))) + + print_last_events(status, 10, printer) + plot(status, printer) + + if status.get_current_state() == State.PROFIT: + playsound("sounds/coin.mp3") + + printer.reset_current_line() + await status.wait() + + return + + +def colored_percentage(perc, color, **kwargs): + return "{}".format(colored("{:1.2f}%".format(perc), color=color, **kwargs)) + + +def colored_float(num, color, **kwargs): + return "{}".format(colored("{:1.2f}".format(num), color=color, **kwargs)) + + +def print_last_events(status: Status, n: int, printer: Printer): + printer.print_next_line(colored(f"Last {n} events:", attrs=["bold"])) + + for e in status.last_events(n): + printer.print_next_line(f"- {e}") + + +def plot(status: Status, printer: Printer): + if status.ticks: + figure = termplotlib.figure() + x = range(1, status.get_current_tick() + 1) + y = [x for x in status.ticks.values()] + + figure.plot(x, y, width=printer.screen.width, + height=printer.screen.height - printer.get_current_line() - 1) + + printer.print_next_line(figure.get_string()) + + +async def get_current_price(symbol): + tickers = await bfx.get_public_ticker(symbol) + return tickers[6] + + +def clear(): + system("clear") + + +def screen_main(): + return + + +if __name__ == "__main__": + asyncio.run(Screen.wrapper(main)) + # asyncio.run(main()) + # screen_main() diff --git a/sounds/coin.mp3 b/sounds/coin.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..14fc710783a87093143333071c73daab8665edf5 GIT binary patch literal 31973 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 literal 0 HcmV?d00001