In [ ]:
import pandas as pd
import json
from pandas_datareader import data
from datetime import datetime, timedelta
from pixiedust.display.app import *
@PixieApp
class StockViewer():
"""
Sample Stock Viewer PixieApp with live quotes
"""
def setup(self):
self.tickers = {}
self.start = datetime(2014,1,1)
self.end = datetime.today()
self.show = "table"
self.measurements = ["Open", "Close", "High", "Low", "Volume"]
self.sel_measurement = self.measurements[0]
self.dateranges = [(30,"1M"), (90,"3M"), (180,"6M"), (365,"1Y"), (730,"2Y")]
self.sel_daterange = self.dateranges[0][0]
self.pixieapp_entity = None
self.provider = "yahoo"
self.providers = ["google", "yahoo", "yahoo-actions", "yahoo-dividends", "enigma", "fred",
"famafrench", "oecd", "eurostat", "edga-index", "nasdaq", "quandl"]
def enable_ticker(self, ticker, enable):
if ticker in self.tickers:
self.tickers[ticker]["enable"] = (enable == "true")
self.updatePDF()
def update_measurement(self, measurement):
self.sel_measurement=measurement
self.updatePDF()
def update_daterange(self, daterange):
self.sel_daterange=daterange
self.updatePDF()
def update_provider(self, provider):
self.provider = provider
#rebuild all ticker dataframes
self.pixieapp_entity = None
for ticker in self.tickers:
self.add_ticker(ticker)
def updatePDF(self):
df = pd.DataFrame({k: v['pdf'][self.sel_measurement] for k,v in self.tickers.items() if v['enable'] is True})
self.pixieapp_entity = df[(datetime.today()-timedelta(days=self.sel_daterange)):datetime.today()]
self.pixieapp_entity.reset_index(inplace=True)
def add_ticker(self, ticker):
try:
self.tickers[ticker] = {
"pdf" : data.DataReader(ticker,self.provider,self.start,self.end),
"enable": True,
"exception":None
}
self.updatePDF()
print("Successfully added {}.".format(ticker))
except Exception as exc:
self.tickers[ticker]["exception"] = exc
print("Ticker not found. Please enter a valid ticker. {}".format(exc))
@route(tickersList="*")
def tickers_list(self):
return """
{%for ticker in this.tickers%}
<input type="checkbox" checked id="{{ticker}}{{prefix}}"
pd_script="self.enable_ticker('{{ticker}}', '$val({{ticker}}{{prefix}})')"
pd_refresh="target{{prefix}}">
{{ticker}}
{%endfor%}
"""
def get_pd_options(self):
ret_value = {
"noChartCache": "true"
}
if self.show == "table":
ret_value.update({
"handlerId":"dataframe"
})
else:
ret_value.update({
"handlerId": "lineChart",
"keyFields": "Date",
"aggregation": "SUM",
"rowCount":"1000",
"timeseries":"true",
"valueFields":",".join(list(self.tickers.keys()))
})
return json.dumps(ret_value)
@route(tickersContent="*")
def tickers_content(self):
if self.pixieapp_entity is None:
return "<div/>"
return """
<div pd_entity pd_render_onload>
<pd_options>
{{this.get_pd_options()}}
</pd_options>
</div>
"""
@route()
def default(self):
return """
<div class="row">
<center>
<label>Provider:</label>
<select id="provider{{prefix}}" pd_script="self.update_provider('$val(provider{{prefix}})')" pd_refresh="target{{prefix}}">
{%for provider in this.providers %}
<option {%if provider==this.provider%}selected{%endif%} value="{{provider}}">{{provider}}</option>
{%endfor%}
</select>
</center>
</div>
<div class="row">
<div class="form-group col-sm-2" style="padding-right:10px;">
<p>
<label>1. Add tickers</label>
</p>
<p>
<input id="t" name="tickerInput">
</p>
<p>
<button type="submit" id="check" pd_script="self.add_ticker('$val(t)')" pd_refresh="tickersList{{prefix}},target{{prefix}}">
Add
</button>
</p>
<p>
<label>2. Select measurement, date range</label>
</p>
<p>
<select id="measurement{{prefix}}" pd_model="measurement"
pd_script="self.update_measurement('$val(measurement{{prefix}})')" pd_refresh="target{{prefix}}">
{%for measurement in this.measurements %}
<option value="{{measurement}}">{{measurement}}</option>
{%endfor%}
</select>
</p>
<p>
<select id="dateRange{{prefix}}"
pd_script="self.update_daterange($val(dateRange{{prefix}}))" pd_refresh="target{{prefix}}">
{%for daterange in this.dateranges %}
<option value="{{daterange[0]}}">{{daterange[1]}}</option>
{%endfor%}
</select>
</p>
<p>
<label>3. Visualize</label>
</p>
<p>
<button type="submit" class="btn btn-primary" pd_refresh="target{{prefix}}" pd_script="self.show='table'">
Preview as nice table
</button>
</p>
<p>
<button type="submit" class="btn btn-primary" pd_refresh="target{{prefix}}" pd_script="self.show='line'">
Line chart
</button>
</p>
</div>
<div class="form-group col-sm-4 no_loading_msg" id="tickersList{{prefix}}" pd_render_onload pd_options="tickersList=true">
</div>
<div class="form-group col-sm-10" id="target{{prefix}}" pd_render_onload pd_options="tickersContent=true">
</div>
</div>
"""
a = StockViewer()
a.run(runInDialog='false')