Skip to content

Commit

Permalink
Merge pull request #3 from Tim55667757/develop
Browse files Browse the repository at this point in the history
Add new features
  • Loading branch information
Tim55667757 authored Feb 19, 2021
2 parents aa0d6d5 + 5e703ab commit 08a43f9
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ deploy:
skip_cleanup: true

after_script:
- echo "Deploy to PyPI finished."
- echo "All PyPI operations done."
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ priceModel.RenderBokeh(fileName="index.html", viewInBrowser=True)
# Instead of the Bokeh library, you can use simple, non-interactive chart,
# via the Google Candlestick chart library. Just uncomment the next lines.
# Before calling priceModel.RenderGoogle(), you can set your custom template in self.j2template
# priceModel.j2template = "google_template.j2" # template by default
# priceModel.j2template = "google_template_example.j2" # file or multi-string variable with jinja2-template
# priceModel.RenderGoogle(fileName="index.html", viewInBrowser=True)
```

Expand Down
2 changes: 1 addition & 1 deletion README_RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ priceModel.RenderBokeh(fileName="index.html", viewInBrowser=True)
# Вместо библиотеки Bokeh вы можете отрисовать цены на простом, не интерактивном графике,
# через библиотеку Google Candlestick chart. Просто раскомментируйте строчки ниже.
# Перед вызовом priceModel.RenderGoogle(), вы можете задать свой шаблон в переменной self.j2template
# priceModel.j2template = "google_template.j2" # шаблон по умолчанию
# priceModel.j2template = "google_template_example.j2" # полный путь до шаблона или мультистроковая переменная с jinja2-шаблоном
# priceModel.RenderGoogle(fileName="index.html", viewInBrowser=True)
```

Expand Down
158 changes: 156 additions & 2 deletions pricegenerator/PriceGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,154 @@
uLogger.handlers[0].level = 20 # info level by default for STDOUT
# uLogger.handlers[1].level = 10 # debug level by default for log.txt

# Simple jinja2 template for rendering static html-page with not interactive Google Candlestick chart:
GOOGLE_TEMPLATE_J2 = """{# This template based on Jinja markup language: http://jinja.pocoo.org/docs/dev/templates/ #}
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<meta charset="utf-8">
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">google.charts.load('current', {'packages': ['corechart']});</script>
<style type="text/css">
#preloader {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #FFFFFF;
z-index: 99;
}
#status {
width: 300px;
height: 150px;
position: absolute;
left: 50%;
top: 50%;
background-image: url(https://raw.githubusercontent.com/niklausgerber/PreLoadMe/master/img/status.gif);
background-repeat: no-repeat;
background-position: left;
margin: -100px 0 0 -100px;
font-family: "Segoe UI", "Frutiger", "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", "Arial", sans-serif;
font-size: 14px;
}
pre {
font-family: "Lucida Console", sans-serif;
font-size: 11px;
padding: 0;
border-width: 0 0 0 0;
}
table {
font-family: "Segoe UI", "Frutiger", "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", "Arial", sans-serif;
font-size: 12px;
border-spacing: 0;
text-align: left;
background: white;
width: 100%;
}
th {
border-radius: 10px 10px 10px 10px;
border-style: solid;
border-width: 0 1px 1px 0;
border-color: white;
padding: 6px;
vertical-align: middle;
padding-left: 1em;
background: #E6E6E6;
height: 50px;
}
td {
border-radius: 10px 10px 10px 10px;
border-style: solid;
border-width: 0 1px 1px 0;
border-color: white;
padding: 6px;
vertical-align: top;
padding-left: 1em;
background: white;
}
</style>
<script>
function drawChartCandlesticks(candlesData) {
var chartOptions = {
legend: "none",
titlePosition: "in",
chartArea: {width: "100%", height: "100%"},
fontSize: 11,
candlestick: {
fallingColor: {stroke: "#000000", strokeWidth: 1, fill: "#999999"},
risingColor: {stroke: "#000000", strokeWidth: 1, fill: "#FFFFFF"},
},
colors: ["#000000"],
hAxis: {textPosition: "none"},
vAxis: {textPosition: "in", textStyle: {fontSize: 12}},
}
if (typeof candlesData !== "undefined") {
var data = google.visualization.arrayToDataTable(candlesData, true);
var chart = new google.visualization.CandlestickChart(document.getElementById("candlestickChart"));
chart.draw(data, chartOptions);
}
}
</script>
</head>
<body onload="drawChartCandlesticks({{ candlesData }})">
<!-- Preloader -->
<script>
$(window).on('load', function() {
$('#status').fadeOut('slow');
$('#preloader').fadeOut('slow');
})
</script>
<div id="preloader">
<div id="status">Wait...</div>
</div>
<!-- Chart part -->
<table id="chart">
<tr>
<th style="width: 75%;">
<b>{{ title }}</b>
</th>
<th>
<b>Info</b>
</th>
</tr>
<tr>
<td>
<div id="candlestickChart" style="height: 800px; width: 100%;"></div>
</td>
<td>
{% for line in info %}
<pre>{{ line }}</pre>
{% endfor %}
</td>
</tr>
</table>
<!-- Footer -->
<table>
<tr>
<th><b>Generated by <a href="https://github.com/Tim55667757/PriceGenerator">PriceGenerator</a></b></th>
</tr>
</table>
</body>
</html>
"""


