mypythproject 0.1.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.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024, Amine Lahlou
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.1
2
+ Name: mypythproject
3
+ Version: 0.1.1
4
+ Summary: An extension of pybacktestchain that enhances portfolio optimization and backtesting with advanced features.
5
+ License: MIT
6
+ Author: Amine Lahlou
7
+ Requires-Python: >=3.11,<4.0
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: dash (>=2.18.2,<3.0.0)
14
+ Requires-Dist: matplotlib (>=3.10.0,<4.0.0)
15
+ Requires-Dist: numba (>=0.60.0,<0.61.0)
16
+ Requires-Dist: pybacktestchain (>=0.2.1,<0.3.0)
17
+ Description-Content-Type: text/markdown
18
+
19
+ # mypythproject
20
+
21
+ An extension of pybacktestchain that enhances portfolio optimization and backtesting with advanced features.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ $ pip install mypythproject
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ - TODO
32
+
33
+ ## Contributing
34
+
35
+ Interested in contributing? Check out the contributing guidelines. Please note that this project is released with a Code of Conduct. By contributing to this project, you agree to abide by its terms.
36
+
37
+ ## License
38
+
39
+ `mypythproject` was created by Amine Lahlou. It is licensed under the terms of the MIT license.
40
+
41
+ ## Credits
42
+
43
+ `mypythproject` was created with [`cookiecutter`](https://cookiecutter.readthedocs.io/en/latest/) and the `py-pkgs-cookiecutter` [template](https://github.com/py-pkgs/py-pkgs-cookiecutter).
44
+
@@ -0,0 +1,25 @@
1
+ # mypythproject
2
+
3
+ An extension of pybacktestchain that enhances portfolio optimization and backtesting with advanced features.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ $ pip install mypythproject
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ - TODO
14
+
15
+ ## Contributing
16
+
17
+ Interested in contributing? Check out the contributing guidelines. Please note that this project is released with a Code of Conduct. By contributing to this project, you agree to abide by its terms.
18
+
19
+ ## License
20
+
21
+ `mypythproject` was created by Amine Lahlou. It is licensed under the terms of the MIT license.
22
+
23
+ ## Credits
24
+
25
+ `mypythproject` was created with [`cookiecutter`](https://cookiecutter.readthedocs.io/en/latest/) and the `py-pkgs-cookiecutter` [template](https://github.com/py-pkgs/py-pkgs-cookiecutter).
@@ -0,0 +1,31 @@
1
+ [tool.poetry]
2
+ name = "mypythproject"
3
+ version = "0.1.1"
4
+ description = "An extension of pybacktestchain that enhances portfolio optimization and backtesting with advanced features."
5
+ authors = ["Amine Lahlou"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+
9
+ [tool.poetry.dependencies]
10
+ python = "^3.11"
11
+ pybacktestchain = "^0.2.1"
12
+ numba = "^0.60.0"
13
+ dash = "^2.18.2"
14
+ matplotlib = "^3.10.0"
15
+
16
+ [tool.poetry.dev-dependencies]
17
+
18
+ [tool.poetry.group.dev.dependencies]
19
+ python-semantic-release = "^9.15.2"
20
+ pytest = "^8.3.4"
21
+ pytest-cov = "^6.0.0"
22
+
23
+ [build-system]
24
+ requires = ["poetry-core>=1.0.0"]
25
+ build-backend = "poetry.core.masonry.api"
26
+
27
+ [tool.semantic_release]
28
+ version_variable = "pyproject.toml:version"
29
+ version_toml = [
30
+ "pyproject.toml:tool.poetry.version",
31
+ ]
@@ -0,0 +1,357 @@
1
+ import dash
2
+ from dash import dcc, html, dash_table
3
+ from dash.dependencies import Input, Output, State
4
+ from datetime import datetime, timedelta
5
+ import pandas as pd
6
+ import plotly.graph_objs as go
7
+ from pybacktestchain.data_module import get_stock_data
8
+ from pybacktestchain.broker import Backtest, StopLoss, Broker, Position
9
+ from optimization_techniques import MaxSharpe, MinVariance, MaxReturn
10
+ from pybacktestchain.data_module import FirstTwoMoments
11
+ from tickers import csv_to_ticker_dict
12
+ import logging
13
+ import random
14
+ import string
15
+
16
+ # Remove yfinance error logs
17
+ logging.getLogger("yfinance").setLevel(logging.CRITICAL)
18
+
19
+ # Map the symbols in the dictionary to securities
20
+ sp_dict = csv_to_ticker_dict()
21
+ universe_options = [
22
+ {"label": security, "value": symbol} for symbol, security in sp_dict.items()
23
+ ]
24
+
25
+ # Create Dash App
26
+ app = dash.Dash(__name__)
27
+
28
+ app.layout = html.Div([
29
+ html.H1("Python Project - Backtest Portfolio Value", style={'marginBottom': '20px'}),
30
+
31
+ html.Div([
32
+ html.Label("Initial Date:"),
33
+ dcc.DatePickerSingle(
34
+ id='initial-date',
35
+ date='2019-01-01',
36
+ display_format='YYYY-MM-DD'
37
+ )
38
+ ], style={'marginBottom': '20px'}),
39
+
40
+ html.Div([
41
+ html.Label("Final Date:"),
42
+ dcc.DatePickerSingle(
43
+ id='final-date',
44
+ date='2020-01-01',
45
+ display_format='YYYY-MM-DD'
46
+ )
47
+ ], style={'marginBottom': '20px'}),
48
+
49
+ html.Div([
50
+ html.Label("Optimization Technique:"),
51
+ dcc.Dropdown(
52
+ id='information-class',
53
+ options=[
54
+ {'label': 'FirstTwoMoments', 'value': 'first_two_moments'},
55
+ {'label': 'MaxReturn', 'value': 'max_return'},
56
+ {'label': 'MinVariance', 'value': 'min_variance'},
57
+ {'label': 'MaxSharpe', 'value': 'max_sharpe'},
58
+ ],
59
+ value='first_two_moments',
60
+ clearable=False
61
+ )
62
+ ], style={'width': '300px', 'marginBottom': '20px'}),
63
+
64
+ html.Div([
65
+ html.Label("Select S&P500 Securities:"),
66
+ dcc.Dropdown(
67
+ id='universe-dropdown',
68
+ options=universe_options,
69
+ value=[],
70
+ multi=True,
71
+ placeholder='Pick one or more securities'
72
+ )
73
+ ], style={'width': '400px', 'marginBottom': '20px'}),
74
+
75
+ html.Button("Run Backtest", id='run-button', n_clicks=0,
76
+ style={'marginTop': '20px', 'marginBottom': '20px'}),
77
+
78
+ html.Div([
79
+ html.H3("Final Portfolio Summary"),
80
+ dash_table.DataTable(id='portfolio-summary-table', style_table={'overflowX': 'auto'})
81
+ ], style={'marginTop': '40px'}),
82
+
83
+ dcc.Graph(id='correlation-graph', style={'marginTop': '40px'}),
84
+
85
+ dcc.Graph(id='portfolio-value-graph', style={'marginTop': '40px'}),
86
+
87
+ html.Div([
88
+ html.H3("Statistics (Daily Returns)"),
89
+ dash_table.DataTable(
90
+ id='stats-table',
91
+ style_table={'overflowX': 'auto'},
92
+ style_cell={'textAlign': 'center'}
93
+ )
94
+ ], style={'marginTop': '40px'})
95
+ ])
96
+
97
+ @app.callback(
98
+ [
99
+ Output('portfolio-summary-table', 'data'),
100
+ Output('portfolio-summary-table', 'columns'),
101
+ Output('correlation-graph', 'figure'),
102
+ Output('portfolio-value-graph', 'figure'),
103
+ Output('stats-table', 'data'),
104
+ Output('stats-table', 'columns')
105
+ ],
106
+ Input('run-button', 'n_clicks'),
107
+ State('initial-date', 'date'),
108
+ State('final-date', 'date'),
109
+ State('information-class', 'value'),
110
+ State('universe-dropdown', 'value')
111
+ )
112
+
113
+ def run_backtest(n_clicks, init_date_str, final_date_str, information_class_str, selected_symbols):
114
+ if n_clicks == 0:
115
+ return [], [], go.Figure(), go.Figure(), [], []
116
+
117
+ init_date = datetime.strptime(init_date_str, "%Y-%m-%d")
118
+ final_date = datetime.strptime(final_date_str, "%Y-%m-%d")
119
+
120
+ # Map information class
121
+ information_class = {
122
+ 'first_two_moments': FirstTwoMoments,
123
+ 'max_return': MaxReturn,
124
+ 'min_variance': MinVariance,
125
+ 'max_sharpe': MaxSharpe
126
+ }.get(information_class_str, FirstTwoMoments)
127
+
128
+ # -------------------------
129
+ # 1) BACKTEST AND BROKER
130
+ # -------------------------
131
+ backtest = Backtest(
132
+ initial_date=init_date,
133
+ final_date=final_date,
134
+ information_class=information_class,
135
+ risk_model=StopLoss,
136
+ name_blockchain='backtest_' + ''.join(random.choices(string.ascii_lowercase + string.digits, k=5)),
137
+ verbose=False
138
+ )
139
+ backtest.universe = selected_symbols
140
+
141
+ backtest.run_backtest()
142
+ broker = Broker(cash=1_000_000, verbose=False)
143
+
144
+ # Transaction log from the backtest
145
+ transaction_log = backtest.broker.get_transaction_log()
146
+
147
+ # We'll track daily portfolio value
148
+ portfolio_values = []
149
+ last_prices = {}
150
+ rebalance_dates = []
151
+
152
+ current_date = init_date
153
+ while current_date <= final_date:
154
+ # Skip weekends explicitly
155
+ if current_date.weekday() >= 5:
156
+ current_date += timedelta(days=1)
157
+ continue
158
+
159
+ # Filter transactions for current day
160
+ daily_transactions = transaction_log[transaction_log['Date'] == current_date]
161
+ for _, transaction in daily_transactions.iterrows():
162
+ ticker = transaction['Ticker']
163
+ action = transaction['Action']
164
+ quantity = transaction['Quantity']
165
+ price = transaction['Price']
166
+
167
+ if action == 'BUY':
168
+ broker.buy(ticker, quantity, price, current_date)
169
+ elif action == 'SELL':
170
+ broker.sell(ticker, quantity, price, current_date)
171
+
172
+ # Check for rebalancing
173
+ if backtest.rebalance_flag().time_to_rebalance(current_date):
174
+ rebalance_dates.append(current_date)
175
+
176
+ # Get current market prices
177
+ market_prices = {}
178
+ for ticker in broker.positions.keys():
179
+ try:
180
+ data = get_stock_data(
181
+ ticker,
182
+ current_date.strftime('%Y-%m-%d'),
183
+ (current_date + timedelta(days=1)).strftime('%Y-%m-%d')
184
+ )
185
+ if not data.empty:
186
+ market_prices[ticker] = data.iloc[-1]['Close']
187
+ last_prices[ticker] = market_prices[ticker]
188
+ else:
189
+ market_prices[ticker] = last_prices.get(ticker, 0)
190
+ except Exception:
191
+ market_prices[ticker] = last_prices.get(ticker, 0)
192
+
193
+ # Calculate portfolio value for the current day
194
+ try:
195
+ portfolio_value = broker.get_portfolio_value(market_prices)
196
+ except Exception:
197
+ # If something goes wrong, fallback to previous day
198
+ portfolio_value = portfolio_values[-1][1] if portfolio_values else 1_000_000
199
+
200
+ portfolio_values.append((current_date, portfolio_value))
201
+
202
+ current_date += timedelta(days=1)
203
+
204
+ # -------------------------
205
+ # 2) PREPARE SUMMARY TABLE
206
+ # -------------------------
207
+ final_market_prices = {
208
+ ticker: last_prices.get(ticker, 0) for ticker in broker.positions.keys()
209
+ }
210
+ summary_data = []
211
+ for ticker, position in broker.positions.items():
212
+ summary_data.append({
213
+ "Ticker": ticker,
214
+ "Shares": position.quantity,
215
+ "Last Price": final_market_prices[ticker],
216
+ "Value": position.quantity * final_market_prices[ticker]
217
+ })
218
+
219
+ total_value = sum(item["Value"] for item in summary_data) + broker.cash
220
+ summary_data.append({
221
+ "Ticker": "Total",
222
+ "Shares": "-",
223
+ "Last Price": "-",
224
+ "Value": total_value
225
+ })
226
+
227
+ summary_columns = [
228
+ {"name": "Ticker", "id": "Ticker"},
229
+ {"name": "Shares", "id": "Shares"},
230
+ {"name": "Last Price", "id": "Last Price"},
231
+ {"name": "Value", "id": "Value"}
232
+ ]
233
+
234
+ # -------------------------
235
+ # 3) CORRELATION GRAPH
236
+ # -------------------------
237
+ # Build a DataFrame of daily closes for each selected symbol so we can compute daily returns and correlation.
238
+ price_df = pd.DataFrame()
239
+ for symbol in selected_symbols:
240
+ data = get_stock_data(symbol, init_date_str, final_date_str)
241
+ if not data.empty:
242
+ # Align on date index to handle merges properly
243
+ data = data[['Date','Close']].set_index('Date')
244
+ data.index = pd.to_datetime(data.index)
245
+ price_df[symbol] = data['Close']
246
+
247
+ # Drop any days that are all NaN
248
+ price_df.dropna(how='all', inplace=True)
249
+
250
+ # Compute daily returns and then plot correlation heatmap
251
+ ret_df = price_df.pct_change().dropna()
252
+ if not ret_df.empty:
253
+ corr_matrix = ret_df.corr()
254
+ corr_fig = go.Figure(
255
+ data=go.Heatmap(
256
+ z=corr_matrix.values,
257
+ x=corr_matrix.columns,
258
+ y=corr_matrix.columns,
259
+ colorscale='RdYlGn',
260
+ zmin=-1,
261
+ zmax=1
262
+ )
263
+ )
264
+ corr_fig.update_layout(title="Correlation Heatmap of Daily Returns")
265
+ else:
266
+ corr_fig = go.Figure()
267
+
268
+ # -------------------------
269
+ # 4) PORTFOLIO VALUE GRAPH
270
+ # -------------------------
271
+ df_portfolio = pd.DataFrame(portfolio_values, columns=['Date', 'Portfolio Value'])
272
+ fig_portfolio = go.Figure()
273
+ fig_portfolio.add_trace(
274
+ go.Scatter(
275
+ x=df_portfolio['Date'],
276
+ y=df_portfolio['Portfolio Value'],
277
+ mode='lines',
278
+ name='Portfolio Value'
279
+ )
280
+ )
281
+ # Add a reference line at 1M
282
+ fig_portfolio.add_trace(
283
+ go.Scatter(
284
+ x=df_portfolio['Date'],
285
+ y=[1_000_000] * len(df_portfolio),
286
+ mode='lines',
287
+ line=dict(color='red', dash='dash'),
288
+ name='1M Threshold'
289
+ )
290
+ )
291
+ # Mark rebalancing points
292
+ for reb_date in rebalance_dates:
293
+ marker_day = reb_date - timedelta(days=1)
294
+ val = df_portfolio.loc[df_portfolio['Date'] == marker_day, 'Portfolio Value']
295
+ if not val.empty:
296
+ fig_portfolio.add_trace(
297
+ go.Scatter(
298
+ x=[marker_day],
299
+ y=[val.values[0]],
300
+ mode='markers',
301
+ marker=dict(color='blue', size=10, symbol='circle'),
302
+ showlegend=False
303
+ )
304
+ )
305
+ fig_portfolio.update_layout(
306
+ title="Portfolio Value Over Time",
307
+ xaxis_title="Date",
308
+ yaxis_title="Portfolio Value"
309
+ )
310
+
311
+ # -------------------------
312
+ # 5) STATISTICS TABLE
313
+ # -------------------------
314
+ stats_data = []
315
+ if not ret_df.empty:
316
+ # Per-ticker stats:
317
+ for symbol in ret_df.columns:
318
+ avg_return = ret_df[symbol].mean() * 100
319
+ std_return = ret_df[symbol].std() * 100
320
+ stats_data.append({
321
+ 'Ticker': symbol,
322
+ 'Average Return (%)': round(avg_return, 2),
323
+ 'Std Dev (%)': round(std_return, 2)
324
+ })
325
+
326
+ # Entire portfolio stats:
327
+ if len(df_portfolio) > 1:
328
+ df_portfolio['Daily Return'] = df_portfolio['Portfolio Value'].pct_change()
329
+ # Drop the first row (NaN return)
330
+ daily_returns = df_portfolio['Daily Return'].dropna()
331
+
332
+ if not daily_returns.empty:
333
+ avg_port = daily_returns.mean() * 100
334
+ std_port = daily_returns.std() * 100
335
+ stats_data.append({
336
+ 'Ticker': 'Entire Portfolio',
337
+ 'Average Return (%)': round(avg_port, 2),
338
+ 'Std Dev (%)': round(std_port, 2)
339
+ })
340
+
341
+ stats_columns = [
342
+ {'name': 'Ticker', 'id': 'Ticker'},
343
+ {'name': 'Average Return (%)', 'id': 'Average Return (%)'},
344
+ {'name': 'Std Dev (%)', 'id': 'Std Dev (%)'}
345
+ ]
346
+
347
+ return (
348
+ summary_data,
349
+ summary_columns,
350
+ corr_fig,
351
+ fig_portfolio,
352
+ stats_data,
353
+ stats_columns
354
+ )
355
+
356
+ if __name__ == '__main__':
357
+ app.run_server(debug=True)
@@ -0,0 +1,3 @@
1
+ # read version from installed package
2
+ from importlib.metadata import version
3
+ __version__ = version("mypythproject")
@@ -0,0 +1,26 @@
1
+ from pybacktestchain.broker import Backtest, StopLoss
2
+ from pybacktestchain.blockchain import load_blockchain
3
+ from datetime import datetime
4
+ from optimization_techniques import MaxSharpe
5
+ from optimization_techniques import MinVariance
6
+ from optimization_techniques import MaxReturn
7
+ from pybacktestchain.data_module import FirstTwoMoments
8
+
9
+ # Set verbosity for logging
10
+ verbose = False # Set to True to enable logging, or False to suppress it
11
+
12
+ backtest = Backtest(
13
+ initial_date=datetime(2019, 1, 1),
14
+ final_date=datetime(2020, 1, 1),
15
+ information_class=FirstTwoMoments,
16
+ risk_model=StopLoss,
17
+ name_blockchain='backtest',
18
+ verbose=verbose
19
+ )
20
+ backtest.universe = ['BAC','JPM','GS']
21
+ backtest.run_backtest()
22
+ block_chain = load_blockchain('backtest')
23
+
24
+ print(str(block_chain))
25
+ # check if the blockchain is valid
26
+ print(block_chain.is_valid())
@@ -0,0 +1,240 @@
1
+ import yfinance as yf
2
+ import pandas as pd
3
+ from sec_cik_mapper import StockMapper
4
+ from dataclasses import dataclass
5
+ from datetime import datetime, timedelta
6
+ import logging
7
+ from scipy.optimize import minimize
8
+ import numpy as np
9
+ from pybacktestchain.data_module import Information
10
+
11
+ @dataclass
12
+ class MaxSharpe(Information):
13
+ def compute_portfolio(self, t: datetime, information_set: dict):
14
+ try:
15
+ mu = information_set['expected_return']
16
+ Sigma = information_set['covariance_matrix']
17
+ n = len(mu)
18
+
19
+ # Sharpe objective
20
+ def sharpe_ratio_neg(x):
21
+ eps = 1e-8 # Add small epsilon to avoid division by zero
22
+ numerator = x.dot(mu)
23
+ denominator = np.sqrt(x.dot(Sigma).dot(x)) + eps
24
+ return - numerator / denominator
25
+
26
+ # constraints:
27
+ constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
28
+ bounds = [(0.0, 1.0)] * n
29
+
30
+ # initial guess, equal weights
31
+ x0 = np.ones(n) / n
32
+
33
+ res = minimize(sharpe_ratio_neg,
34
+ x0,
35
+ constraints=constraints,
36
+ bounds=bounds,
37
+ method='SLSQP')
38
+
39
+ # prepare dictionary
40
+ portfolio = {k: None for k in information_set['companies']}
41
+
42
+ # if converged update
43
+ if res.success:
44
+ for i, company in enumerate(information_set['companies']):
45
+ portfolio[company] = res.x[i]
46
+ else:
47
+ raise Exception("Optimization did not converge")
48
+
49
+ return portfolio
50
+
51
+ except Exception as e:
52
+ # if something goes wrong return an equal weigh portfolio but let the user know
53
+ logging.warning("Error computing portfolio, returning equal weight portfolio")
54
+ logging.warning(e)
55
+ return {k: 1/len(information_set['companies'])
56
+ for k in information_set['companies']}
57
+
58
+
59
+ def compute_information(self, t: datetime):
60
+ # get the data module
61
+ data = self.slice_data(t)
62
+ # the information set will be a dictionary with data
63
+ information_set = {}
64
+ # sort data by ticker and date
65
+ data = data.sort_values(by=[self.company_column, self.time_column])
66
+
67
+ # compute returns
68
+ data['return'] = data.groupby(self.company_column)[self.adj_close_column].pct_change()
69
+
70
+ # expected return by company
71
+ information_set['expected_return'] = data.groupby(self.company_column)['return'].mean().to_numpy()
72
+
73
+ # covariance matrix
74
+
75
+ # 1. pivot the data
76
+ data_pivot = data.pivot(index=self.time_column,
77
+ columns=self.company_column,
78
+ values=self.adj_close_column)
79
+ # drop missing values
80
+ data_pivot = data_pivot.dropna(axis=0)
81
+ # 2. compute the covariance matrix
82
+ covariance_matrix = data_pivot.cov().to_numpy()
83
+
84
+ # add to information set
85
+ information_set['covariance_matrix'] = covariance_matrix
86
+ information_set['companies'] = data_pivot.columns.to_numpy()
87
+
88
+ return information_set
89
+
90
+ @dataclass
91
+ class MinVariance(Information):
92
+ def compute_portfolio(self, t: datetime, information_set: dict):
93
+ try:
94
+ mu = information_set['expected_return']
95
+ Sigma = information_set['covariance_matrix']
96
+ n = len(mu)
97
+
98
+ # Min Variance objective
99
+ def variance_obj(x):
100
+ return x.dot(Sigma).dot(x)
101
+
102
+ # constraints:
103
+ constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
104
+ bounds = [(0.0, 1.0)] * n
105
+
106
+ # initial guess, equal weights
107
+ x0 = np.ones(n) / n
108
+
109
+ res = minimize(variance_obj,
110
+ x0,
111
+ constraints=constraints,
112
+ bounds=bounds,
113
+ method='SLSQP')
114
+
115
+ # prepare dictionary
116
+ portfolio = {k: None for k in information_set['companies']}
117
+
118
+ # if converged update
119
+ if res.success:
120
+ for i, company in enumerate(information_set['companies']):
121
+ portfolio[company] = res.x[i]
122
+ else:
123
+ raise Exception("Optimization did not converge")
124
+
125
+ return portfolio
126
+
127
+ except Exception as e:
128
+ # if something goes wrong return an equal weight portfolio but let the user know
129
+ logging.warning("Error computing portfolio, returning equal weight portfolio")
130
+ logging.warning(e)
131
+ return {k: 1/len(information_set['companies'])
132
+ for k in information_set['companies']}
133
+
134
+
135
+ def compute_information(self, t: datetime):
136
+ # get the data module
137
+ data = self.slice_data(t)
138
+ # the information set will be a dictionary with data
139
+ information_set = {}
140
+ # sort data by ticker and date
141
+ data = data.sort_values(by=[self.company_column, self.time_column])
142
+
143
+ # compute returns
144
+ data['return'] = data.groupby(self.company_column)[self.adj_close_column].pct_change()
145
+
146
+ # expected return by company
147
+ information_set['expected_return'] = data.groupby(self.company_column)['return'].mean().to_numpy()
148
+
149
+ # covariance matrix
150
+
151
+ # 1. pivot the data
152
+ data_pivot = data.pivot(index=self.time_column,
153
+ columns=self.company_column,
154
+ values=self.adj_close_column)
155
+ # drop missing values
156
+ data_pivot = data_pivot.dropna(axis=0)
157
+ # 2. compute the covariance matrix
158
+ covariance_matrix = data_pivot.cov().to_numpy()
159
+
160
+ # add to information set
161
+ information_set['covariance_matrix'] = covariance_matrix
162
+ information_set['companies'] = data_pivot.columns.to_numpy()
163
+
164
+ return information_set
165
+
166
+ @dataclass
167
+ class MaxReturn(Information):
168
+ def compute_portfolio(self, t: datetime, information_set: dict):
169
+ try:
170
+ mu = information_set['expected_return']
171
+ Sigma = information_set['covariance_matrix']
172
+ n = len(mu)
173
+
174
+ # Max Return objective
175
+ def neg_return(x):
176
+ return -x.dot(mu)
177
+
178
+ # constraints:
179
+ constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
180
+ bounds = [(0.0, 1.0)] * n
181
+
182
+ # initial guess, equal weights
183
+ x0 = np.ones(n) / n
184
+
185
+ res = minimize(neg_return,
186
+ x0,
187
+ constraints=constraints,
188
+ bounds=bounds,
189
+ method='SLSQP')
190
+
191
+ # prepare dictionary
192
+ portfolio = {k: None for k in information_set['companies']}
193
+
194
+ # if converged update
195
+ if res.success:
196
+ for i, company in enumerate(information_set['companies']):
197
+ portfolio[company] = res.x[i]
198
+ else:
199
+ raise Exception("Optimization did not converge")
200
+
201
+ return portfolio
202
+
203
+ except Exception as e:
204
+ # if something goes wrong return an equal weight portfolio but let the user know
205
+ logging.warning("Error computing portfolio, returning equal weight portfolio")
206
+ logging.warning(e)
207
+ return {k: 1/len(information_set['companies'])
208
+ for k in information_set['companies']}
209
+
210
+
211
+ def compute_information(self, t: datetime):
212
+ # get the data module
213
+ data = self.slice_data(t)
214
+ # the information set will be a dictionary with data
215
+ information_set = {}
216
+ # sort data by ticker and date
217
+ data = data.sort_values(by=[self.company_column, self.time_column])
218
+
219
+ # compute returns
220
+ data['return'] = data.groupby(self.company_column)[self.adj_close_column].pct_change()
221
+
222
+ # expected return by company
223
+ information_set['expected_return'] = data.groupby(self.company_column)['return'].mean().to_numpy()
224
+
225
+ # covariance matrix
226
+
227
+ # 1. pivot the data
228
+ data_pivot = data.pivot(index=self.time_column,
229
+ columns=self.company_column,
230
+ values=self.adj_close_column)
231
+ # drop missing values
232
+ data_pivot = data_pivot.dropna(axis=0)
233
+ # 2. compute the covariance matrix
234
+ covariance_matrix = data_pivot.cov().to_numpy()
235
+
236
+ # add to information set
237
+ information_set['covariance_matrix'] = covariance_matrix
238
+ information_set['companies'] = data_pivot.columns.to_numpy()
239
+
240
+ return information_set
@@ -0,0 +1,504 @@
1
+ Symbol;Security;GICS Sector
2
+ MMM;3M;Industrials
3
+ AOS;A. O. Smith;Industrials
4
+ ABT;Abbott Laboratories;Health Care
5
+ ABBV;AbbVie;Health Care
6
+ ACN;Accenture;Information Technology
7
+ ADBE;Adobe Inc.;Information Technology
8
+ AMD;Advanced Micro Devices;Information Technology
9
+ AES;AES Corporation;Utilities
10
+ AFL;Aflac;Financials
11
+ A;Agilent Technologies;Health Care
12
+ APD;Air Products;Materials
13
+ ABNB;Airbnb;Consumer Discretionary
14
+ AKAM;Akamai Technologies;Information Technology
15
+ ALB;Albemarle Corporation;Materials
16
+ ARE;Alexandria Real Estate Equities;Real Estate
17
+ ALGN;Align Technology;Health Care
18
+ ALLE;Allegion;Industrials
19
+ LNT;Alliant Energy;Utilities
20
+ ALL;Allstate;Financials
21
+ GOOGL;Alphabet Inc. (Class A);Communication Services
22
+ GOOG;Alphabet Inc. (Class C);Communication Services
23
+ MO;Altria;Consumer Staples
24
+ AMZN;Amazon;Consumer Discretionary
25
+ AMCR;Amcor;Materials
26
+ AEE;Ameren;Utilities
27
+ AEP;American Electric Power;Utilities
28
+ AXP;American Express;Financials
29
+ AIG;American International Group;Financials
30
+ AMT;American Tower;Real Estate
31
+ AWK;American Water Works;Utilities
32
+ AMP;Ameriprise Financial;Financials
33
+ AME;Ametek;Industrials
34
+ AMGN;Amgen;Health Care
35
+ APH;Amphenol;Information Technology
36
+ ADI;Analog Devices;Information Technology
37
+ ANSS;Ansys;Information Technology
38
+ AON;Aon;Financials
39
+ APA;APA Corporation;Energy
40
+ APO;Apollo Global Management;Financials
41
+ AAPL;Apple Inc.;Information Technology
42
+ AMAT;Applied Materials;Information Technology
43
+ APTV;Aptiv;Consumer Discretionary
44
+ ACGL;Arch Capital Group;Financials
45
+ ADM;Archer Daniels Midland;Consumer Staples
46
+ ANET;Arista Networks;Information Technology
47
+ AJG;Arthur J. Gallagher & Co.;Financials
48
+ AIZ;Assurant;Financials
49
+ T;AT&T;Communication Services
50
+ ATO;Atmos Energy;Utilities
51
+ ADSK;Autodesk;Information Technology
52
+ ADP;Automatic Data Processing;Industrials
53
+ AZO;AutoZone;Consumer Discretionary
54
+ AVB;AvalonBay Communities;Real Estate
55
+ AVY;Avery Dennison;Materials
56
+ AXON;Axon Enterprise;Industrials
57
+ BKR;Baker Hughes;Energy
58
+ BALL;Ball Corporation;Materials
59
+ BAC;Bank of America;Financials
60
+ BAX;Baxter International;Health Care
61
+ BDX;Becton Dickinson;Health Care
62
+ BRK.B;Berkshire Hathaway;Financials
63
+ BBY;Best Buy;Consumer Discretionary
64
+ TECH;Bio-Techne;Health Care
65
+ BIIB;Biogen;Health Care
66
+ BLK;BlackRock;Financials
67
+ BX;Blackstone Inc.;Financials
68
+ BK;BNY Mellon;Financials
69
+ BA;Boeing;Industrials
70
+ BKNG;Booking Holdings;Consumer Discretionary
71
+ BWA;BorgWarner;Consumer Discretionary
72
+ BSX;Boston Scientific;Health Care
73
+ BMY;Bristol Myers Squibb;Health Care
74
+ AVGO;Broadcom;Information Technology
75
+ BR;Broadridge Financial Solutions;Industrials
76
+ BRO;Brown & Brown;Financials
77
+ BF.B;Brown–Forman;Consumer Staples
78
+ BLDR;Builders FirstSource;Industrials
79
+ BG;Bunge Global;Consumer Staples
80
+ BXP;BXP, Inc.;Real Estate
81
+ CHRW;C.H. Robinson;Industrials
82
+ CDNS;Cadence Design Systems;Information Technology
83
+ CZR;Caesars Entertainment;Consumer Discretionary
84
+ CPT;Camden Property Trust;Real Estate
85
+ CPB;Campbell Soup Company;Consumer Staples
86
+ COF;Capital One;Financials
87
+ CAH;Cardinal Health;Health Care
88
+ KMX;CarMax;Consumer Discretionary
89
+ CCL;Carnival;Consumer Discretionary
90
+ CARR;Carrier Global;Industrials
91
+ CAT;Caterpillar Inc.;Industrials
92
+ CBOE;Cboe Global Markets;Financials
93
+ CBRE;CBRE Group;Real Estate
94
+ CDW;CDW;Information Technology
95
+ CE;Celanese;Materials
96
+ COR;Cencora;Health Care
97
+ CNC;Centene Corporation;Health Care
98
+ CNP;CenterPoint Energy;Utilities
99
+ CF;CF Industries;Materials
100
+ CRL;Charles River Laboratories;Health Care
101
+ SCHW;Charles Schwab Corporation;Financials
102
+ CHTR;Charter Communications;Communication Services
103
+ CVX;Chevron Corporation;Energy
104
+ CMG;Chipotle Mexican Grill;Consumer Discretionary
105
+ CB;Chubb Limited;Financials
106
+ CHD;Church & Dwight;Consumer Staples
107
+ CI;Cigna;Health Care
108
+ CINF;Cincinnati Financial;Financials
109
+ CTAS;Cintas;Industrials
110
+ CSCO;Cisco;Information Technology
111
+ C;Citigroup;Financials
112
+ CFG;Citizens Financial Group;Financials
113
+ CLX;Clorox;Consumer Staples
114
+ CME;CME Group;Financials
115
+ CMS;CMS Energy;Utilities
116
+ KO;Coca-Cola Company (The);Consumer Staples
117
+ CTSH;Cognizant;Information Technology
118
+ CL;Colgate-Palmolive;Consumer Staples
119
+ CMCSA;Comcast;Communication Services
120
+ CAG;Conagra Brands;Consumer Staples
121
+ COP;ConocoPhillips;Energy
122
+ ED;Consolidated Edison;Utilities
123
+ STZ;Constellation Brands;Consumer Staples
124
+ CEG;Constellation Energy;Utilities
125
+ COO;Cooper Companies (The);Health Care
126
+ CPRT;Copart;Industrials
127
+ GLW;Corning Inc.;Information Technology
128
+ CPAY;Corpay;Financials
129
+ CTVA;Corteva;Materials
130
+ CSGP;CoStar Group;Real Estate
131
+ COST;Costco;Consumer Staples
132
+ CTRA;Coterra;Energy
133
+ CRWD;CrowdStrike;Information Technology
134
+ CCI;Crown Castle;Real Estate
135
+ CSX;CSX Corporation;Industrials
136
+ CMI;Cummins;Industrials
137
+ CVS;CVS Health;Health Care
138
+ DHR;Danaher Corporation;Health Care
139
+ DRI;Darden Restaurants;Consumer Discretionary
140
+ DVA;DaVita;Health Care
141
+ DAY;Dayforce;Industrials
142
+ DECK;Deckers Brands;Consumer Discretionary
143
+ DE;Deere & Company;Industrials
144
+ DELL;Dell Technologies;Information Technology
145
+ DAL;Delta Air Lines;Industrials
146
+ DVN;Devon Energy;Energy
147
+ DXCM;Dexcom;Health Care
148
+ FANG;Diamondback Energy;Energy
149
+ DLR;Digital Realty;Real Estate
150
+ DFS;Discover Financial;Financials
151
+ DG;Dollar General;Consumer Staples
152
+ DLTR;Dollar Tree;Consumer Staples
153
+ D;Dominion Energy;Utilities
154
+ DPZ;Domino's;Consumer Discretionary
155
+ DOV;Dover Corporation;Industrials
156
+ DOW;Dow Inc.;Materials
157
+ DHI;D. R. Horton;Consumer Discretionary
158
+ DTE;DTE Energy;Utilities
159
+ DUK;Duke Energy;Utilities
160
+ DD;DuPont;Materials
161
+ EMN;Eastman Chemical Company;Materials
162
+ ETN;Eaton Corporation;Industrials
163
+ EBAY;eBay;Consumer Discretionary
164
+ ECL;Ecolab;Materials
165
+ EIX;Edison International;Utilities
166
+ EW;Edwards Lifesciences;Health Care
167
+ EA;Electronic Arts;Communication Services
168
+ ELV;Elevance Health;Health Care
169
+ EMR;Emerson Electric;Industrials
170
+ ENPH;Enphase Energy;Information Technology
171
+ ETR;Entergy;Utilities
172
+ EOG;EOG Resources;Energy
173
+ EPAM;EPAM Systems;Information Technology
174
+ EQT;EQT Corporation;Energy
175
+ EFX;Equifax;Industrials
176
+ EQIX;Equinix;Real Estate
177
+ EQR;Equity Residential;Real Estate
178
+ ERIE;Erie Indemnity;Financials
179
+ ESS;Essex Property Trust;Real Estate
180
+ EL;Estée Lauder Companies (The);Consumer Staples
181
+ EG;Everest Group;Financials
182
+ EVRG;Evergy;Utilities
183
+ ES;Eversource Energy;Utilities
184
+ EXC;Exelon;Utilities
185
+ EXPE;Expedia Group;Consumer Discretionary
186
+ EXPD;Expeditors International;Industrials
187
+ EXR;Extra Space Storage;Real Estate
188
+ XOM;ExxonMobil;Energy
189
+ FFIV;F5, Inc.;Information Technology
190
+ FDS;FactSet;Financials
191
+ FICO;Fair Isaac;Information Technology
192
+ FAST;Fastenal;Industrials
193
+ FRT;Federal Realty Investment Trust;Real Estate
194
+ FDX;FedEx;Industrials
195
+ FIS;Fidelity National Information Services;Financials
196
+ FITB;Fifth Third Bancorp;Financials
197
+ FSLR;First Solar;Information Technology
198
+ FE;FirstEnergy;Utilities
199
+ FI;Fiserv;Financials
200
+ FMC;FMC Corporation;Materials
201
+ F;Ford Motor Company;Consumer Discretionary
202
+ FTNT;Fortinet;Information Technology
203
+ FTV;Fortive;Industrials
204
+ FOXA;Fox Corporation (Class A);Communication Services
205
+ FOX;Fox Corporation (Class B);Communication Services
206
+ BEN;Franklin Resources;Financials
207
+ FCX;Freeport-McMoRan;Materials
208
+ GRMN;Garmin;Consumer Discretionary
209
+ IT;Gartner;Information Technology
210
+ GE;GE Aerospace;Industrials
211
+ GEHC;GE HealthCare;Health Care
212
+ GEV;GE Vernova;Industrials
213
+ GEN;Gen Digital;Information Technology
214
+ GNRC;Generac;Industrials
215
+ GD;General Dynamics;Industrials
216
+ GIS;General Mills;Consumer Staples
217
+ GM;General Motors;Consumer Discretionary
218
+ GPC;Genuine Parts Company;Consumer Discretionary
219
+ GILD;Gilead Sciences;Health Care
220
+ GPN;Global Payments;Financials
221
+ GL;Globe Life;Financials
222
+ GDDY;GoDaddy;Information Technology
223
+ GS;Goldman Sachs;Financials
224
+ HAL;Halliburton;Energy
225
+ HIG;Hartford (The);Financials
226
+ HAS;Hasbro;Consumer Discretionary
227
+ HCA;HCA Healthcare;Health Care
228
+ DOC;Healthpeak Properties;Real Estate
229
+ HSIC;Henry Schein;Health Care
230
+ HSY;Hershey Company (The);Consumer Staples
231
+ HES;Hess Corporation;Energy
232
+ HPE;Hewlett Packard Enterprise;Information Technology
233
+ HLT;Hilton Worldwide;Consumer Discretionary
234
+ HOLX;Hologic;Health Care
235
+ HD;Home Depot (The);Consumer Discretionary
236
+ HON;Honeywell;Industrials
237
+ HRL;Hormel Foods;Consumer Staples
238
+ HST;Host Hotels & Resorts;Real Estate
239
+ HWM;Howmet Aerospace;Industrials
240
+ HPQ;HP Inc.;Information Technology
241
+ HUBB;Hubbell Incorporated;Industrials
242
+ HUM;Humana;Health Care
243
+ HBAN;Huntington Bancshares;Financials
244
+ HII;Huntington Ingalls Industries;Industrials
245
+ IBM;IBM;Information Technology
246
+ IEX;IDEX Corporation;Industrials
247
+ IDXX;Idexx Laboratories;Health Care
248
+ ITW;Illinois Tool Works;Industrials
249
+ INCY;Incyte;Health Care
250
+ IR;Ingersoll Rand;Industrials
251
+ PODD;Insulet Corporation;Health Care
252
+ INTC;Intel;Information Technology
253
+ ICE;Intercontinental Exchange;Financials
254
+ IFF;International Flavors & Fragrances;Materials
255
+ IP;International Paper;Materials
256
+ IPG;Interpublic Group of Companies (The);Communication Services
257
+ INTU;Intuit;Information Technology
258
+ ISRG;Intuitive Surgical;Health Care
259
+ IVZ;Invesco;Financials
260
+ INVH;Invitation Homes;Real Estate
261
+ IQV;IQVIA;Health Care
262
+ IRM;Iron Mountain;Real Estate
263
+ JBHT;J.B. Hunt;Industrials
264
+ JBL;Jabil;Information Technology
265
+ JKHY;Jack Henry & Associates;Financials
266
+ J;Jacobs Solutions;Industrials
267
+ JNJ;Johnson & Johnson;Health Care
268
+ JCI;Johnson Controls;Industrials
269
+ JPM;JPMorgan Chase;Financials
270
+ JNPR;Juniper Networks;Information Technology
271
+ K;Kellanova;Consumer Staples
272
+ KVUE;Kenvue;Consumer Staples
273
+ KDP;Keurig Dr Pepper;Consumer Staples
274
+ KEY;KeyCorp;Financials
275
+ KEYS;Keysight Technologies;Information Technology
276
+ KMB;Kimberly-Clark;Consumer Staples
277
+ KIM;Kimco Realty;Real Estate
278
+ KMI;Kinder Morgan;Energy
279
+ KKR;KKR;Financials
280
+ KLAC;KLA Corporation;Information Technology
281
+ KHC;Kraft Heinz;Consumer Staples
282
+ KR;Kroger;Consumer Staples
283
+ LHX;L3Harris;Industrials
284
+ LH;LabCorp;Health Care
285
+ LRCX;Lam Research;Information Technology
286
+ LW;Lamb Weston;Consumer Staples
287
+ LVS;Las Vegas Sands;Consumer Discretionary
288
+ LDOS;Leidos;Industrials
289
+ LEN;Lennar;Consumer Discretionary
290
+ LII;Lennox International;Industrials
291
+ LLY;Lilly (Eli);Health Care
292
+ LIN;Linde plc;Materials
293
+ LYV;Live Nation Entertainment;Communication Services
294
+ LKQ;LKQ Corporation;Consumer Discretionary
295
+ LMT;Lockheed Martin;Industrials
296
+ L;Loews Corporation;Financials
297
+ LOW;Lowe's;Consumer Discretionary
298
+ LULU;Lululemon Athletica;Consumer Discretionary
299
+ LYB;LyondellBasell;Materials
300
+ MTB;M&T Bank;Financials
301
+ MPC;Marathon Petroleum;Energy
302
+ MKTX;MarketAxess;Financials
303
+ MAR;Marriott International;Consumer Discretionary
304
+ MMC;Marsh McLennan;Financials
305
+ MLM;Martin Marietta Materials;Materials
306
+ MAS;Masco;Industrials
307
+ MA;Mastercard;Financials
308
+ MTCH;Match Group;Communication Services
309
+ MKC;McCormick & Company;Consumer Staples
310
+ MCD;McDonald's;Consumer Discretionary
311
+ MCK;McKesson Corporation;Health Care
312
+ MDT;Medtronic;Health Care
313
+ MRK;Merck & Co.;Health Care
314
+ META;Meta Platforms;Communication Services
315
+ MET;MetLife;Financials
316
+ MTD;Mettler Toledo;Health Care
317
+ MGM;MGM Resorts;Consumer Discretionary
318
+ MCHP;Microchip Technology;Information Technology
319
+ MU;Micron Technology;Information Technology
320
+ MSFT;Microsoft;Information Technology
321
+ MAA;Mid-America Apartment Communities;Real Estate
322
+ MRNA;Moderna;Health Care
323
+ MHK;Mohawk Industries;Consumer Discretionary
324
+ MOH;Molina Healthcare;Health Care
325
+ TAP;Molson Coors Beverage Company;Consumer Staples
326
+ MDLZ;Mondelez International;Consumer Staples
327
+ MPWR;Monolithic Power Systems;Information Technology
328
+ MNST;Monster Beverage;Consumer Staples
329
+ MCO;Moody's Corporation;Financials
330
+ MS;Morgan Stanley;Financials
331
+ MOS;Mosaic Company (The);Materials
332
+ MSI;Motorola Solutions;Information Technology
333
+ MSCI;MSCI;Financials
334
+ NDAQ;Nasdaq, Inc.;Financials
335
+ NTAP;NetApp;Information Technology
336
+ NFLX;Netflix;Communication Services
337
+ NEM;Newmont;Materials
338
+ NWSA;News Corp (Class A);Communication Services
339
+ NWS;News Corp (Class B);Communication Services
340
+ NEE;NextEra Energy;Utilities
341
+ NKE;Nike, Inc.;Consumer Discretionary
342
+ NI;NiSource;Utilities
343
+ NDSN;Nordson Corporation;Industrials
344
+ NSC;Norfolk Southern Railway;Industrials
345
+ NTRS;Northern Trust;Financials
346
+ NOC;Northrop Grumman;Industrials
347
+ NCLH;Norwegian Cruise Line Holdings;Consumer Discretionary
348
+ NRG;NRG Energy;Utilities
349
+ NUE;Nucor;Materials
350
+ NVDA;Nvidia;Information Technology
351
+ NVR;NVR, Inc.;Consumer Discretionary
352
+ NXPI;NXP Semiconductors;Information Technology
353
+ ORLY;O'Reilly Auto Parts;Consumer Discretionary
354
+ OXY;Occidental Petroleum;Energy
355
+ ODFL;Old Dominion;Industrials
356
+ OMC;Omnicom Group;Communication Services
357
+ ON;ON Semiconductor;Information Technology
358
+ OKE;ONEOK;Energy
359
+ ORCL;Oracle Corporation;Information Technology
360
+ OTIS;Otis Worldwide;Industrials
361
+ PCAR;Paccar;Industrials
362
+ PKG;Packaging Corporation of America;Materials
363
+ PLTR;Palantir Technologies;Information Technology
364
+ PANW;Palo Alto Networks;Information Technology
365
+ PARA;Paramount Global;Communication Services
366
+ PH;Parker Hannifin;Industrials
367
+ PAYX;Paychex;Industrials
368
+ PAYC;Paycom;Industrials
369
+ PYPL;PayPal;Financials
370
+ PNR;Pentair;Industrials
371
+ PEP;PepsiCo;Consumer Staples
372
+ PFE;Pfizer;Health Care
373
+ PCG;PG&E Corporation;Utilities
374
+ PM;Philip Morris International;Consumer Staples
375
+ PSX;Phillips 66;Energy
376
+ PNW;Pinnacle West;Utilities
377
+ PNC;PNC Financial Services;Financials
378
+ POOL;Pool Corporation;Consumer Discretionary
379
+ PPG;PPG Industries;Materials
380
+ PPL;PPL Corporation;Utilities
381
+ PFG;Principal Financial Group;Financials
382
+ PG;Procter & Gamble;Consumer Staples
383
+ PGR;Progressive Corporation;Financials
384
+ PLD;Prologis;Real Estate
385
+ PRU;Prudential Financial;Financials
386
+ PEG;Public Service Enterprise Group;Utilities
387
+ PTC;PTC Inc.;Information Technology
388
+ PSA;Public Storage;Real Estate
389
+ PHM;PulteGroup;Consumer Discretionary
390
+ PWR;Quanta Services;Industrials
391
+ QCOM;Qualcomm;Information Technology
392
+ DGX;Quest Diagnostics;Health Care
393
+ RL;Ralph Lauren Corporation;Consumer Discretionary
394
+ RJF;Raymond James Financial;Financials
395
+ RTX;RTX Corporation;Industrials
396
+ O;Realty Income;Real Estate
397
+ REG;Regency Centers;Real Estate
398
+ REGN;Regeneron Pharmaceuticals;Health Care
399
+ RF;Regions Financial Corporation;Financials
400
+ RSG;Republic Services;Industrials
401
+ RMD;ResMed;Health Care
402
+ RVTY;Revvity;Health Care
403
+ ROK;Rockwell Automation;Industrials
404
+ ROL;Rollins, Inc.;Industrials
405
+ ROP;Roper Technologies;Information Technology
406
+ ROST;Ross Stores;Consumer Discretionary
407
+ RCL;Royal Caribbean Group;Consumer Discretionary
408
+ SPGI;S&P Global;Financials
409
+ CRM;Salesforce;Information Technology
410
+ SBAC;SBA Communications;Real Estate
411
+ SLB;Schlumberger;Energy
412
+ STX;Seagate Technology;Information Technology
413
+ SRE;Sempra;Utilities
414
+ NOW;ServiceNow;Information Technology
415
+ SHW;Sherwin-Williams;Materials
416
+ SPG;Simon Property Group;Real Estate
417
+ SWKS;Skyworks Solutions;Information Technology
418
+ SJM;J.M. Smucker Company (The);Consumer Staples
419
+ SW;Smurfit WestRock;Materials
420
+ SNA;Snap-on;Industrials
421
+ SOLV;Solventum;Health Care
422
+ SO;Southern Company;Utilities
423
+ LUV;Southwest Airlines;Industrials
424
+ SWK;Stanley Black & Decker;Industrials
425
+ SBUX;Starbucks;Consumer Discretionary
426
+ STT;State Street Corporation;Financials
427
+ STLD;Steel Dynamics;Materials
428
+ STE;Steris;Health Care
429
+ SYK;Stryker Corporation;Health Care
430
+ SMCI;Supermicro;Information Technology
431
+ SYF;Synchrony Financial;Financials
432
+ SNPS;Synopsys;Information Technology
433
+ SYY;Sysco;Consumer Staples
434
+ TMUS;T-Mobile US;Communication Services
435
+ TROW;T. Rowe Price;Financials
436
+ TTWO;Take-Two Interactive;Communication Services
437
+ TPR;Tapestry, Inc.;Consumer Discretionary
438
+ TRGP;Targa Resources;Energy
439
+ TGT;Target Corporation;Consumer Staples
440
+ TEL;TE Connectivity;Information Technology
441
+ TDY;Teledyne Technologies;Information Technology
442
+ TFX;Teleflex;Health Care
443
+ TER;Teradyne;Information Technology
444
+ TSLA;Tesla, Inc.;Consumer Discretionary
445
+ TXN;Texas Instruments;Information Technology
446
+ TPL;Texas Pacific Land Corporation;Energy
447
+ TXT;Textron;Industrials
448
+ TMO;Thermo Fisher Scientific;Health Care
449
+ TJX;TJX Companies;Consumer Discretionary
450
+ TSCO;Tractor Supply;Consumer Discretionary
451
+ TT;Trane Technologies;Industrials
452
+ TDG;TransDigm Group;Industrials
453
+ TRV;Travelers Companies (The);Financials
454
+ TRMB;Trimble Inc.;Information Technology
455
+ TFC;Truist Financial;Financials
456
+ TYL;Tyler Technologies;Information Technology
457
+ TSN;Tyson Foods;Consumer Staples
458
+ USB;U.S. Bancorp;Financials
459
+ UBER;Uber;Industrials
460
+ UDR;UDR, Inc.;Real Estate
461
+ ULTA;Ulta Beauty;Consumer Discretionary
462
+ UNP;Union Pacific Corporation;Industrials
463
+ UAL;United Airlines Holdings;Industrials
464
+ UPS;United Parcel Service;Industrials
465
+ URI;United Rentals;Industrials
466
+ UNH;UnitedHealth Group;Health Care
467
+ UHS;Universal Health Services;Health Care
468
+ VLO;Valero Energy;Energy
469
+ VTR;Ventas;Real Estate
470
+ VLTO;Veralto;Industrials
471
+ VRSN;Verisign;Information Technology
472
+ VRSK;Verisk Analytics;Industrials
473
+ VZ;Verizon;Communication Services
474
+ VRTX;Vertex Pharmaceuticals;Health Care
475
+ VTRS;Viatris;Health Care
476
+ VICI;Vici Properties;Real Estate
477
+ V;Visa Inc.;Financials
478
+ VST;Vistra Corp.;Utilities
479
+ VMC;Vulcan Materials Company;Materials
480
+ WRB;W. R. Berkley Corporation;Financials
481
+ GWW;W. W. Grainger;Industrials
482
+ WAB;Wabtec;Industrials
483
+ WBA;Walgreens Boots Alliance;Consumer Staples
484
+ WMT;Walmart;Consumer Staples
485
+ DIS;Walt Disney Company (The);Communication Services
486
+ WBD;Warner Bros. Discovery;Communication Services
487
+ WM;Waste Management;Industrials
488
+ WAT;Waters Corporation;Health Care
489
+ WEC;WEC Energy Group;Utilities
490
+ WFC;Wells Fargo;Financials
491
+ WELL;Welltower;Real Estate
492
+ WST;West Pharmaceutical Services;Health Care
493
+ WDC;Western Digital;Information Technology
494
+ WY;Weyerhaeuser;Real Estate
495
+ WMB;Williams Companies;Energy
496
+ WTW;Willis Towers Watson;Financials
497
+ WDAY;Workday, Inc.;Information Technology
498
+ WYNN;Wynn Resorts;Consumer Discretionary
499
+ XEL;Xcel Energy;Utilities
500
+ XYL;Xylem Inc.;Industrials
501
+ YUM;Yum! Brands;Consumer Discretionary
502
+ ZBRA;Zebra Technologies;Information Technology
503
+ ZBH;Zimmer Biomet;Health Care
504
+ ZTS;Zoetis;Health Care
@@ -0,0 +1,10 @@
1
+ import pandas as pd
2
+
3
+ def csv_to_ticker_dict(csv_file_path="src/mypythproject/sp500_companies.csv", print_dict=False):
4
+ df = pd.read_csv(csv_file_path, delimiter=';')
5
+ ticker_dict = dict(zip(df['Symbol'], df['Security']))
6
+
7
+ if print_dict:
8
+ print(ticker_dict) # Only prints if you explicitly set print_dict=True
9
+
10
+ return ticker_dict