mypythproject 0.1.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- mypythproject/DashBoard.py +357 -0
- mypythproject/__init__.py +3 -0
- mypythproject/mypythproject.py +26 -0
- mypythproject/optimization_techniques.py +240 -0
- mypythproject/sp500_companies.csv +504 -0
- mypythproject/tickers.py +10 -0
- mypythproject-0.1.1.dist-info/LICENSE +22 -0
- mypythproject-0.1.1.dist-info/METADATA +44 -0
- mypythproject-0.1.1.dist-info/RECORD +10 -0
- mypythproject-0.1.1.dist-info/WHEEL +4 -0
@@ -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,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
|
mypythproject/tickers.py
ADDED
@@ -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
|
@@ -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,10 @@
|
|
1
|
+
mypythproject/DashBoard.py,sha256=yzpZPXUBPNx9z5I_wLHGsZUsbt6lEaXPBSjVSKIoQ9I,12074
|
2
|
+
mypythproject/__init__.py,sha256=v4bN6tc6I04o6kyMLEIbEdYP67b6ad9SikMa-xepG7Q,115
|
3
|
+
mypythproject/mypythproject.py,sha256=zPgB1g1ijIkRbIWXCVQ_vcl1fm4e7NSl088YXLn6PK4,849
|
4
|
+
mypythproject/optimization_techniques.py,sha256=hwLSNYeC4TBMmWoaqf_FRf5_vUUX9tkn_tmXmFgnpUc,8842
|
5
|
+
mypythproject/sp500_companies.csv,sha256=WFerV0sFOA0TN_IlzpbRj_LBaG70T6CNYPhuD8tiAo0,17757
|
6
|
+
mypythproject/tickers.py,sha256=CLOvr__n78lkgGxIOzE9Pw8ukBkHKMg6UeEr8D3TJCQ,350
|
7
|
+
mypythproject-0.1.1.dist-info/LICENSE,sha256=dk-TNwoEpjaKVZ6mhXpOLNXGsQFob9OalWMzYUEex_4,1071
|
8
|
+
mypythproject-0.1.1.dist-info/METADATA,sha256=9DxaUU_VdbUpxokNQEfU3wXaTj8xtajCt3j8lNgqPwo,1433
|
9
|
+
mypythproject-0.1.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
10
|
+
mypythproject-0.1.1.dist-info/RECORD,,
|