Current section
Files
Jump to
Current section
Files
priv/chart.py
import numpy as np
from bokeh.layouts import column
from bokeh.plotting import figure, show, output_file
from bokeh.models import LinearAxis, Range1d
from bokeh.models.annotations import Title
import json
import collections
def datetime(x):
return np.array(x, dtype=np.datetime64)
def create_plot(chart_title):
plot = figure(x_axis_type="datetime", title=chart_title, plot_height=500, width=1000)
plot.grid.grid_line_alpha = 0.3
plot.xaxis.axis_label = 'Date'
plot.yaxis.axis_label = 'Price'
return plot
def create_plot_oscillator(related_plot):
plot = figure(x_axis_type="datetime", x_range=related_plot.x_range, plot_height=150, width=1000)
plot.grid.grid_line_alpha = 0.3
plot.xaxis.axis_label = 'Date'
plot.yaxis.axis_label = 'Value'
return plot
def create_plot_trades(related_plot):
plot = figure(x_axis_type="datetime", x_range=related_plot.x_range, plot_height=150, width=1000)
plot.grid.grid_line_alpha = 0.3
plot.xaxis.axis_label = 'Date'
plot.yaxis.axis_label = 'Price'
return plot
def add_line_to_plot(plot, data_title, data_date, data_close, color):
plot.line(datetime(data_date), data_close, color=color, legend=data_title)
return plot
def add_line_to_plot_with_yrange(plot, data_title, data_date, data_close, color, y_range_name):
plot.line(datetime(data_date), data_close, color=color, legend=data_title, y_range_name=y_range_name)
return plot
def add_up_to_plot(plot, data_title, data_date, data_close, color="green"):
plot.triangle(x=datetime(data_date), y=data_close, color=color, legend=data_title)
return plot
def add_down_to_plot(plot, data_title, data_date, data_close, color="red"):
plot.inverted_triangle(x=datetime(data_date), y=data_close,
color=color, legend=data_title)
return plot
def show_plot(plot, oscillator, trades):
plot.legend.location = "top_left"
oscillator.legend.location = "top_left"
trades.legend.location = "top_left"
output_file("chart.html", title=plot.title.text)
show(column(children=[plot, oscillator, trades]))
def create_show_single_plot(chart_title):
plot = create_plot(chart_title)
plot.legend.location = "top_left"
output_file("chart.html", title=plot.title.text)
show(column(children=[plot]))
def show_single_plot(plot):
plot.legend.location = "top_left"
output_file("chart.html", title=plot.title.text)
show(column(children=[plot]))
def make_chart(pair_name: str, data: [], more_data: str, date_data: [], oscillator_data: [{}], trade_history_json: str):
trade_history = json.loads(trade_history_json)
# convert keys to integer since json encoder in Elixir convert keys to string
trade_history_unsorted = {int(k):v for k,v in trade_history.items()}
# also it needs to be sorted
trade_history = {}
for key in sorted(trade_history_unsorted):
trade_history[key] = trade_history_unsorted[key]
# 1. create main chart and add series to it
plot = create_plot(pair_name)
line_colors = ['lightgray', 'blue', 'maroon']
add_line_to_plot(plot, pair_name, date_data, data, line_colors[0])
# 2. Add BUY and SELL points to the main char
buy_indexes = [x for x in trade_history if trade_history[x]['type'] == 'BUY']
buy_prices = [data[x] for x in buy_indexes]
buy_dates = [date_data[x] for x in buy_indexes]
sell_indexes = [x for x in trade_history if trade_history[x]['type'] == 'SELL']
sell_prices = [data[x] for x in sell_indexes]
sell_dates = [date_data[x] for x in sell_indexes]
add_up_to_plot(plot, "Buys", buy_dates, buy_prices)
add_down_to_plot(plot, "Sells", sell_dates, sell_prices)
if more_data != "":
more_data_dict = json.loads(more_data)
plot.extra_y_ranges = {"ind": Range1d(start=min(data), end=max(data))}
plot.add_layout(LinearAxis(y_range_name="ind", axis_label="Ind"), 'right')
i = 0
for key in more_data_dict:
i += 1
if i >2:
i = 0
add_line_to_plot(plot, key, date_data, more_data_dict[key], line_colors[i])
# 3. Create oscillator and add series to it
oscillator = create_plot_oscillator(plot)
def add_to_oscillator(item):
add_line_to_plot(oscillator, decode_str(item[b'title']), date_data, item[b'data'], line_colors[0])
list(map(add_to_oscillator, oscillator_data))
# 4. Add Cach + buy and sell data
trades = create_plot_trades(plot)
if len(trade_history) > 0:
cash_history = [trade_history[x]['cash'] for x in trade_history]
cash_dates = [date_data[x] for x in trade_history]
cash_min = min(cash_history)
cash_max = max(cash_history)
add_up_to_plot(trades, "Buys", buy_dates, buy_prices)
add_down_to_plot(trades, "Sells", sell_dates, sell_prices)
trades.extra_y_ranges = {"cash": Range1d(start=cash_min/1.2, end=cash_max*1.2)}
trades.add_layout(LinearAxis(y_range_name="cash", axis_label="Cash"), 'right')
add_line_to_plot_with_yrange(trades, "Cash", cash_dates, cash_history, line_colors[0], 'cash')
return (plot, oscillator, trades)
def make_chart_and_show(pair_name: str, data: [], more_data: str, date_data: [], oscillator_data: [{}], trade_history: {}):
pair_name = decode_str(pair_name)
date_data = decode_str_array(date_data)
more_data = decode_str(more_data)
plot, oscillator, trades = make_chart(pair_name, data, more_data, date_data, oscillator_data, trade_history)
show_plot(plot, oscillator, trades)
def decode_str(str):
return ''.join(chr(i) for i in str)
def decode_str_array(str_arr: []):
return [decode_str(s) for s in str_arr]