class PriceGenerator:
"""
Expand All @@ -45,7 +193,7 @@ def __init__(self):
self.csvHeaders = ["date", "time", "open", "high", "low", "close", "volume"] # headers if .csv-file used
self.dfHeaders = ["datetime", "open", "high", "low", "close", "volume"] # dataframe headers
self.sep = "," # Separator in csv-file
self.j2template = "google_template.j2" # path to custom jinja2 html template
self.j2template = GOOGLE_TEMPLATE_J2 # full path to custom jinja2 html template (e.g. "google_template_example.j2") or template as a long multi-string variable
self.j2model = None # dictionary of variables for jinja2 template, if None then auto-generating for default google_template.j2

self._precision = 2 # signs after comma
Expand Down Expand Up @@ -650,8 +798,14 @@ def RenderGoogle(self, fileName="index.html", viewInBrowser=False):
uLogger.debug("Using custom chart model")

# --- Rendering and saving chart as html-file and markdown-file with statistics:
renderedTemplate = jinja2.Template(open(self.j2template, "r", encoding="UTF-8").read())
if os.path.exists(self.j2template):
renderedTemplate = jinja2.Template(open(self.j2template, "r", encoding="UTF-8").read())

else:
renderedTemplate = jinja2.Template(self.j2template)

htmlMain = renderedTemplate.render(self.j2model)

with open(fileName, "w", encoding="UTF-8") as fH:
fH.write(htmlMain)
with open("{}.md".format(fileName), "w", encoding="UTF-8") as fH:
Expand Down
File renamed without changes.
21 changes: 8 additions & 13 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from setuptools import setup
import os

__version__ = "1.0"
__version__ = "1.1"

devStatus = "4 - Beta"

Expand Down Expand Up @@ -74,10 +74,6 @@
"testdata",
],

packages=[
"pricegenerator",
],

tests_require=[
"pytest>=5.3.5",
"pandas>=1.0.1",
Expand All @@ -89,17 +85,16 @@
"bokeh>=1.4.0",
],

packages=[
"pricegenerator",
],

package_data={
"": [
"./pricegenerator/*.py",
"./media/*",
"./tests/*",

"LICENSE",
"README.md",
"README_RU.md",
"pricegenerator": [
"*.j2",
],
},

include_package_data=True,
zip_safe=True,
)
12 changes: 11 additions & 1 deletion tests/test_PriceGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,17 @@ def test_RenderBokeh(self):
assert os.path.exists(name), "Expected .html-file '{}' after saving but it is not exist!".format(name)
assert os.path.exists(nameMD), "Expected markdown file '{}' after saving but it is not exist!".format(nameMD)

def test_RenderGoogle(self):
def test_RenderGoogleDefault(self):
self.model.horizon = 5
self.model.Generate()
suffix = random.uniform(0, 1000000000)
name = "test_render_google{}.html".format(suffix)
nameMD = "{}.md".format(name)
self.model.RenderGoogle(fileName=name, viewInBrowser=False)
assert os.path.exists(name), "Expected .html-file '{}' after saving but it is not exist!".format(name)
assert os.path.exists(nameMD), "Expected markdown file '{}' after saving but it is not exist!".format(nameMD)

def test_RenderGoogleFromFileTemplate(self):
self.model.horizon = 5
self.model.Generate()
suffix = random.uniform(0, 1000000000)
Expand Down

0 comments on commit 08a43f9

Please sign in to comment.