Skip to content

Commit

Permalink
#17 new param was added: nbInLine, if True, then output chart in …
Browse files Browse the repository at this point in the history
…Jupyter Notebook cell. `False` by default.
  • Loading branch information
Tim55667757 committed Jan 1, 2023
1 parent 640b278 commit d1efd5c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
38 changes: 26 additions & 12 deletions pricegenerator/PriceGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
from bokeh.plotting import figure, save, output_file, ColumnDataSource
from bokeh.models import Legend, HoverTool, Range1d, NumeralTickFormatter
from bokeh.layouts import gridplot
from bokeh.io import output_notebook,show
from bokeh.resources import INLINE
import jinja2

import pricegenerator.UniLogger as uLog
Expand Down Expand Up @@ -602,7 +604,7 @@ def GetStatistics(self):
" - 99 percentile: ≤ {}".format(round(self.stat["deltas"]["q99"], self.precision)),
" - 95 percentile: ≤ {}".format(round(self.stat["deltas"]["q95"], self.precision)),
" - 80 percentile: ≤ {}".format(round(self.stat["deltas"]["q80"], self.precision)),
"- Cumulative sum of volumes: {}".format(self.stat["cumSumVolumes"]),
"- Cumulative sum of volumes: {}".format(self.stat["cumSumVolumes"]),
]

uLogger.info("Some statistical info:\n{}".format("\n".join(summary)))
Expand Down Expand Up @@ -781,7 +783,7 @@ def RenderBokeh(
self, fileName: Optional[str] = "index.html", viewInBrowser: bool = False,
darkTheme: bool = False, layouts: Optional[list] = None,
title: Optional[str] = None, width: Optional[int] = 1800, height: Optional[int] = 990,
showStatOnChart: bool = True, showControlsOnChart: bool = True,
showStatOnChart: bool = True, showControlsOnChart: bool = True, nbInLine: bool = False,
) -> Optional[gridplot]:
"""
Rendering prices from Pandas DataFrame as OHLCV Bokeh chart of candlesticks and save it to HTML-file.
Expand All @@ -799,12 +801,9 @@ def RenderBokeh(
:param height: chart height. If `None`, then used auto-height. 990 px by default.
:param showStatOnChart: add statistics block on chart, `True` by default.
:param showControlsOnChart: add controls block on chart, `True` by default.
:param nbInLine: if `True`, then output chart in Jupyter Notebook cell. `False` by default.
:return: bokeh.layouts.gridplot with all layouts objects or None.
"""
title = self._chartTitle if title is None or not title else title # chart title
width = 1200 if width is None or width <= 0 else width # chart summary width
height = 800 if height is None or height <= 0 else height - 90 # chart summary height

if self.prices is None or self.prices.empty:
raise Exception("Empty price data! Generate or load prices before show as Bokeh chart!")

Expand All @@ -814,8 +813,15 @@ def RenderBokeh(
self.DetectTimeframe() # auto-detect time delta between last two neighbour candles
infoBlock = self.GetStatistics() # calculating some indicators

title = self._chartTitle if title is None or not title else title # chart title
width = 1200 if width is None or width <= 0 else width # chart summary width
height = 800 if height is None or height <= 0 else height - 90 # chart summary height

uLogger.debug("Preparing Bokeh chart configuration...")
uLogger.debug("Title: {}".format(self._chartTitle))
uLogger.debug("Title: {}".format(title))

if nbInLine:
output_notebook(resources=INLINE, verbose=False, hide_banner=True) # set output to notebook cell

# --- Preparing Main chart:
chart = figure(
Expand Down Expand Up @@ -1180,26 +1186,32 @@ def RenderBokeh(
)
unionChart.toolbar.logo = None

if nbInLine:
show(unionChart)

# preparing html-file chart and statistics in markdown:
if fileName:
output_file(fileName, title=self._chartTitle, mode="cdn")
save(unionChart)
with open("{}.md".format(fileName), "w", encoding="UTF-8") as fH:
fH.write("\n".join(infoBlock))

uLogger.info("Pandas dataframe rendered as html-file [{}]".format(os.path.abspath(fileName)))

if viewInBrowser:
os.system(os.path.abspath(fileName)) # view forecast chart in default browser immediately

uLogger.info("Pandas dataframe rendered as html-file [{}]".format(os.path.abspath(fileName)))

return unionChart

def RenderGoogle(self, fileName="index.html", viewInBrowser=False):
def RenderGoogle(self, fileName: str = "index.html", viewInBrowser: bool = False, title: Optional[str] = None):
"""
Rendering prices from pandas dataframe to not interactive Google Candlestick chart and save to html-file.
See: https://developers.google.com/chart/interactive/docs/gallery/candlestickchart
See also: https://developers.google.com/chart/interactive/docs/gallery/candlestickchart
:param fileName: html-file path to save Google Candlestick chart.
:param viewInBrowser: If True, then immediately opens html in browser after rendering.
:param title: specific chart title. If `None`, then used auto-generated title. `None` by default.
"""
if self.prices is None or self.prices.empty:
raise Exception("Empty price data! Generate or load prices before show as Google Candlestick chart!")
Expand All @@ -1210,9 +1222,11 @@ def RenderGoogle(self, fileName="index.html", viewInBrowser=False):
self.DetectTimeframe() # auto-detect time delta between last two neighbour candles
infoBlock = self.GetStatistics() # calculating some indicators

title = self._chartTitle if title is None or not title else title # chart title

if self.j2model is None or not self.j2model:
uLogger.debug("Preparing Google Candlestick chart configuration...")
self.j2model = {"info": infoBlock, "title": self._chartTitle}
self.j2model = {"info": infoBlock, "title": title}
googleDates = [pd.to_datetime(date).strftime("%Y-%m-%d %H:%M:%S") for date in self.prices.datetime.values]
data = zip(googleDates, self.prices.low, self.prices.open, self.prices.close, self.prices.high)
self.j2model["candlesData"] = [list(x) for x in data]
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ numpy >= 1.20.1 # BSD-3-Clause license
matplotlib >= 3.3.4 # PSF license
python-dateutil >= 2.8.1 # Apache-2.0 license
jinja2 >= 2.11.3 # BSD-3-Clause license
pandas_ta >= 0.3.14b0 # MIT License
pandas_ta >= 0.3.14b0 # MIT License
notebook >= 6.5.2 # BSD License

0 comments on commit d1efd5c

Please sign in to comment.