Repository navigation
Expand file tree
/
Copy pathexample_modified.py
More file actions
142 lines (122 loc) · 6.1 KB
/
Copy pathexample_modified.py
File metadata and controls
142 lines (122 loc) · 6.1 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# %%
# -*- coding: utf-8 -*-
'''This is an example of how the scale and data definitions can be 'glued'
together to generate and output a point and figure chart as an html page.
'''
import pandas as pd
import datetime as dt
import os
import datadefs, scalefuncs
import yfinance
# %%
DEBUG = False
#Generate PnF Charts and output to html tables
#INIT chart
close_column_name = 'close'
percent_scale = 1
chart_type = datadefs.ChartType.Close # It could be .Close or .HighLow, if HL change the code!!
num_reversal_boxes = 3
print("\n\nGenerating charts...")
# %%
#Read in fake data
path = 'example_data.csv'
df = pd.read_csv(path, index_col='date', na_values='null')
# %%
# Use this if you want any ticker through Yahoo Finance
ticker = 'BTC-USD'
df = yfinance.download(ticker, start='2018-01-01', end='2025-11-15')
df
# %%
# You can select the subset you want:
df = df[['Close']]
#df = df[['Close', ticker]].copy() # Select that column as a DataFrame
df.columns = ['close'] # Rename the column to 'close'
df
# %%
minVal = df[close_column_name].min()
maxVal = df[close_column_name].max()
start_date = df.index[0]
start_value = df[close_column_name].iloc[0]
chart = datadefs.Chart(start_date, num_reversal_boxes, chart_type=chart_type)
chart.set_chart_scale_traditional(minVal, maxVal) #set_chart_scale_percent(minVal, maxVal, percent_scale)
# %%
first_direction = scalefuncs.getFirstColumnDirection(df, close_column_name, chart.scale)
column = datadefs.Column(start_date=df.index[0], start_value=df[close_column_name].iloc[0],
direction=first_direction, num_reversal_boxes=chart.num_reversal_boxes,
chart_scale=chart.scale)
# %%
for date, price in df[close_column_name].items():
box_value = scalefuncs.getBoxForValue(price, column.direction, chart.scale)
if column.direction == datadefs.Direction.X:
if price >= column.next_box:
new_boxes = scalefuncs.getBoxesBetweenValues(column.next_box, box_value, column.direction, chart.scale)
column.boxes += new_boxes
column.next_box = scalefuncs.getNextBoxUp(price, chart.scale)
column.reversal_box = scalefuncs.getReversalDn(price, chart.scale, column.num_reversal_boxes)
if DEBUG: print('{0} {1}: Price:{2:8.2f} Next:{3} Reversal:{4}\t{5}'.format(date, column.direction.value, price, column.next_box, column.reversal_box, column.print_boxes()))
elif price <= column.reversal_box:
chart.append_column(column)
rev_box = column.reversal_box
if DEBUG: print('{0}==>Reversal to O\t{1}-{2}\tPrice: {3:8.2f}\tNext:{4}\tReversal:{5}'.format(date, column.start_date, column.end_date, price, column.next_box, column.reversal_box))
column = datadefs.Column(date, price, datadefs.Direction.O, chart.num_reversal_boxes, chart.scale)
column.boxes = scalefuncs.getBoxesInReversals(rev_box, num_reversal_boxes, column.direction, chart.scale)
if DEBUG: print('{0} {1}: Price:{2:8.2f} Next:{3} Reversal:{4}\t{5}'.format(date, column.direction.value, price, column.next_box, column.reversal_box, column.print_boxes()))
else:
if DEBUG=='FULL':
print('{0}: Price:{1:8.2f} Box:{2} No Change'.format(date, price, box_value))
elif column.direction == datadefs.Direction.O:
if price <= column.next_box:
new_boxes = scalefuncs.getBoxesBetweenValues(column.next_box, box_value, column.direction, chart.scale)
column.boxes = new_boxes + column.boxes
column.next_box = scalefuncs.getNextBoxDn(price, chart.scale)
column.reversal_box = scalefuncs.getReversalUp(price, chart.scale, column.num_reversal_boxes)
if DEBUG: print('{0} {1}: Price:{2:8.2f} Next:{3} Reversal:{4}\t{5}'.format(date, column.direction.value, price, column.next_box, column.reversal_box, column.print_boxes()))
elif price >= column.reversal_box:
chart.append_column(column)
rev_box = column.reversal_box
if DEBUG: print('{0}==>Reversal to X\t{1}-{2}\tPrice: {3:8.2f}\tNext:{4}\tReversal:{5}'.format(date, column.start_date, column.end_date, price, column.next_box, column.reversal_box))
column = datadefs.Column(date, rev_box, datadefs.Direction.X, chart.num_reversal_boxes, chart.scale)
column.boxes = scalefuncs.getBoxesInReversals(rev_box, num_reversal_boxes, column.direction, chart.scale)
if DEBUG: print('{0} {1}: Price:{2:8.2f} Next:{3} Reversal:{4}\t{5}'.format(date, column.direction.value, price, column.next_box, column.reversal_box, column.print_boxes()))
else:
if DEBUG=='FULL':
print('{0}: Price:{1:8.2f} Box:{2} No Change'.format(date, price, box_value))
else:
raise SystemExit('This shouldn''t happen')
column.end_date = date
chart.append_column(column)
PnF = chart.get_dataframe()
# %%
#OUTPUT SOMETHING USEFUL
print("exporting")
#ticker = 'test_data'
html = PnF.to_html()
for year in range(1990, 2022):
html = html.replace('<th>' + str(year) + '-', '<th>' + str(year) + '-</br>')
html = html.replace('<td>X</td>', '<td><center><b><font color="black">X</font></b></center></td>')
html = html.replace('<td>O</td>', '<td><center><b><font color="black">O</font></b></center></td>')
out_path = os.path.join('', dt.datetime.now().isoformat()[:10])
if not os.path.exists(out_path):
os.mkdir(out_path)
with open(os.path.join(out_path, ticker + '.html'), 'w') as export:
export.writelines('''<html>
<style>
table {
border-collapse: collapse;
}
th, td {
border: 1px solid lightgray;
padding: 0px;
}
</style>''')
export.writelines(f'<body><h1>{ticker}</h1>')
export.writelines('<h1>Point and figure</h2>')
export.writelines(f'Scale: {chart.scale_type}</br>Reversal Boxes: {chart.num_reversal_boxes}</br>')
export.writelines(f'Type: {chart.chart_type}</br>')
export.write('<div>')
export.write(html.replace(' 00:00:00', ''))
export.writelines('</div>')
export.writelines('</body>\n</html>')
print("Done")
# %%
# Scales calculations