-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathstock.py
120 lines (96 loc) · 4.11 KB
/
stock.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
"""
This file implements a bokeh applet for returns distribution.
It requires a bokeh-server.
See the README.md file in this directory for instructions on running.
"""
import logging
logging.basicConfig(level=logging.DEBUG)
import numpy as np
from bokeh.plotting import figure
from bokeh.models import Plot, ColumnDataSource, DataRange1d, TapTool, Circle
from bokeh.properties import Instance
from bokeh.server.app import bokeh_app
from bokeh.server.utils.plugins import object_page
from bokeh.models.widgets import HBox, VBox, Slider, TextInput, VBoxForm
class StockApp(VBox):
""" Applet for exploring the returns of a stock """
extra_generated_classes = [['StockApp', 'StockApp', 'VBox']]
stock_plot = Instance(Plot)
source = Instance(ColumnDataSource)
@classmethod
def create_stock(cls, source):
# xdr1 = DataRange1d(sources=[source.columns("x")])
# ydr1 = DataRange1d(sources=[source.columns("y")])
# plot1 = figure(title="Outliers", x_range=xdr1, y_range=ydr1, plot_width=650, plot_height=400)
stock_plot = figure(title="", plot_width=650, plot_height=400)
# stock_plot.tools.append(TapTool(plot=stock_plot))
# stock_plot.line(x="x", y="values", size=12, color="blue", line_dash=[2, 4], source=source)
return stock_plot
# plot1.scatter(x="x", y="y", size="size", fill_color="red", source=source)
@classmethod
def create(clz):
"""One-time creation of app's objects.
This function is called once, and is responsible for
creating all objects (plots, datasources, etc)
"""
self = clz()
n_vals = 1000
self.source = ColumnDataSource(
data=dict(
top=[],
bottom=0,
left=[],
right=[],
x= np.arange(n_vals),
values= np.random.randn(n_vals)
))
# Generate a figure container
self.stock_plot = clz.create_stock(self.source)
self.update_data()
self.children.append(self.stock_plot)
def setup_events(self):
"""Attaches the on_change event to the value property of the widget.
The callback is set to the input_change method of this app.
"""
super(StockApp, self).setup_events()
logging.debug("%s" % str(self.source))
# Slider event registration
# self.source.on_change('selected', self, 'on_selection_change')
print("+++++++++++++++++++++++++++++++++")
print(self)
self.stock_plot.on_change('value', self, 'input_change')
# self.outliers_source.on_change('selected', self, 'on_selection_change')
# for w in ["bins"]:
# getattr(self, w).on_change('value', self, 'input_change')
def input_change(self, obj, attrname, old, new):
"""Executes whenever the input form changes.
It is responsible for updating the plot, or anything else you want.
Args:
obj : the object that changed
attrname : the attr that changed
old : old value of attr
new : new value of attr
"""
self.update_data()
def update_data(self):
"""Called each time that any watched property changes.
This updates the sin wave data with the most recent values of the
sliders. This is stored as two numpy arrays in a dict into the app's
data histogram_source property.
"""
logging.debug("update_data")
n_vals = 1000
self.source.data = dict(top=hist, bottom=0, left=0, right = 0, x=np.arange(n_vals), values=np.random.randn(n_vals))
def on_selection_change(self, attr, _, inds, x):
pass
# The following code adds a "/bokeh/sliders/" url to the bokeh-server. This
# URL will render this sine wave sliders app. If you don't want to serve this
# applet from a Bokeh server (for instance if you are embedding in a separate
# Flask application), then just remove this block of code.
@bokeh_app.route("/bokeh/stock/")
@object_page("StockApp")
def make_stock():
logging.debug('creating')
app = StockApp.create()
logging.debug('created')
return app