kyoslib_py 5.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kyoslib_py/__init__.py +0 -0
- kyoslib_py/forward_curve.py +228 -0
- kyoslib_py/front_end.py +388 -0
- kyoslib_py/historical_price.py +535 -0
- kyoslib_py/kyos_api.py +95 -0
- kyoslib_py/kyos_utils.py +201 -0
- kyoslib_py/settings.py +1270 -0
- kyoslib_py/simulation.py +2214 -0
- kyoslib_py/tradable_product.py +470 -0
- kyoslib_py/valuation_interface.py +732 -0
- kyoslib_py-5.4.4.dist-info/LICENSE.txt +21 -0
- kyoslib_py-5.4.4.dist-info/METADATA +81 -0
- kyoslib_py-5.4.4.dist-info/RECORD +15 -0
- kyoslib_py-5.4.4.dist-info/WHEEL +4 -0
- kyoslib_py-5.4.4.dist-info/entry_points.txt +3 -0
kyoslib_py/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
from kyoslib_py.kyos_api import call_kyos_api_v1
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def write_curve_to_csv(curves, delTypes, grID, fullFileName):
|
|
9
|
+
"""
|
|
10
|
+
Stores the forward curves in generalized data format on the disk in ./ForwardCurves
|
|
11
|
+
directory.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
curves (dict): HTTP response body which provided by kyos_api.call_kyos_api_v1
|
|
15
|
+
delTypes (list): baseload:1, peak:2, offpeak:3
|
|
16
|
+
grID (int): granularity id of the requested forward curve(e.g. half-hour:1, hour:2, day:3, month:5)
|
|
17
|
+
fullFileName (str): full path of the file(e.g. "./ForwardCurves/ForwardCurveDaily_2_20200101")
|
|
18
|
+
|
|
19
|
+
Note:
|
|
20
|
+
The current implementation allows to store only data based on monthly granularity.
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
>>> from kyoslib_py.forward_curve import write_curve_to_csv
|
|
24
|
+
>>> curves = {}
|
|
25
|
+
>>> data = {}
|
|
26
|
+
>>> month = {}
|
|
27
|
+
>>> baseload = [{'date':'2020-01-01', 'value':20.2}, {'date':'2020-02-01', 'value':30.3}]
|
|
28
|
+
>>> month['baseload'] = baseload
|
|
29
|
+
>>> data['month'] = month
|
|
30
|
+
>>> curves['data'] = data
|
|
31
|
+
>>> write_curve_to_csv(curves, [1, 2, 3], 5, "./ForwardCurves/ForwardCurveMonthlyDeliveryTypes_2_20200101")
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
if grID == 1: # half-hourly
|
|
35
|
+
return
|
|
36
|
+
elif grID == 2: # hourly
|
|
37
|
+
return
|
|
38
|
+
elif grID == 3: # daily
|
|
39
|
+
return
|
|
40
|
+
elif grID == 5: # monthly
|
|
41
|
+
curves_df = pd.DataFrame()
|
|
42
|
+
numDelType = len(delTypes)
|
|
43
|
+
# read dates from base load and store in the table, column name should be "0" for the date column
|
|
44
|
+
curves_df['0'] = [x['date'] for x in curves['data']['month']['baseload']]
|
|
45
|
+
|
|
46
|
+
for i in range(numDelType):
|
|
47
|
+
if delTypes[i] == 1:
|
|
48
|
+
curves_df[str(delTypes[i])] = [
|
|
49
|
+
x['value'] for x in curves['data']['month']['baseload']
|
|
50
|
+
]
|
|
51
|
+
elif delTypes[i] == 2:
|
|
52
|
+
curves_df[str(delTypes[i])] = [
|
|
53
|
+
x['value'] for x in curves['data']['month']['peakload']
|
|
54
|
+
]
|
|
55
|
+
elif delTypes[i] == 3:
|
|
56
|
+
curves_df[str(delTypes[i])] = [
|
|
57
|
+
x['value'] for x in curves['data']['month']['offpeak']
|
|
58
|
+
]
|
|
59
|
+
# write monthly curves to csv
|
|
60
|
+
curves_df.to_csv(fullFileName, index=False)
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_curve_api(fwdCurveID, granularityID, deliveryTypes, tradingDates, isCSVWrite):
|
|
65
|
+
"""
|
|
66
|
+
Performs API requests to KYOS API and stores the curve inputs in a generalized format in CSV
|
|
67
|
+
files or returns a pandas.DataFrame.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
fwdCurveID (int): id of the curve profile
|
|
71
|
+
granularityID (int): half-hour:1, hour:2, day:3, month:5
|
|
72
|
+
deliveryTypes (list|int): list of delivery type ids(int array), base load:1, peak:2, off-peak:3
|
|
73
|
+
tradingDates (list): list of trading dates(string array) e.g. ['2019-01-01', '2019-01-02', '2019-01-03']
|
|
74
|
+
isCSVWrite (bool): indicator of creating csv files, 0 or 1, we will provide a DataFrame in case of zero.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
(pandas.DataFrame): Contains all requested curves. If isCSVWrite equals 1 then the dataframe will be empty and
|
|
78
|
+
the curves will be saved as CSV files on the disk in directory ./ForwardCurves.
|
|
79
|
+
|
|
80
|
+
Note:
|
|
81
|
+
KYOS API provides the curves with the daylight saving switches for the half-hourly and hourly curves.
|
|
82
|
+
KYOS API supports base load, peak and off-peak delivery types only for monthly granularity.
|
|
83
|
+
|
|
84
|
+
Examples:
|
|
85
|
+
>>> from kyoslib_py.forward_curve import get_curve_api
|
|
86
|
+
>>> arg = {'fwdCurveID': 4, 'granularityID': 5, 'deliveryTypes': [1, 2, 3],
|
|
87
|
+
>>> 'tradingDates': ['2019-01-01', '2019-01-02'], 'isCSVWrite': 1}
|
|
88
|
+
>>> curves_df = get_curve_api(**arg)
|
|
89
|
+
>>> arg = {'fwdCurveID': 4, 'granularityID': 5, 'deliveryTypes': 1 ,
|
|
90
|
+
>>> 'tradingDates': '2019-01-01', 'isCSVWrite': 1}
|
|
91
|
+
>>> curves_df2 = get_curve_api(**arg)
|
|
92
|
+
"""
|
|
93
|
+
# Initialize output directory
|
|
94
|
+
curDir = os.getcwd()
|
|
95
|
+
outputDir = os.path.join(curDir, 'ForwardCurves')
|
|
96
|
+
if isCSVWrite and (not os.path.exists(outputDir)):
|
|
97
|
+
os.mkdir(outputDir)
|
|
98
|
+
forward_curves_df = pd.DataFrame()
|
|
99
|
+
# ################################ INPUT VALIDATION ###########################################
|
|
100
|
+
# Check the granularity input
|
|
101
|
+
if granularityID == 1:
|
|
102
|
+
fileName = f"ForwardCurveHalfHourlyDST_{fwdCurveID}_"
|
|
103
|
+
granularity = 'half_hour'
|
|
104
|
+
elif granularityID == 2:
|
|
105
|
+
fileName = f"ForwardCurveHourlyDST_{fwdCurveID}_"
|
|
106
|
+
granularity = 'hour'
|
|
107
|
+
elif granularityID == 3:
|
|
108
|
+
fileName = f"ForwardCurveDaily_{fwdCurveID}_"
|
|
109
|
+
granularity = 'day'
|
|
110
|
+
elif granularityID == 5:
|
|
111
|
+
fileName = f"ForwardCurveMonthlyDeliveryTypes_{fwdCurveID}_"
|
|
112
|
+
granularity = 'month'
|
|
113
|
+
else:
|
|
114
|
+
print('The granularity id:' + str(granularityID) + ' is not supported in KYOS API!!!')
|
|
115
|
+
return forward_curves_df
|
|
116
|
+
# in case of empty delivery type after the cleaning process, initialize base load in the list
|
|
117
|
+
if deliveryTypes is None:
|
|
118
|
+
deliveryTypes = [1]
|
|
119
|
+
|
|
120
|
+
# Check the delivery type input, deliveryTypes should be a list
|
|
121
|
+
if type(deliveryTypes) != list:
|
|
122
|
+
deliveryTypes = [deliveryTypes]
|
|
123
|
+
if len(deliveryTypes) == 0:
|
|
124
|
+
deliveryTypes.append(1) # in case of empty delivery type list, import the base load curve
|
|
125
|
+
else:
|
|
126
|
+
# remove the unsupported delivery types from the list
|
|
127
|
+
deliveryTypes = [
|
|
128
|
+
deliveryTypes for deliveryTypes in deliveryTypes if deliveryTypes in [1, 2, 3]
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
# Check tradingDates, it should be provided as a list
|
|
132
|
+
if type(tradingDates) != list:
|
|
133
|
+
tradingDates = [tradingDates]
|
|
134
|
+
|
|
135
|
+
# ########################################### IMPORT CURVES #######################################################
|
|
136
|
+
numTradDays = tradingDates.__len__()
|
|
137
|
+
for i in range(numTradDays):
|
|
138
|
+
tradingDate_i = tradingDates[i]
|
|
139
|
+
query = f"/curves/results/{fwdCurveID}/{tradingDate_i}?filter[granularity]={granularity}"
|
|
140
|
+
|
|
141
|
+
status, data = call_kyos_api_v1(query)
|
|
142
|
+
if 200 >= status < 300:
|
|
143
|
+
if isCSVWrite == 1: # in this case, we will store the curves on disk per trading dates
|
|
144
|
+
fullName = os.path.join(
|
|
145
|
+
outputDir, f"{fileName}{tradingDate_i.replace('-', '')}.csv"
|
|
146
|
+
)
|
|
147
|
+
write_curve_to_csv(data, deliveryTypes, granularityID, fullName)
|
|
148
|
+
else: # in this case, we will store the curves in a dataframe
|
|
149
|
+
curves_df_i = pd.DataFrame()
|
|
150
|
+
numDelType = len(deliveryTypes)
|
|
151
|
+
# update curve id and trading dates column
|
|
152
|
+
if granularityID == 1: # half-hourly
|
|
153
|
+
if data.get('data'):
|
|
154
|
+
numHhours = data['data']['half_hour']['baseload'].__len__()
|
|
155
|
+
curves_df_i['curve_id'] = [fwdCurveID for _ in range(numHhours)]
|
|
156
|
+
curves_df_i['trading_dates'] = [tradingDate_i for _ in range(numHhours)]
|
|
157
|
+
|
|
158
|
+
# read dates from base load and store in the table as delivery dates
|
|
159
|
+
curves_df_i['delivery_dates'] = [
|
|
160
|
+
x['date'] for x in data['data']['half_hour']['baseload']
|
|
161
|
+
]
|
|
162
|
+
curves_df_i['baseload'] = [
|
|
163
|
+
x['value'] for x in data['data']['half_hour']['baseload']
|
|
164
|
+
]
|
|
165
|
+
else:
|
|
166
|
+
print('There is no ' + granularity + ' curve for this profile!')
|
|
167
|
+
return forward_curves_df
|
|
168
|
+
elif granularityID == 2: # hourly
|
|
169
|
+
if data.get('data'):
|
|
170
|
+
numHours = data['data']['hour']['baseload'].__len__()
|
|
171
|
+
curves_df_i['curve_id'] = [fwdCurveID for _ in range(numHours)]
|
|
172
|
+
curves_df_i['trading_dates'] = [tradingDate_i for _ in range(numHours)]
|
|
173
|
+
|
|
174
|
+
# read dates from base load and store in the table as delivery dates
|
|
175
|
+
curves_df_i['delivery_dates'] = [
|
|
176
|
+
x['date'] for x in data['data']['hour']['baseload']
|
|
177
|
+
]
|
|
178
|
+
curves_df_i['baseload'] = [
|
|
179
|
+
x['value'] for x in data['data']['hour']['baseload']
|
|
180
|
+
]
|
|
181
|
+
else:
|
|
182
|
+
print('There is no ' + granularity + ' curve for this profile!')
|
|
183
|
+
return forward_curves_df
|
|
184
|
+
elif granularityID == 3: # daily
|
|
185
|
+
if data.get('data'):
|
|
186
|
+
numDays = data['data']['day']['baseload'].__len__()
|
|
187
|
+
curves_df_i['curve_id'] = [fwdCurveID for _ in range(numDays)]
|
|
188
|
+
curves_df_i['trading_dates'] = [tradingDate_i for _ in range(numDays)]
|
|
189
|
+
|
|
190
|
+
# read dates from base load and store in the table as delivery dates
|
|
191
|
+
curves_df_i['delivery_dates'] = [
|
|
192
|
+
x['date'] for x in data['data']['day']['baseload']
|
|
193
|
+
]
|
|
194
|
+
curves_df_i['baseload'] = [
|
|
195
|
+
x['value'] for x in data['data']['day']['baseload']
|
|
196
|
+
]
|
|
197
|
+
else:
|
|
198
|
+
print('There is no ' + granularity + ' curve for this profile!')
|
|
199
|
+
return forward_curves_df
|
|
200
|
+
elif granularityID == 5: # monthly
|
|
201
|
+
numMonths = data['data']['month']['baseload'].__len__()
|
|
202
|
+
curves_df_i['curve_id'] = [fwdCurveID for _ in range(numMonths)]
|
|
203
|
+
curves_df_i['trading_dates'] = [tradingDate_i for _ in range(numMonths)]
|
|
204
|
+
|
|
205
|
+
# read dates from base load and store in the table as delivery dates
|
|
206
|
+
curves_df_i['delivery_dates'] = [
|
|
207
|
+
x['date'] for x in data['data']['month']['baseload']
|
|
208
|
+
]
|
|
209
|
+
for i in range(numDelType):
|
|
210
|
+
if deliveryTypes[i] == 1:
|
|
211
|
+
curves_df_i['baseload'] = [
|
|
212
|
+
x['value'] for x in data['data']['month']['baseload']
|
|
213
|
+
]
|
|
214
|
+
elif deliveryTypes[i] == 2:
|
|
215
|
+
curves_df_i['peak'] = [
|
|
216
|
+
x['value'] for x in data['data']['month']['peakload']
|
|
217
|
+
]
|
|
218
|
+
elif deliveryTypes[i] == 3:
|
|
219
|
+
curves_df_i['offpeak'] = [
|
|
220
|
+
x['value'] for x in data['data']['month']['offpeak']
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
forward_curves_df = pd.concat([forward_curves_df, curves_df_i])
|
|
224
|
+
print(query + ' Imported!')
|
|
225
|
+
else:
|
|
226
|
+
print(query + ' could not be imported!')
|
|
227
|
+
|
|
228
|
+
return forward_curves_df
|
kyoslib_py/front_end.py
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import csv
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import plotly.express as px
|
|
7
|
+
from plotly.io import write_json as plotly_write_json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PlatformGraphs(object):
|
|
11
|
+
"""
|
|
12
|
+
Handle the mapping of plotly graphs to a format which can be displayed by the KYOS platform.
|
|
13
|
+
There can be at most one instance of this class (singleton design pattern).
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
_instance = None # keep instance reference
|
|
17
|
+
|
|
18
|
+
def __new__(cls):
|
|
19
|
+
if not cls._instance:
|
|
20
|
+
cls._instance = super(PlatformGraphs, cls).__new__(cls)
|
|
21
|
+
# initialize output directory for platform graphs
|
|
22
|
+
output_location = os.path.join(os.getcwd(), 'Output', 'PlatformDisplay')
|
|
23
|
+
if not os.path.exists(output_location):
|
|
24
|
+
os.makedirs(output_location)
|
|
25
|
+
cls._instance.output_location = output_location
|
|
26
|
+
return cls._instance
|
|
27
|
+
|
|
28
|
+
def save2disk(
|
|
29
|
+
self,
|
|
30
|
+
fig,
|
|
31
|
+
filename: str,
|
|
32
|
+
xanchor='left',
|
|
33
|
+
yanchor='bottom',
|
|
34
|
+
orientation='h',
|
|
35
|
+
x=0.1,
|
|
36
|
+
y=-0.075,
|
|
37
|
+
):
|
|
38
|
+
"""
|
|
39
|
+
Save a plotly graph object in a json format and in a proper location on the KYOS servers.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
fig (plotly.graph_objects): a fully built plotly figure
|
|
43
|
+
filename (str): under what filename should the graph be saved on the server's hard-disk.
|
|
44
|
+
Note that the filename plays a role in the order of displaying graphs in the fornt end.
|
|
45
|
+
xanchor (str): (Optional) One of ( "auto" | "left" | "center" | "right" ) Sets the title's horizontal
|
|
46
|
+
alignment with respect to its x position. "left" means that the title starts at x. Default:"left"
|
|
47
|
+
yanchor (str): (Optional) One of ( "auto" | "top" | "middle" | "bottom" ) Sets the title's vertical
|
|
48
|
+
alignment with respect to its y position. "top" means that the title's cap line is at y. Default:"bottom"
|
|
49
|
+
orientation (str): (Optional) one of ( "v" | "h" ). Sets the orientation of the legend. Default:"h"
|
|
50
|
+
x (float): (Optional) number between or equal to -2 and 3 Sets the x position (in normalized coordinates)
|
|
51
|
+
of the legend. KYOS Platform Defaults to 0.1
|
|
52
|
+
y (float): (Optional) number between or equal to -2 and 3 Sets the y position (in normalized coordinates)
|
|
53
|
+
of the legend. KYOS Platform Defaults to -0.075
|
|
54
|
+
|
|
55
|
+
Examples:
|
|
56
|
+
>>> graph_object = PlatformGraphs()
|
|
57
|
+
>>> fig = px.histogram()
|
|
58
|
+
>>> graph_object.save2disk(fig, filename="001_option_value")
|
|
59
|
+
"""
|
|
60
|
+
# legend style same over the whole platform
|
|
61
|
+
# -> styling can be moved to a separate method
|
|
62
|
+
fig.update_layout(
|
|
63
|
+
legend={
|
|
64
|
+
'xanchor': xanchor,
|
|
65
|
+
'yanchor': yanchor,
|
|
66
|
+
'orientation': orientation,
|
|
67
|
+
'x': x,
|
|
68
|
+
'y': y,
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
fig.update_layout(
|
|
72
|
+
plot_bgcolor="#FFF", # Sets background color to white
|
|
73
|
+
xaxis=dict(
|
|
74
|
+
linecolor="#BCCCDC", # Sets color of X-axis line
|
|
75
|
+
showgrid=False, # Removes X-axis grid lines
|
|
76
|
+
),
|
|
77
|
+
yaxis=dict(
|
|
78
|
+
linecolor='gray',
|
|
79
|
+
showgrid=True, # Keep Y-axis grid lines
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
full_path = os.path.join(self.output_location, filename + "_plotly.json")
|
|
84
|
+
plotly_write_json(fig, full_path)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def make_platform_table(
|
|
88
|
+
df, table_name, bold_row_name=True, bold_column_name=True, columns_names=None
|
|
89
|
+
):
|
|
90
|
+
"""
|
|
91
|
+
Function which outputs a pandas dataframe in a format which can be displayed in the KYOS platform.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
df (pandas.Dataframe): A single row index is allowed. Multiple column indexes are allowed.
|
|
95
|
+
bold_row_name (bool): Display the row name in bold font when showing it in the platform front-end
|
|
96
|
+
bold_column_name (bool): Display the column name in bold font when showing it in the platform front-end
|
|
97
|
+
columns_names (None|list): None: use the column names of the dataframe | list of list: user defined columns names (should include name for the row index as well)
|
|
98
|
+
|
|
99
|
+
Notes:
|
|
100
|
+
The data in the dataframe saved in a csv file in the desired format.
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
>>> make_platform_table(data_df, '001_Option_Value', bold_column_name=True)
|
|
104
|
+
"""
|
|
105
|
+
current_dir = os.path.dirname(os.path.realpath('__file__'))
|
|
106
|
+
# create output directory
|
|
107
|
+
output_dir = os.path.join(current_dir, 'Output/PlatformDisplay/')
|
|
108
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
109
|
+
|
|
110
|
+
values = df.values.tolist()
|
|
111
|
+
|
|
112
|
+
# attach row names to the values
|
|
113
|
+
# currently only a single row name index is supported
|
|
114
|
+
all_rows = df.index.values.tolist()
|
|
115
|
+
n_row_indx = len(all_rows)
|
|
116
|
+
for r in range(n_row_indx):
|
|
117
|
+
name = all_rows[r]
|
|
118
|
+
if bold_row_name == True and name != "":
|
|
119
|
+
# add a tag to display the column name as bold
|
|
120
|
+
name = "<b>" + name.replace('_', ' ') + "</b>"
|
|
121
|
+
values[r].insert(0, name)
|
|
122
|
+
|
|
123
|
+
# Generate columns names consistent with the platform display format
|
|
124
|
+
if columns_names == None:
|
|
125
|
+
all_columns = df.columns.values.tolist()
|
|
126
|
+
all_col_names = []
|
|
127
|
+
if type(all_columns[0]) == str:
|
|
128
|
+
n_col_indx = 1
|
|
129
|
+
else: # tuple of all column indexes' name
|
|
130
|
+
n_col_indx = len(all_columns[0])
|
|
131
|
+
|
|
132
|
+
for i in range(n_col_indx):
|
|
133
|
+
col_names = [""] # currently only a single row name indexation is supported
|
|
134
|
+
unique_name = None
|
|
135
|
+
for col in all_columns:
|
|
136
|
+
if n_col_indx == 1:
|
|
137
|
+
name = col # col is just a string name
|
|
138
|
+
else:
|
|
139
|
+
name = str(col[i]) # column is a tuple of string names
|
|
140
|
+
|
|
141
|
+
if unique_name is not None and name == unique_name:
|
|
142
|
+
# a dataframe outputs the same name for a column when we have multi-indexing
|
|
143
|
+
# to display properly in the platform we drop the repeating names
|
|
144
|
+
name = ""
|
|
145
|
+
else:
|
|
146
|
+
unique_name = name
|
|
147
|
+
|
|
148
|
+
if bold_column_name == True and name != "":
|
|
149
|
+
# add a tag to display the column name as bold
|
|
150
|
+
name = "<b>" + name + "</b>"
|
|
151
|
+
col_names.append(name)
|
|
152
|
+
all_col_names.append(col_names)
|
|
153
|
+
else:
|
|
154
|
+
n_col_rows = len(columns_names[0])
|
|
155
|
+
all_col_names = []
|
|
156
|
+
for i in range(n_col_rows):
|
|
157
|
+
col_names = [x[i] for x in columns_names]
|
|
158
|
+
all_col_names.append(col_names)
|
|
159
|
+
|
|
160
|
+
with open(output_dir + table_name + ".csv", "w") as f:
|
|
161
|
+
writer = csv.writer(f)
|
|
162
|
+
writer.writerows(all_col_names)
|
|
163
|
+
with open(output_dir + table_name + ".csv", "a") as f:
|
|
164
|
+
writer = csv.writer(f)
|
|
165
|
+
writer.writerows(values)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def make_platform_histogram(
|
|
169
|
+
values, values_names, n_bins='auto', title=' ', output_filename='name'
|
|
170
|
+
):
|
|
171
|
+
"""
|
|
172
|
+
Build a histogram based on one or more value series. The histogram will be displayed dynamically in the
|
|
173
|
+
Kyos Analytical Platform.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
values (numpy.ndarray): a histogram is built for each value series.
|
|
177
|
+
The min/max of the histogram buckets is based on the smallest/biggest element of all series.
|
|
178
|
+
[shape = (n_rows, n_series)]
|
|
179
|
+
values_names (list): a list of string names for each series.
|
|
180
|
+
[len = n_series]
|
|
181
|
+
n_bins (int): how many bins should be used in the histogram.
|
|
182
|
+
title (string): title of the histogram
|
|
183
|
+
output_filename (string): beginning of the name of the output json file. It can be used to order how graphs are
|
|
184
|
+
displayed in the platform. Graph with start of the name "001_" will be displayed first.
|
|
185
|
+
|
|
186
|
+
Note:
|
|
187
|
+
The histogram graph is build using the "Highcharts" package. For more info refer to [HighCharts](https://www.highcharts.com/demo/column-basic)
|
|
188
|
+
|
|
189
|
+
Examples:
|
|
190
|
+
>>> make_platform_histogram(values=values, values_names=['Value'],
|
|
191
|
+
>>> title='Total Option Value (EUR)',
|
|
192
|
+
>>> n_bins=20, output_filename='001_option_value')
|
|
193
|
+
"""
|
|
194
|
+
# find bin edges based on all value series.
|
|
195
|
+
bin_edges = np.histogram_bin_edges(values, bins=n_bins, range=None, weights=None)
|
|
196
|
+
bin_means = list()
|
|
197
|
+
for b in range(len(bin_edges[:-1])):
|
|
198
|
+
bin_means.append((bin_edges[b] + bin_edges[b + 1]) / 2)
|
|
199
|
+
|
|
200
|
+
# find the frequency histogram per a single series
|
|
201
|
+
series = []
|
|
202
|
+
n_series = values.shape[1]
|
|
203
|
+
for i in range(n_series):
|
|
204
|
+
hist, bin_edges_out = np.histogram(values[:, i], bins=bin_edges)
|
|
205
|
+
hist_frequency = hist / hist.sum() * 100
|
|
206
|
+
hist_frequency = hist_frequency.tolist()
|
|
207
|
+
series.append({'name': values_names[i], 'data': hist_frequency})
|
|
208
|
+
|
|
209
|
+
y_label = 'Frequency'
|
|
210
|
+
column_chart = {
|
|
211
|
+
'chart': {'type': 'column'},
|
|
212
|
+
'title': {'text': title},
|
|
213
|
+
'subtitle': {'text': ' '},
|
|
214
|
+
'xAxis': {
|
|
215
|
+
'labels': {'format': '{value:,.0f}'},
|
|
216
|
+
'categories': bin_means,
|
|
217
|
+
'crosshair': 'true',
|
|
218
|
+
},
|
|
219
|
+
'yAxis': {
|
|
220
|
+
'labels': {'format': '{value} %'},
|
|
221
|
+
'min': 0,
|
|
222
|
+
'title': {
|
|
223
|
+
'text': y_label,
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
'tooltip': {
|
|
227
|
+
'headerFormat': ' ',
|
|
228
|
+
'pointFormat': '<p><span style="color:{series.color}">●</span> <b>{series.name}: </b>{point.y:.1f} %</p>',
|
|
229
|
+
'shared': 'true',
|
|
230
|
+
'useHTML': 'true',
|
|
231
|
+
},
|
|
232
|
+
'credits': {'text': 'Kyos Energy Consulting', 'href': 'http://www.kyos.com'},
|
|
233
|
+
'plotOptions': {'column': {'pointPadding': 0, 'borderWidth': 0}},
|
|
234
|
+
'series': series,
|
|
235
|
+
}
|
|
236
|
+
# output chart to json
|
|
237
|
+
with open('Output/PlatformDisplay/' + output_filename + '_chart.json', 'w') as outfile:
|
|
238
|
+
json.dump(column_chart, outfile)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def make_bar_column_chart(
|
|
242
|
+
values,
|
|
243
|
+
values_names,
|
|
244
|
+
is_stacked=False,
|
|
245
|
+
x_axis=None,
|
|
246
|
+
title=' ',
|
|
247
|
+
y_axis_title='values',
|
|
248
|
+
output_filename='name',
|
|
249
|
+
unit_name='unit',
|
|
250
|
+
):
|
|
251
|
+
"""
|
|
252
|
+
Build a bar column chart based on one or more value series. The chart will be displayed dynamically in the
|
|
253
|
+
Kyos Analytical Platform.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
values (numpy.ndarray): y axis values
|
|
257
|
+
[shape = (n_rows, n_series)]
|
|
258
|
+
values_names (list): a list of string names for each series.
|
|
259
|
+
[len = n_series]
|
|
260
|
+
is_stacked (bool): indicator for chart type. basic column and stacked column chart supported
|
|
261
|
+
False: Basic column chart
|
|
262
|
+
True: Stacked column chart
|
|
263
|
+
x_axis (None|list): list of x-axis values
|
|
264
|
+
None: integer values will be used [1,2,3 .......]
|
|
265
|
+
list: user defined x axis names (e.g. dates)
|
|
266
|
+
title (string): title of the chart
|
|
267
|
+
y_axis_title (string): title of the y-axis
|
|
268
|
+
output_filename (string): beginning of the name of the output json file. It can be used to order how graphs are
|
|
269
|
+
displayed in the platform. Graph with start of the name "001_" will be displayed first.
|
|
270
|
+
unit_name (string): unit name of the values
|
|
271
|
+
|
|
272
|
+
Note:
|
|
273
|
+
The histogram graph is build using the "Highcharts" package. For more info refer to
|
|
274
|
+
[HighCharts](https://www.highcharts.com/demo/column-basic)
|
|
275
|
+
|
|
276
|
+
Examples:
|
|
277
|
+
>>> make_bar_column_chart(values=np.zeros((2,2)), values_names=['series_1', 'series_2'],is_stacked=True,
|
|
278
|
+
>>> x_axis=['2019-01-01', '2019-01-02'], title='Daily Positions', y_axis_title='Positions',
|
|
279
|
+
>>> output_filename='001_option_value', unit_name='Lots')
|
|
280
|
+
"""
|
|
281
|
+
|
|
282
|
+
if x_axis is None:
|
|
283
|
+
x_axis = []
|
|
284
|
+
y_axis_title = y_axis_title + ' (' + unit_name + ')'
|
|
285
|
+
# Check chart type and create plot options
|
|
286
|
+
plot_options = {}
|
|
287
|
+
if is_stacked:
|
|
288
|
+
plot_options = {'column': {'stacking': 'normal'}}
|
|
289
|
+
# covert series to list
|
|
290
|
+
series = []
|
|
291
|
+
n_series = values.shape[1]
|
|
292
|
+
for i in range(n_series):
|
|
293
|
+
series_i = values[:, i].tolist()
|
|
294
|
+
series.append({'name': values_names[i], 'data': series_i})
|
|
295
|
+
|
|
296
|
+
bar_chart = {
|
|
297
|
+
'chart': {'type': 'column'},
|
|
298
|
+
'title': {'text': title},
|
|
299
|
+
'xAxis': {'categories': x_axis},
|
|
300
|
+
'yAxis': {'min': 0, 'title': {'text': y_axis_title}},
|
|
301
|
+
'tooltip': {
|
|
302
|
+
'headerFormat': '<span style="font-size:10px">{point.key}</span><table>',
|
|
303
|
+
'pointFormat': '<tr><td style="color:{series.color};padding:0">{series.name}: </td>'
|
|
304
|
+
+ '<td style="padding:0"><b>{point.y:.1f} '
|
|
305
|
+
+ unit_name
|
|
306
|
+
+ '</b></td></tr>',
|
|
307
|
+
'footerFormat': '</table>',
|
|
308
|
+
'shared': 'true',
|
|
309
|
+
'useHTML': 'true',
|
|
310
|
+
},
|
|
311
|
+
'credits': {'text': 'Kyos Energy Consulting', 'href': 'http://www.kyos.com'},
|
|
312
|
+
'plotOptions': plot_options,
|
|
313
|
+
'series': series,
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
# output chart to json
|
|
317
|
+
with open('Output/PlatformDisplay/' + output_filename + '_chart.json', 'w') as outfile:
|
|
318
|
+
json.dump(bar_chart, outfile)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def make_basic_line_chart(
|
|
322
|
+
values,
|
|
323
|
+
values_names,
|
|
324
|
+
x_axis=None,
|
|
325
|
+
title=' ',
|
|
326
|
+
y_axis_title='values',
|
|
327
|
+
output_filename='name',
|
|
328
|
+
unit_name='unit',
|
|
329
|
+
):
|
|
330
|
+
"""
|
|
331
|
+
Build a bar column chart based on one or more value series. The chart will be displayed dynamically in the
|
|
332
|
+
Kyos Analytical Platform.
|
|
333
|
+
|
|
334
|
+
Args:
|
|
335
|
+
values (numpy.ndarray): y axis values
|
|
336
|
+
[shape = (n_rows, n_series)]
|
|
337
|
+
values_names (list): a list of string names for each series.
|
|
338
|
+
[len = n_series]
|
|
339
|
+
x_axis (None|list): list of x-axis values
|
|
340
|
+
None: integer values will be used [1,2,3 .......]
|
|
341
|
+
list: user defined x axis names (e.g. dates)
|
|
342
|
+
title (string): title of the chart
|
|
343
|
+
y_axis_title (string): title of the y-axis
|
|
344
|
+
output_filename (string): beginning of the name of the output json file. It can be used to order how graphs are
|
|
345
|
+
displayed in the platform. Graph with start of the name "001_" will be displayed first.
|
|
346
|
+
unit_name (string): unit name of the values
|
|
347
|
+
|
|
348
|
+
Note:
|
|
349
|
+
The histogram graph is build using the "Highcharts" package. For more info refer to
|
|
350
|
+
[HighCharts](https://www.highcharts.com/demo/column-basic)
|
|
351
|
+
|
|
352
|
+
Examples:
|
|
353
|
+
>>> make_basic_line_chart(values=np.zeros((2,2)), values_names=['series_1', 'series_2'],
|
|
354
|
+
>>> x_axis=['2019-01-01', '2019-01-02'], title='Daily Positions', y_axis_title=' ',
|
|
355
|
+
>>> output_filename='001_option_value', unit_name='Lots')
|
|
356
|
+
"""
|
|
357
|
+
|
|
358
|
+
if x_axis is None:
|
|
359
|
+
x_axis = []
|
|
360
|
+
y_axis_title = y_axis_title + ' (' + unit_name + ')'
|
|
361
|
+
# covert series to list
|
|
362
|
+
series = []
|
|
363
|
+
n_series = values.shape[1]
|
|
364
|
+
for i in range(n_series):
|
|
365
|
+
series_i = values[:, i].tolist()
|
|
366
|
+
series.append({'name': values_names[i], 'data': series_i})
|
|
367
|
+
|
|
368
|
+
line_chart = {
|
|
369
|
+
'title': {'text': title},
|
|
370
|
+
'xAxis': {'categories': x_axis},
|
|
371
|
+
'yAxis': {'title': {'text': y_axis_title}},
|
|
372
|
+
'tooltip': {
|
|
373
|
+
'headerFormat': '<span style="font-size:10px">{point.key}</span><table>',
|
|
374
|
+
'pointFormat': '<tr><td style="color:{series.color};padding:0">{series.name}: </td>'
|
|
375
|
+
+ '<td style="padding:0"><b>{point.y:.1f} '
|
|
376
|
+
+ unit_name
|
|
377
|
+
+ '</b></td></tr>',
|
|
378
|
+
'footerFormat': '</table>',
|
|
379
|
+
'shared': 'true',
|
|
380
|
+
'useHTML': 'true',
|
|
381
|
+
},
|
|
382
|
+
'credits': {'text': 'Kyos Energy Consulting', 'href': 'http://www.kyos.com'},
|
|
383
|
+
'series': series,
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
# output chart to json
|
|
387
|
+
with open('Output/PlatformDisplay/' + output_filename + '_chart.json', 'w') as outfile:
|
|
388
|
+
json.dump(line_chart, outfile)
|