goldhand 14.6__tar.gz → 15.1__tar.gz
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.
Potentially problematic release.
This version of goldhand might be problematic. Click here for more details.
- {goldhand-14.6 → goldhand-15.1}/PKG-INFO +1 -1
- {goldhand-14.6 → goldhand-15.1}/goldhand/backtest.py +3 -3
- {goldhand-14.6 → goldhand-15.1}/goldhand/strategy_goldhand_line.py +34 -16
- {goldhand-14.6 → goldhand-15.1}/goldhand/strategy_rsi.py +20 -21
- {goldhand-14.6 → goldhand-15.1}/goldhand/tw.py +4 -2
- {goldhand-14.6 → goldhand-15.1}/goldhand.egg-info/PKG-INFO +1 -1
- {goldhand-14.6 → goldhand-15.1}/setup.py +1 -1
- {goldhand-14.6 → goldhand-15.1}/README.md +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand/__init__.py +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand/helpers.py +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand/stocks.py +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand.egg-info/SOURCES.txt +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand.egg-info/dependency_links.txt +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand.egg-info/requires.txt +0 -0
- {goldhand-14.6 → goldhand-15.1}/goldhand.egg-info/top_level.txt +0 -0
- {goldhand-14.6 → goldhand-15.1}/setup.cfg +0 -0
|
@@ -30,8 +30,10 @@ class Backtest:
|
|
|
30
30
|
'ticker' : self.data['ticker'].iloc[0],
|
|
31
31
|
'number_of_trades' : self.trades.shape[0],
|
|
32
32
|
'win_ratio(%)' : round(((sum(self.trades['result'] >1) / self.trades.shape[0])*100),2),
|
|
33
|
-
|
|
34
33
|
'average_res(%)' : round(((self.trades['result'].mean()-1)*100),2),
|
|
34
|
+
'average_trade_len(days)' : round(self.trades['days_in_trade'].mean(), 0),
|
|
35
|
+
|
|
36
|
+
|
|
35
37
|
'median_res(%)': round(((self.trades['result'].median()-1)*100),2),
|
|
36
38
|
'cumulative_result': list(np.cumprod(self.trades['result'], axis=0))[-1],
|
|
37
39
|
'trade_results': ' # '.join([ str(round(((x-1)*100),2)) for x in self.trades['result']]),
|
|
@@ -46,8 +48,6 @@ class Backtest:
|
|
|
46
48
|
'looser_trades_mean' : round((( np.mean([x for x in self.trades['result'] if x<1])-1)*100),2),
|
|
47
49
|
'looser_trades_median' : round((( np.median([x for x in self.trades['result'] if x<1])-1)*100),2),
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
'average_trade_len(days)' : self.trades['days_in_trade'].mean(),
|
|
51
51
|
'median_trade_len(days)' : self.trades['days_in_trade'].median(),
|
|
52
52
|
|
|
53
53
|
|
|
@@ -9,6 +9,13 @@ from goldhand import *
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def goldhand_line_strategy(data):
|
|
12
|
+
"""
|
|
13
|
+
This function implements the goldhand line strategy.
|
|
14
|
+
Parameters:
|
|
15
|
+
data (pandas.DataFrame): The dataframe containing the data.
|
|
16
|
+
Returns:
|
|
17
|
+
res_df (pandas.DataFrame): The dataframe containing the results.
|
|
18
|
+
"""
|
|
12
19
|
|
|
13
20
|
data['hl2'] = (data['high'] + data['low'])/2
|
|
14
21
|
|
|
@@ -91,7 +98,18 @@ def goldhand_line_strategy(data):
|
|
|
91
98
|
return(res_df)
|
|
92
99
|
|
|
93
100
|
|
|
94
|
-
def show_indicator_goldhand_line_strategy(ticker, plot_title = '', ndays=0, plot_height=
|
|
101
|
+
def show_indicator_goldhand_line_strategy(ticker, plot_title = '', ndays=0, plot_height=1000, add_strategy_summary = True):
|
|
102
|
+
"""
|
|
103
|
+
This function shows the goldhand line strategy on a plotly candlestick chart.
|
|
104
|
+
Parameters:
|
|
105
|
+
ticker (str): The ticker of the stock or ETF.
|
|
106
|
+
plot_title (str): The title of the plot.
|
|
107
|
+
ndays (int): The number of days to show. If 0, all data will be shown.
|
|
108
|
+
plot_height (int): The height of the plot.
|
|
109
|
+
add_strategy_summary (bool): If True, the strategy summary will be added to the plot.
|
|
110
|
+
Returns:
|
|
111
|
+
fig (plotly.graph_objects.Figure): The plotly figure.
|
|
112
|
+
"""
|
|
95
113
|
|
|
96
114
|
data = GoldHand(ticker).df
|
|
97
115
|
|
|
@@ -237,21 +255,21 @@ def show_indicator_goldhand_line_strategy(ticker, plot_title = '', ndays=0, plot
|
|
|
237
255
|
fig.update_layout(showlegend=False, plot_bgcolor='white', height=plot_height, title=plot_title)
|
|
238
256
|
fig.update(layout_xaxis_rangeslider_visible=False)
|
|
239
257
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
258
|
+
if add_strategy_summary:
|
|
259
|
+
t= backtest.trades_summary
|
|
260
|
+
trade_text = f"Trades: {t['number_of_trades']}<br>"\
|
|
261
|
+
f"Win ratio: {t['win_ratio(%)']}%<br>"\
|
|
262
|
+
f"Average result: {t['average_res(%)']}%<br>"\
|
|
263
|
+
f"Median result: {t['median_res(%)']}%<br>"\
|
|
264
|
+
f"Average trade lenght: {round(t['average_trade_len(days)'], 0)} days<br>"\
|
|
265
|
+
f"Cumulative result: {round(t['cumulative_result'], 2)}x<br>"\
|
|
266
|
+
f"Profitable trades mean: {t['profitable_trades_mean']}%<br>"\
|
|
267
|
+
f"Profitable trades median: {t['profitable_trades_median']}%<br>"\
|
|
268
|
+
f"Looser trades mean: {t['looser_trades_mean']}%<br>"\
|
|
269
|
+
f"Looser trades median: {t['looser_trades_median']}%<br>"
|
|
270
|
+
|
|
271
|
+
# Add a larger textbox using annotations
|
|
272
|
+
fig.add_annotation( go.layout.Annotation( x=tex_loc[0], y=tex_loc[1], xref='paper', yref='paper', text=trade_text, showarrow=True, arrowhead=4, ax=0, ay=0, bordercolor='black', borderwidth=2, bgcolor='white', align='left', font=dict(size=14, color='black')))
|
|
255
273
|
|
|
256
274
|
# Show the plot
|
|
257
275
|
return (fig)
|
|
@@ -68,14 +68,14 @@ def rsi_strategy(data, buy_threshold = 30, sell_threshold = 70):
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
def show_indicator_rsi_strategy(ticker, buy_threshold = 30, sell_threshold = 70, plot_title = '', ndays=0, plot_height=
|
|
71
|
+
def show_indicator_rsi_strategy(ticker, buy_threshold = 30, sell_threshold = 70, plot_title = '', ndays=0, plot_height=1000, add_strategy_summary = True):
|
|
72
72
|
|
|
73
73
|
tdf = GoldHand(ticker).df
|
|
74
74
|
backtest = Backtest( tdf, rsi_strategy, buy_threshold=buy_threshold, sell_threshold=sell_threshold)
|
|
75
75
|
trades =backtest.trades
|
|
76
76
|
|
|
77
|
-
if ndays
|
|
78
|
-
tdf =
|
|
77
|
+
if ndays > 0:
|
|
78
|
+
tdf = tdf.tail(ndays)
|
|
79
79
|
trades = trades.loc[trades['buy_date']>tdf.date.min()]
|
|
80
80
|
|
|
81
81
|
if tdf['high'].max() == max(tdf['high'][0:50]):
|
|
@@ -86,7 +86,7 @@ def show_indicator_rsi_strategy(ticker, buy_threshold = 30, sell_threshold = 70,
|
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
# Create subplots with shared x-axis and custom heights
|
|
89
|
-
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.1, subplot_titles=[
|
|
89
|
+
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.1, subplot_titles=['', "RSI"], row_heights=[0.7, 0.3])
|
|
90
90
|
|
|
91
91
|
# Add OHLC candlestick chart
|
|
92
92
|
fig.add_trace(go.Ohlc(x=tdf['date'], open=tdf['open'], high=tdf['high'], low=tdf['low'], close=tdf['close']), row=1, col=1)
|
|
@@ -151,7 +151,7 @@ def show_indicator_rsi_strategy(ticker, buy_threshold = 30, sell_threshold = 70,
|
|
|
151
151
|
font=dict(size=13, color=triangle_color, family="Times New Roman")))
|
|
152
152
|
|
|
153
153
|
# Update layout
|
|
154
|
-
fig.update_layout(showlegend=False, plot_bgcolor='white', height=
|
|
154
|
+
fig.update_layout(showlegend=False, plot_bgcolor='white', height=plot_height, title=plot_title)
|
|
155
155
|
fig.update(layout_xaxis_rangeslider_visible=False)
|
|
156
156
|
|
|
157
157
|
# Update x-axes and y-axes for the main chart
|
|
@@ -162,22 +162,21 @@ def show_indicator_rsi_strategy(ticker, buy_threshold = 30, sell_threshold = 70,
|
|
|
162
162
|
fig.update_xaxes(mirror=True, ticks='outside', showline=True, linecolor='black', gridcolor='lightgrey', row=2, col=1)
|
|
163
163
|
fig.update_yaxes(mirror=True, ticks='outside', showline=True, linecolor='black', gridcolor='lightgrey', row=2, col=1)
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
165
|
+
if add_strategy_summary:
|
|
166
|
+
t= backtest.trades_summary
|
|
167
|
+
trade_text = f"Trades: {t['number_of_trades']}<br>"\
|
|
168
|
+
f"Win ratio: {t['win_ratio(%)']}%<br>"\
|
|
169
|
+
f"Average result: {t['average_res(%)']}%<br>"\
|
|
170
|
+
f"Median result: {t['median_res(%)']}%<br>"\
|
|
171
|
+
f"Average trade length: {round(t['average_trade_len(days)'], 0)} days<br>"\
|
|
172
|
+
f"Cumulative result: {round(t['cumulative_result'], 2)}x<br>"\
|
|
173
|
+
f"Profitable trades mean: {t['profitable_trades_mean']}%<br>"\
|
|
174
|
+
f"Profitable trades median: {t['profitable_trades_median']}%<br>"\
|
|
175
|
+
f"Looser trades mean: {t['looser_trades_mean']}%<br>"\
|
|
176
|
+
f"Looser trades median: {t['looser_trades_median']}%<br>"
|
|
177
|
+
|
|
178
|
+
# Add a larger textbox using annotations
|
|
179
|
+
fig.add_annotation( go.layout.Annotation( x=tex_loc[0], y=tex_loc[1], xref='paper', yref='paper', text=trade_text, showarrow=True, arrowhead=4, ax=0, ay=0, bordercolor='black', borderwidth=2, bgcolor='white', align='left', font=dict(size=14, color='black')))
|
|
181
180
|
|
|
182
181
|
|
|
183
182
|
# Add RSI line
|
|
@@ -92,7 +92,9 @@ class Tw:
|
|
|
92
92
|
|
|
93
93
|
secdf.rename(columns = {'description': 'Company'}, inplace=True)
|
|
94
94
|
|
|
95
|
-
fig = px.bar(secdf, x='name', y='market_cap_basic', title = f"{row_df['Company'].iloc[0]} ({row_df['name'].iloc[0]})<br>{row_df['sector'].iloc[0]} | {row_df['industry'].iloc[0]}", labels={'market_cap_basic':'Market kapitalization'}, text='Company')
|
|
95
|
+
#fig = px.bar(secdf, x='name', y='market_cap_basic', title = f"{row_df['Company'].iloc[0]} ({row_df['name'].iloc[0]})<br>{row_df['sector'].iloc[0]} | {row_df['industry'].iloc[0]}", labels={'market_cap_basic':'Market kapitalization'}, text='Company')
|
|
96
|
+
|
|
97
|
+
fig = px.bar(secdf, x='name', y='market_cap_basic', title = self.get_plotly_title(ticker), labels={'market_cap_basic':'Market kapitalization'}, text='Company')
|
|
96
98
|
|
|
97
99
|
fig.add_annotation( x=row_df['name'].iloc[0], y=row_df['market_cap_basic'].iloc[0], text= f"{market_cap}", showarrow=True, align="center", bordercolor="#c7c7c7", font=dict(family="Courier New, monospace", size=16, color="#214e34" ), borderwidth=2, borderpad=4, bgcolor="#f4fdff", opacity=0.8, arrowhead=2, arrowsize=1, arrowwidth=1, ax=65,ay=-45)
|
|
98
100
|
fig.update_layout(showlegend=False, plot_bgcolor='white', height=600)
|
|
@@ -110,7 +112,7 @@ class Tw:
|
|
|
110
112
|
|
|
111
113
|
inddf.rename(columns = {'description': 'Company'}, inplace=True)
|
|
112
114
|
|
|
113
|
-
fig = px.bar(inddf, x='name', y='market_cap_basic', title =
|
|
115
|
+
fig = px.bar(inddf, x='name', y='market_cap_basic', title = self.get_plotly_title(ticker), labels={'market_cap_basic':'Market kapitalization'}, text='Company')
|
|
114
116
|
|
|
115
117
|
|
|
116
118
|
fig.add_annotation( x=row_df['name'].iloc[0], y=row_df['market_cap_basic'].iloc[0], text= f"{market_cap}", showarrow=True, align="center", bordercolor="#c7c7c7", font=dict(family="Courier New, monospace", size=16, color="#214e34" ), borderwidth=2, borderpad=4, bgcolor="#f4fdff", opacity=0.8, arrowhead=2, arrowsize=1, arrowwidth=1, ax=65,ay=-45)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|