-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- added chart for easier visualization of pool vs. market - added update_pools.py for automated pool updating
- Loading branch information
iamredbar
committed
Dec 6, 2020
1 parent
e2d4ce1
commit 6de2696
Showing
9 changed files
with
584 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
# by Christopher Sanborn | ||
import tkinter as tk | ||
from tkinter import ttk | ||
import math | ||
import numpy as numpy | ||
import matplotlib | ||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg | ||
from matplotlib.figure import Figure | ||
|
||
from bitshares import BitShares | ||
from bitshares.amount import Amount | ||
from bitshares.asset import Asset | ||
|
||
|
||
matplotlib.use("TkAgg") | ||
|
||
class DepthData(): | ||
|
||
def __init__(self): | ||
self.dirty=True | ||
|
||
def update_blockchain_data(self, blockchain_data): | ||
self.dirty = True | ||
self.pool = blockchain_data['pool'] | ||
self.amount_x = self.pool.amount_x() | ||
self.amount_y = self.pool.amount_y() | ||
self.bids = self.pool.market_bids() | ||
self.asks = self.pool.market_asks() | ||
|
||
def get_pool_price(self): | ||
return self.pool.price() | ||
|
||
def get_pool_buys(self, p_min, p_max): | ||
p_pool = self.get_pool_price() | ||
p_min = p_min if p_min > 0 else (p_max-p_min)/1e6 | ||
p_max = min(p_max, p_pool) | ||
prices = numpy.linspace(p_min,p_max,100) if p_min<p_max else [] | ||
depth = [self.amount_y*(math.sqrt(p_pool/p) - 1) for p in prices] | ||
return { | ||
'x':prices, | ||
'y':depth | ||
} | ||
|
||
def get_pool_sells(self, p_min, p_max): | ||
p_pool = self.get_pool_price() | ||
p_min = max(p_min, p_pool) | ||
prices = numpy.linspace(p_min,p_max,100) if p_min<p_max else [] | ||
depth = [self.amount_y*(1-math.sqrt(p_pool/p)) for p in prices] | ||
return { | ||
'x':prices, | ||
'y':depth | ||
} | ||
|
||
def get_book_buys(self, p_min, p_max): | ||
x = [] | ||
y = [] | ||
cum = 0 | ||
for pr in self.bids: | ||
price = pr.price | ||
if price >= p_min: | ||
previous = cum | ||
cum = cum + pr['quote']['amount'] | ||
x.extend([price, price]) | ||
y.extend([previous, cum]) | ||
if cum > 0: | ||
x.append(p_min) | ||
y.append(cum) | ||
return { | ||
'x':x, | ||
'y':y | ||
} | ||
|
||
def get_book_sells(self, p_min, p_max): | ||
x = [] | ||
y = [] | ||
cum = 0 | ||
for pr in self.asks: | ||
price = pr.price | ||
if price <= p_max: | ||
previous = cum | ||
cum = cum + pr['quote']['amount'] | ||
x.extend([price, price]) | ||
y.extend([previous, cum]) | ||
if cum > 0: | ||
x.append(p_max) | ||
y.append(cum) | ||
return { | ||
'x':x, | ||
'y':y | ||
} | ||
|
||
|
||
class DepthChart(tk.Frame): | ||
|
||
def __init__(self, parent, controller, **kwargs): | ||
tk.Frame.__init__(self, parent, **kwargs) | ||
self.data = DepthData() | ||
self.fig = None | ||
self.canvas = None | ||
|
||
def update_blockchain_data(self, blockchain_data): | ||
self.data.update_blockchain_data(blockchain_data) | ||
pool_price = self.data.get_pool_price() | ||
prices = [] | ||
prices.extend([pr.price for pr in blockchain_data['market_orderbook']['asks']]) | ||
self.pricewindow = [pool_price*(1/2), | ||
pool_price*(3/2)] | ||
self.draw() | ||
|
||
def draw(self): | ||
|
||
pool_sell_curve = self.data.get_pool_sells(*self.pricewindow) | ||
pool_buy_curve = self.data.get_pool_buys(*self.pricewindow) | ||
book_sell_curve = self.data.get_book_sells(*self.pricewindow) | ||
book_buy_curve = self.data.get_book_buys(*self.pricewindow) | ||
|
||
if self.fig is None: | ||
self.fig = Figure(figsize=(7,4.5)) | ||
self.fig.clf() | ||
self.fig.patch.set_facecolor("burlywood") | ||
a = self.fig.gca() | ||
a.set_facecolor("ghostwhite") | ||
|
||
attr = { | ||
"book": { | ||
"buy": { | ||
"line": { | ||
"color": "darkgreen", | ||
}, | ||
"area": { | ||
"color": "darkgreen", | ||
"alpha": 0.25, | ||
}, | ||
}, | ||
"sell": { | ||
"line": { | ||
"color": "darkred", | ||
}, | ||
"area": { | ||
"color": "darkred", | ||
"alpha": 0.25, | ||
}, | ||
}, | ||
}, | ||
"pool": { | ||
"buy": { | ||
"line": { | ||
"color": "green", | ||
}, | ||
"area": { | ||
"color": "green", | ||
"alpha": 0.25, | ||
}, | ||
}, | ||
"sell": { | ||
"line": { | ||
"color": "red", | ||
}, | ||
"area": { | ||
"color": "red", | ||
"alpha": 0.25, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
a.plot(pool_sell_curve['x'], pool_sell_curve['y'], **attr['pool']['sell']['line']) | ||
a.plot(pool_buy_curve['x'], pool_buy_curve['y'], **attr['pool']['buy']['line']) | ||
a.fill_between(pool_sell_curve['x'], pool_sell_curve['y'], **attr['pool']['sell']['area']) | ||
a.fill_between(pool_buy_curve['x'], pool_buy_curve['y'], **attr['pool']['buy']['area']) | ||
|
||
a.plot(book_sell_curve['x'], book_sell_curve['y'], **attr['book']['sell']['line']) | ||
a.plot(book_buy_curve['x'], book_buy_curve['y'], **attr['book']['buy']['line']) | ||
a.fill_between(book_sell_curve['x'], book_sell_curve['y'], **attr['book']['sell']['area']) | ||
a.fill_between(book_buy_curve['x'], book_buy_curve['y'], **attr['book']['buy']['area']) | ||
|
||
a.set_xlim(self.pricewindow) | ||
a.set_ylim(bottom=0) | ||
a.ticklabel_format(style='plain') | ||
|
||
a.set_title(self.data.pool.market().get_string(separator=":"), loc="left") | ||
a.set_ylabel("Depth (%s)"%(self.data.pool.asset_y()['symbol'])) | ||
a.set_xlabel("Price (%s/%s)"%(self.data.pool.asset_x()['symbol'], | ||
self.data.pool.asset_y()['symbol'])) | ||
|
||
if self.canvas is None: | ||
self.canvas = FigureCanvasTkAgg(self.fig, self) | ||
self.canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) | ||
self.canvas.draw() |
Oops, something went wrong.