├── .gitignore ├── CHANGELOG.md ├── README.md ├── __init__.py ├── events ├── Condition.py ├── EventFinder.py ├── EventStudy.py ├── MultipleEvents.py ├── PastEvent.py ├── SampleConditions.py └── __init__.py ├── examples ├── Basic │ ├── DataAccess.py │ ├── DateUtils.py │ ├── EventStudy_Finder.py │ ├── EventStudy_Multiple.py │ ├── EventStudy_Past.py │ ├── FV_PV_R_n.ipynb │ ├── ListUtils.py │ ├── MarketSimulator.py │ └── MarketSimulator_orders.csv ├── Combining │ └── Events and Simulator.ipynb └── ItCFaFE │ ├── Assignment 1 - Excel │ ├── Q&A.pdf │ └── Solution.py │ ├── Assignment 1 │ ├── Q&A.pdf │ └── Solution.py │ ├── Assignment 2 │ ├── Questions │ └── Solution.py │ ├── Assignment 3 - Computations │ ├── Questions.pdf │ └── Solution.py │ ├── Assignment 4 - Matrix Algebra │ ├── Questions.pdf │ └── Solution.py │ └── README.md ├── finance.sublime-project ├── finance.sublime-workspace ├── plots ├── __init__.py └── errorfill.py ├── sim ├── MarketSimulator.py └── __init__.py ├── test ├── AllTets.py ├── FinanceTest.py ├── __init__.py ├── events │ ├── EventFinder.py │ ├── MultipleEvents.py │ ├── PastEvent.py │ ├── __init__.py │ └── docs │ │ ├── MultipleEvents_1.ods │ │ ├── MultipleEvents_window_1.csv │ │ ├── PastEvent_1.csv │ │ ├── PastEvent_1.ods │ │ ├── PastEvent_window_1.csv │ │ ├── test1_1.png │ │ └── test1_2.png ├── sim │ ├── MarketSimulator.py │ ├── __init__.py │ └── docs │ │ ├── Test_1.csv │ │ ├── Test_1.ods │ │ └── orders_1.csv └── utils │ ├── CalculatorTypes.py │ ├── CalculatorValues.py │ ├── DataAccess.py │ ├── DateUtils.py │ ├── FileManager.py │ ├── __init__.py │ └── docs │ ├── Calculator_Assets.ods │ ├── Calculator_Assets_1.csv │ ├── Calculator_TVM.ods │ ├── Calculator_TVM_1.csv │ ├── Calculator_TVM_2.csv │ └── Calculator_TVM_3.csv └── utils ├── Calculator.py ├── DataAccess.py ├── DateUtils.py ├── FileManager.py ├── ListUtils.py ├── __init__.py └── lists ├── NYSE_dates.py ├── NYSE_dates.txt ├── SP500_2008.py ├── SP500_2008.txt ├── SP500_2012.py ├── SP500_2012.txt └── __init__.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Python Specific 2 | *.py[cod] 3 | __pycache__ 4 | 5 | # Mr Developer 6 | data -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | PythonFinance 2 | ============= 3 | 4 | v0.04 - Dev 5 | ----------- 6 | - new Condition class to mark events on the Finder 7 | - new FinaceTest to easier testing 8 | - Rename BasicUtils to Calculator 9 | - Add more utils to the Calculator: 10 | - Future Value 11 | - Present Value 12 | - Rates (Annual rate) 13 | - Number of periods (n) 14 | - Efective annual return 15 | - Improve total_return to give return by position 16 | - Rename daily_returns to just returns 17 | - Add Continusly compouding to total_return and returns 18 | - Calculator Tests based on CSV files 19 | - A lot of more examples 20 | 21 | v0.035 22 | ------ 23 | - Integration between the EventFinder and MarketSimulator 24 | - MultipleEvents: 25 | - Add: Plot with error bars 26 | 27 | v0.03 28 | ----- 29 | - Bug fixes on FileManager and DataAccess 30 | - Create DateUtils: 31 | - Get dates from NYSE 32 | - Ask for more specific dates 33 | - Ask for dates between a date 34 | - Create ListUtils: 35 | - Dates from NYSE 36 | - S&P 500 symbols for some years 37 | - Create PastEvent: Analysis of an specific event: 38 | - Allows specific event window and estimation period 39 | - Expected Returns 40 | - Abnormal Returns 41 | - Cumulative Abnormal Returns 42 | - Create EventFinder: Find events on data 43 | - Create MultipleEvent: Analysis of a list of events: std, mean 44 | - Allows specific event window and estimation period 45 | - Expected Returns 46 | - Abnormal Returns 47 | - Cumulative Abnormal Returns 48 | 49 | v0.02 50 | ----- 51 | - Create MarketSimulator: Simulate orders of trades 52 | - Data Access 53 | - CHANGE: index of the DataFrame to DatetimeIndex not string 54 | - Moved the module folder from ‘./data/’ to ‘./utils/’ 55 | - Create Basic Utils: 56 | - Total Return 57 | - Daily Return 58 | - Sharpe Ratio 59 | 60 | v0.01 61 | ----- 62 | - Create FileManager: Download information from Yahoo! Finance 63 | - Create DataAccess: Manage the downloaded information 64 | - Ask for specific dates and fields of the data 65 | - Returns pandas.DataFrame 66 | - Serialization of the data -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PythonFinance 2 | ============= 3 | 4 | basic Finance Utilities for Python 5 | 6 | Requirements 7 | ------------ 8 | 9 | 1. Python >= 3 10 | 2. numpy 11 | 3. scipy 12 | 4. pandas 13 | 14 | Features 15 | -------- 16 | 17 | 1. Data Manager 18 | - Automatic download data from Yahoo! Finance 19 | - Get only interested information: dates and fields (Adj Close, Volume, ...) 20 | - Serialization (pickle) of data with custom names 21 | 2. Calculator Utils 22 | - Present Value, Future Value 23 | - Rates (Annual Rate) 24 | - Efective Annual Return 25 | - Number of Periods 26 | - Total return 27 | - Daily returns 28 | - Sharpe ratio 29 | 3. Date Utils: to handle open NYSE Dates 30 | - open dates between two dates + back and forward windows 31 | - add and substract dates 32 | 4. Market Simulator: Simulates a list of orders 33 | - Automatically download necessary data 34 | - Can load the trades from a CSV file 35 | - Can use custom list of orders (usually from the EventFinder) 36 | 37 | ### Event Study ### 38 | 39 | 1. PastEvent: Analysis of an specific event: 40 | - Allows specific event window and estimation period 41 | - Expected Returns 42 | - Abnormal Returns 43 | - Cumulative Abnormal Returns 44 | 45 | 2. EventFinder: Find events on data 46 | 47 | 3. MultipleEvent: Analysis of a list of events 48 | - Allows specific event window and estimation period 49 | - Expected Returns 50 | - Abnormal Returns 51 | - Cumulative Abnormal Returns 52 | - Plot with error bars 53 | 54 | 55 | How to use it 56 | ------------- 57 | 58 | Set the envvars: 59 | `FINANCEPATH` to where you want the data to live. 60 | `ALPHAVANTAGEKEY` to the Alpha Vantage API Key. -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/__init__.py -------------------------------------------------------------------------------- /events/Condition.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Condition(object): 4 | def __init__(self): 5 | self.id = None 6 | self.function = Condition.default 7 | 8 | @staticmethod 9 | def default(i, item, data): 10 | raise Exception('Condition.function needs to be written') -------------------------------------------------------------------------------- /events/EventFinder.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | from datetime import datetime 4 | from finance.utils import DateUtils 5 | from finance.utils import DataAccess 6 | from finance.events import Condition 7 | 8 | class EventFinder(object): 9 | def __init__(self): 10 | self.data_access = DataAccess() 11 | 12 | self.symbols = [] 13 | self.start_date = None 14 | self.end_date = None 15 | self.field = 'adjusted_close' 16 | 17 | self.condition = Condition() 18 | self.matrix = None 19 | self.num_events = 0 20 | 21 | self.oneEventPerEquity = True 22 | 23 | def generate_filename(self): 24 | return '%s%s%s%s%s%s' % (''.join(self.symbols), self.start_date.strftime('%Y-%m-%d'), 25 | self.end_date.strftime('%Y-%m-%d'), self.field, self.condition.id, 26 | str(self.oneEventPerEquity)) 27 | 28 | def search(self, oneEventPerEquity=True, useCache=True, save=True): 29 | self.oneEventPerEquity = oneEventPerEquity 30 | 31 | # 1. Load the data if requested and available 32 | self.matrix = self.data_access.load(self.generate_filename(), '.evt_matrix') 33 | if useCache and self.matrix is not None: 34 | pass 35 | else: 36 | # 2. Data was not loaded 37 | # 2.1 Get the dates, and Download/Import the data 38 | nyse_dates = DateUtils.nyse_dates(start=self.start_date, end=self.end_date) 39 | data = self.data_access.get_data(self.symbols, nyse_dates[0], nyse_dates[-1], self.field) 40 | # Special case 41 | if len(data.columns) == 1: 42 | data.columns = self.symbols 43 | 44 | # 2.2 Create and fill the matrix of events 45 | data = data[self.start_date:self.end_date] 46 | self.matrix = pd.DataFrame(index=data.index, columns=self.symbols) 47 | 48 | for symbol in self.symbols: 49 | i = 0 50 | for item in data[symbol][1:]: 51 | e = self.condition.function(i, item, data[symbol][1:]) 52 | if e: 53 | self.matrix[symbol][i+1] = 1 54 | if oneEventPerEquity == True: 55 | break 56 | i = i + 1 57 | 58 | 59 | # 3. Calculate other results and save if requested 60 | # Reduce Matrix: Sum each row and columns: if is greater than 0 there is an event 61 | self.matrix = self.matrix[self.matrix.fillna(value=0).sum(axis=1) > 0] 62 | valid_cols = self.matrix.columns[self.matrix.fillna(value=0).sum(axis=0) > 0].values 63 | self.matrix = self.matrix[valid_cols] 64 | # 3.2 Create list of events 65 | self.list = pd.Series(index=self.matrix.index, name='Equity') 66 | for idx, row in self.matrix.iterrows(): 67 | equity = row[row == 1].index[0] 68 | self.list.loc[idx] = equity 69 | # 3.3 Save 70 | self.num_events = len(self.list) 71 | if save: 72 | self.data_access.save(self.matrix, self.generate_filename(), '.evt_matrix') 73 | 74 | -------------------------------------------------------------------------------- /events/EventStudy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | from scipy import stats 4 | from datetime import datetime 5 | from finance.utils import Calculator 6 | 7 | class EventStudy(object): 8 | def __init__(self): 9 | self.data = None 10 | self.market = None 11 | 12 | self.start_period = None 13 | self.end_period = None 14 | self.start_window = None 15 | self.end_window = None 16 | 17 | 18 | def market_return(self): 19 | # 1. Linear Regression: On the estimation_period 20 | dr_data = Calculator.returns(self.data) 21 | dr_market = Calculator.returns(self.market) 22 | c_name = dr_data.columns[0] 23 | x = dr_market[c_name][self.start_period:self.end_period] 24 | y = dr_data[c_name][self.start_period:self.end_period] 25 | slope, intercept, r_value, p_value, std_error = stats.linregress(x, y) 26 | er = lambda x: x * slope + intercept 27 | 28 | # 2. Analysis on the event window 29 | # Expexted Return: 30 | self.er = dr_market[self.start_window:self.end_window].apply(er)[c_name] 31 | self.er.name = 'Expected return' 32 | # Abnormal return: Return of the data - expected return 33 | self.ar = dr_data[c_name][self.start_window:self.end_window] - self.er 34 | self.ar.name = 'Abnormal return' 35 | # Cumulative abnormal return 36 | self.car = self.ar.cumsum() 37 | self.car.name = 'Cum abnormal return' 38 | # t-test 39 | t_test_calc = lambda x: x / std_error 40 | self.t_test = self.ar.apply(t_test_calc) 41 | self.t_test.name = 't-test' 42 | self.prob = self.t_test.apply(stats.norm.cdf) 43 | self.prob.name = 'Probability' -------------------------------------------------------------------------------- /events/MultipleEvents.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | from scipy import stats 4 | from datetime import datetime 5 | import matplotlib.pyplot as plt 6 | from finance.plots.errorfill import * 7 | 8 | from finance.utils import DateUtils 9 | from finance.utils import DataAccess 10 | from finance.utils import Calculator 11 | 12 | class MultipleEvents(object): 13 | def __init__(self): 14 | self.data_access = DataAccess() 15 | 16 | self.list = None 17 | self.market = 'SPY' 18 | self.lookback_days = 20 19 | self.lookforward_days = 20 20 | self.estimation_period = 200 21 | self.field = 'adjusted_close' 22 | 23 | # Result 24 | self.equities_window = None 25 | self.equities_estimation = None 26 | self.market_window = None 27 | self.market_estimation = None 28 | 29 | self.reg_estimation = None 30 | 31 | self.dr_equities_window = None 32 | self.dr_equities_estimation = None 33 | self.dr_market_window = None 34 | self.dr_market_estimation = None 35 | 36 | self.er = None 37 | self.ar = None 38 | self.car = None 39 | 40 | def run(self): 41 | ''' 42 | Assess the events 43 | 44 | |-----100-----|-------20-------|-|--------20--------| 45 | estimation lookback event lookforward 46 | 47 | Prerequisites 48 | ------------- 49 | self.matrix 50 | self.market = 'SPY' 51 | self.lookback_days = 20 52 | self.lookforward_days = 20 53 | self.estimation_period = 200 54 | self.field = 'adjusted_close' 55 | ''' 56 | # 0. Get the dates and Download/Import the data 57 | symbols = list(set(self.list)) 58 | start_date = self.list.index[0] 59 | end_date = self.list.index[-1] 60 | nyse_dates = DateUtils.nyse_dates(start=start_date, end=end_date, 61 | lookbackDays=self.lookback_days + self.estimation_period + 1, 62 | lookforwardDays=self.lookforward_days) 63 | 64 | data = self.data_access.get_data(symbols, nyse_dates[0], nyse_dates[-1], self.field) 65 | market = self.data_access.get_data(self.market, nyse_dates[0], nyse_dates[-1], self.field) 66 | 67 | if len(data.columns) == 1: 68 | data.columns = symbols 69 | if len(data) > len(market): 70 | market = market.reindex(data.index) 71 | market.columns = [self.field] 72 | 73 | data = data.fillna(method='ffill').fillna(method='bfill') 74 | market = market.fillna(method='ffill').fillna(method='bfill') 75 | 76 | # 1. Create DataFrames with the data of each event 77 | windows_indexes = range(- self.lookback_days, self.lookforward_days + 1) 78 | estimation_indexes = range(-self.estimation_period - self.lookback_days, - self.lookback_days) 79 | self.equities_window = pd.DataFrame(index=windows_indexes) 80 | self.equities_estimation = pd.DataFrame(index=estimation_indexes) 81 | self.market_window = pd.DataFrame(index=windows_indexes) 82 | self.market_estimation = pd.DataFrame(index=estimation_indexes) 83 | 84 | dr_data = Calculator.returns(data) 85 | dr_market = Calculator.returns(market) 86 | self.dr_equities_window = pd.DataFrame(index=windows_indexes) 87 | self.dr_equities_estimation = pd.DataFrame(index=estimation_indexes) 88 | self.dr_market_window = pd.DataFrame(index=windows_indexes) 89 | self.dr_market_estimation = pd.DataFrame(index=estimation_indexes) 90 | 91 | # 2. Iterate over the list of events and fill the DataFrames 92 | for i in range(len(self.list)): 93 | symbol = self.list[i] 94 | evt_date = self.list.index[i].to_pydatetime() 95 | col_name = symbol + ' ' + evt_date.strftime('%Y-%m-%d') 96 | evt_idx = DateUtils.search_closer_date(evt_date, data[symbol].index, exact=True) 97 | 98 | # 1.1 Data on the estimation period: self.equities_estimation 99 | start_idx = evt_idx - self.lookback_days - self.estimation_period # estimation start idx on self.data 100 | end_idx = evt_idx - self.lookback_days # estimation end idx on self.data 101 | new_equities_estimation = data[symbol][start_idx:end_idx] 102 | new_equities_estimation.index = self.equities_estimation.index 103 | self.equities_estimation[col_name] = new_equities_estimation 104 | # Daily return of the equities on the estimation period 105 | new_dr_equities_estimation = dr_data[symbol][start_idx:end_idx] 106 | new_dr_equities_estimation.index = self.dr_equities_estimation.index 107 | self.dr_equities_estimation[col_name] = new_dr_equities_estimation 108 | 109 | # 1.4 Market on the estimation period: self.market_estimation 110 | new_market_estimation = market[self.field][start_idx:end_idx] 111 | new_market_estimation.index = self.market_estimation.index 112 | self.market_estimation[col_name] = new_market_estimation 113 | # Daily return of the market on the estimation period 114 | new_dr_market_estimation = dr_market[start_idx:end_idx] 115 | new_dr_market_estimation.index = self.dr_market_estimation.index 116 | self.dr_market_estimation[col_name] = new_dr_market_estimation 117 | 118 | # 1.3 Equities on the event window: self.equities_window 119 | start_idx = evt_idx - self.lookback_days # window start idx on self.data 120 | end_idx = evt_idx + self.lookforward_days + 1 # window end idx on self.data 121 | new_equities_window = data[symbol][start_idx:end_idx] 122 | new_equities_window.index = self.equities_window.index 123 | self.equities_window[col_name] = new_equities_window 124 | # Daily return of the equities on the event window 125 | new_dr_equities_window = dr_data[symbol][start_idx:end_idx] 126 | new_dr_equities_window.index = self.dr_equities_window.index 127 | self.dr_equities_window[col_name] = new_dr_equities_window 128 | 129 | # 1.4 Market on the event window: self.market_window 130 | new_market_window = market[self.field][start_idx:end_idx] 131 | new_market_window.index = self.market_window.index 132 | self.market_window[col_name] = new_market_window 133 | # Daily return of the market on the event window 134 | new_dr_market_window = dr_market[start_idx:end_idx] 135 | new_dr_market_window.index = self.dr_market_window.index 136 | self.dr_market_window[col_name] = new_dr_market_window 137 | 138 | # 3. Calculate the linear regression -> expected return 139 | self.reg_estimation = pd.DataFrame(index=self.dr_market_estimation.columns, 140 | columns=['Intercept', 'Slope', 'Std Error']) 141 | self.er = pd.DataFrame(index=self.dr_market_window.index, 142 | columns=self.dr_market_window.columns) 143 | # For each column (event) on the estimation period 144 | for col in self.dr_market_estimation.columns: 145 | # 3.1 Calculate the regression 146 | x = self.dr_market_estimation[col] 147 | y = self.dr_equities_estimation[col] 148 | slope, intercept, r_value, p_value, slope_std_error = stats.linregress(x, y) 149 | self.reg_estimation['Slope'][col] = slope 150 | self.reg_estimation['Intercept'][col] = intercept 151 | self.reg_estimation['Std Error'][col] = slope_std_error 152 | # 3.2 Calculate the expected return of each date using the regression 153 | self.er[col] = intercept + self.dr_market_window[col] * slope 154 | 155 | # 4. Final results 156 | self.er.columns.name = 'Expected return' 157 | self.mean_er = self.er.mean(axis=1) 158 | self.mean_er.name = 'Mean ER' 159 | self.std_er = self.er.std(axis=1) 160 | self.std_er.name = 'Std ER' 161 | 162 | self.ar = self.dr_equities_window - self.er 163 | self.ar.columns.name = 'Abnormal return' 164 | self.mean_ar = self.ar.mean(axis=1) 165 | self.mean_ar.name = 'Mean AR' 166 | self.std_ar = self.ar.std(axis=1) 167 | self.std_ar.name = 'Std AR' 168 | 169 | self.car = self.ar.apply(np.cumsum) 170 | self.car.columns.name = 'Cum Abnormal Return' 171 | self.mean_car = self.car.mean(axis=1) 172 | self.mean_car.name = 'Mean CAR' 173 | self.std_car = self.car.std(axis=1) 174 | self.mean_car.name = 'Mean CAR' 175 | 176 | def plot(self, which): 177 | x = self.mean_car.index.values 178 | if which == 'car': 179 | y = self.mean_car.values 180 | yerr = self.std_car.values 181 | label = self.mean_car.name 182 | elif which == 'ar': 183 | y = self.mean_ar.values 184 | yerr = self.std_ar.values 185 | label = self.mean_ar.name 186 | elif which == 'er': 187 | y = self.mean_er.values 188 | yerr = self.std_er.values 189 | label = self.mean_er.name 190 | errorfill(x, y, yerr, label=label) 191 | 192 | if __name__ == '__main__': 193 | from datetime import datetime 194 | import matplotlib.pyplot as plt 195 | from finance.events import EventFinder 196 | from finance.events import SampleConditions 197 | 198 | evtf = EventFinder() 199 | evtf.symbols = ['AMD', 'CBG'] 200 | evtf.start_date = datetime(2008, 1, 1) 201 | evtf.end_date = datetime(2009, 12, 31) 202 | evtf.condition = SampleConditions.went_below(3) 203 | evtf.search() 204 | 205 | mevt = MultipleEvents() 206 | mevt.list = evtf.list 207 | mevt.market = 'SPY' 208 | mevt.lookback_days = 20 209 | mevt.lookforward_days = 20 210 | mevt.estimation_period = 200 211 | mevt.run() 212 | print(mevt.mean_car) 213 | 214 | #mevt.plot('car') 215 | #plt.legend() 216 | #plt.show() 217 | -------------------------------------------------------------------------------- /events/PastEvent.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | from datetime import datetime 4 | from finance.utils import DateUtils 5 | from finance.utils import DataAccess 6 | from finance.events.EventStudy import EventStudy 7 | 8 | class PastEvent(EventStudy): 9 | ''' 10 | Analyse a particular equity on a particular date 11 | 12 | Necesary Parameters 13 | ------------------- 14 | date: datetime 15 | symbol: str, eg: AAPL 16 | 17 | Optional Parameters 18 | ------------------- 19 | market: str, default2-'SPY' - used to asses the event 20 | lookback_days: int, default=20 - past event window size 21 | lookforward_days: int, default=20 - future event window size 22 | estimation_period: int, default=255 23 | 24 | |-----255-----|-------20-------|-|--------20--------| 25 | estimation lookback event lookforward 26 | ''' 27 | 28 | def __init__(self): 29 | # Utils 30 | self.data_access = DataAccess() 31 | 32 | # Variables 33 | self.date = None # Date of the event 34 | self.symbol = None 35 | self.field = 'adjusted_close' 36 | self.lookback_days = 20 37 | self.lookforward_days = 20 38 | self.estimation_period = 255 39 | self.market = "SPY" 40 | 41 | # Results 42 | self.evt_window_data = None 43 | self.er = None 44 | self.ar = None 45 | self.car = None 46 | self.t_test = None 47 | self.prob = None 48 | 49 | 50 | def run(self): 51 | dates = DateUtils.nyse_dates_event(self.date, 52 | self.lookback_days, self.lookforward_days, self.estimation_period) 53 | start_date = dates[0] 54 | end_date = dates[-1] 55 | 56 | # Data to the General market_return Study 57 | self.data = self.data_access.get_data(self.symbol, start_date, end_date, self.field) 58 | evt_window_dates = dates[- self.lookforward_days - self.lookback_days - 1:] 59 | self.evt_window_data = self.data[evt_window_dates[0]:dates[-1]] 60 | self.market = self.data_access.get_data(self.market, start_date, end_date, self.field) 61 | # Parameters of the General market_return Study 62 | self.start_period = dates[0] 63 | self.end_period = dates[self.estimation_period] 64 | self.start_window = dates[self.estimation_period] 65 | self.end_window = dates[-1] 66 | 67 | # Run the Market Return method 68 | super().market_return() -------------------------------------------------------------------------------- /events/SampleConditions.py: -------------------------------------------------------------------------------- 1 | from finance.events import Condition 2 | 3 | def decrease(decrease): 4 | condition = Condition() 5 | condition.id = 'decrease' + str(decrease) 6 | condition.function = lambda i, item, data: (data[i-1] - item > decrease) 7 | return condition 8 | 9 | def increase(increase): 10 | condition = Condition() 11 | condition.id = 'increase' + str(increase) 12 | condition.function = lambda i, item, data: (item - data[i-1] > increase) 13 | return condition 14 | 15 | def went_below(below): 16 | condition = Condition() 17 | condition.id = 'went_below' + str(below) 18 | condition.function = lambda i, item, data: (data[i-1] >= below and item < below) 19 | return condition 20 | 21 | def went_above(above): 22 | condition = Condition() 23 | condition.id = 'went_above' + str(above) 24 | condition.function = lambda i, item, data: (data[i-1] <= above and item > above) 25 | return condition -------------------------------------------------------------------------------- /events/__init__.py: -------------------------------------------------------------------------------- 1 | from finance.events.Condition import Condition 2 | from finance.events.PastEvent import PastEvent 3 | from finance.events.EventFinder import EventFinder 4 | from finance.events.MultipleEvents import MultipleEvents 5 | -------------------------------------------------------------------------------- /examples/Basic/DataAccess.py: -------------------------------------------------------------------------------- 1 | import os 2 | from datetime import datetime 3 | from finance.utils import DataAccess 4 | 5 | # Option 1: Set the Enviroment Variable FINANCEPATH 6 | os.environ["FINANCEPATH"] = './data' 7 | da = DataAccess() 8 | symbols = ["GOOG", "SPY", "XOM"] 9 | start_date = datetime(2015, 1, 1) 10 | end_date = datetime(2017, 12, 31) 11 | fields = 'close' 12 | close = da.get_data(symbols, start_date, end_date, fields) 13 | print(close) 14 | 15 | # Option 2: Manualy set the PATH, overwrites option 1 16 | 17 | DataAccess.path = 'data2' 18 | da = DataAccess() 19 | 20 | symbols = ["AAPL", "GLD"] 21 | start_date = datetime(2015, 1, 1) 22 | end_date = datetime(2017, 12, 31) 23 | fields = 'close' 24 | close = da.get_data(symbols, start_date, end_date, fields) 25 | print(close) 26 | 27 | -------------------------------------------------------------------------------- /examples/Basic/DateUtils.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from finance.utils import DateUtils 3 | 4 | all_dates = DateUtils.nyse_dates() 5 | print(all_dates) 6 | 7 | print(DateUtils.nyse_dates(start=datetime(2015,1,1))) 8 | 9 | index = DateUtils.search_closer_date(datetime(2017,1,1), all_dates) 10 | print(index, all_dates[index]) -------------------------------------------------------------------------------- /examples/Basic/EventStudy_Finder.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from finance.events import SampleConditions 3 | from finance.events import EventFinder 4 | 5 | # from finance.utils import DataAccess 6 | # DataAccess.path = 'data' 7 | 8 | evtf = EventFinder() 9 | evtf.symbols = ['AMD', 'CBG', 'AAPL'] 10 | evtf.start_date = datetime(2008, 1, 1) 11 | evtf.end_date = datetime(2010, 12, 31) 12 | evtf.condition = SampleConditions.went_below(10) 13 | evtf.search(useCache=False) 14 | 15 | print("Number of events: {0}".format(evtf.num_events)) 16 | print(evtf.list) 17 | -------------------------------------------------------------------------------- /examples/Basic/EventStudy_Multiple.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import matplotlib.pyplot as plt 3 | from finance.events import EventFinder 4 | from finance.events import MultipleEvents 5 | from finance.events import SampleConditions 6 | 7 | # from finance.utils import DataAccess 8 | # DataAccess.path = 'data' 9 | 10 | evtf = EventFinder() 11 | evtf.symbols = ['AMD', 'CBG'] 12 | evtf.start_date = datetime(2008, 1, 1) 13 | evtf.end_date = datetime(2009, 12, 31) 14 | evtf.condition = SampleConditions.went_below(3) 15 | evtf.search() 16 | print(evtf.list) 17 | 18 | mevt = MultipleEvents() 19 | mevt.list = evtf.list 20 | mevt.market = 'SPY' 21 | mevt.lookback_days = 20 22 | mevt.lookforward_days = 20 23 | mevt.estimation_period = 200 24 | mevt.run() 25 | 26 | print(mevt.mean_ar) 27 | 28 | mevt.plot('car') 29 | plt.show() 30 | -------------------------------------------------------------------------------- /examples/Basic/EventStudy_Past.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import matplotlib.pyplot as plt 3 | from finance.events import PastEvent 4 | 5 | # from finance.utils import DataAccess 6 | # DataAccess.path = 'data' 7 | 8 | evt = PastEvent() 9 | evt.symbol = 'AAPL' 10 | evt.market = "^gspc" 11 | evt.lookback_days = 10 12 | evt.lookforward_days = 10 13 | evt.estimation_period = 252 14 | evt.date = datetime(2009, 1, 5) 15 | evt.run() 16 | 17 | #print("Expected Return: {0}".format(evt.er)) 18 | #print("Abnormal Return: {0}".format(evt.ar)) 19 | print(evt.car) 20 | #print("T Test: {0}".format(evt.t_test)) 21 | 22 | evt.ar.plot() 23 | plt.show() -------------------------------------------------------------------------------- /examples/Basic/FV_PV_R_n.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "from finance.utils import Calculator" 10 | ] 11 | }, 12 | { 13 | "cell_type": "heading", 14 | "metadata": {}, 15 | "level": 2, 16 | "source": [ 17 | "Futuve Value" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "You have $4321.5 USD right now and want to invest at an annual interest rate of 5.6% for 10 years.\n", 25 | "How much would you have after the 10 years?" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "Compound annually" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": {}, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/plain": [ 43 | "7452.014638066742" 44 | ] 45 | }, 46 | "execution_count": 2, 47 | "metadata": {}, 48 | "output_type": "execute_result" 49 | } 50 | ], 51 | "source": [ 52 | "Calculator.FV(PV=4321.5, R=0.056, n=10) # m=1 is default" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "Compound semmiannually" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 3, 65 | "metadata": {}, 66 | "outputs": [ 67 | { 68 | "data": { 69 | "text/plain": [ 70 | "7507.52540538301" 71 | ] 72 | }, 73 | "execution_count": 3, 74 | "metadata": {}, 75 | "output_type": "execute_result" 76 | } 77 | ], 78 | "source": [ 79 | "Calculator.FV(PV=4321.5, R=0.056, n=10, m=2)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "Compound quarterly" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 4, 92 | "metadata": {}, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "7536.20523592885" 98 | ] 99 | }, 100 | "execution_count": 4, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "Calculator.FV(PV=4321.5, R=0.056, n=10, m=4)" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "Compoung monthly" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 5, 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "data": { 123 | "text/plain": [ 124 | "7555.682646463114" 125 | ] 126 | }, 127 | "execution_count": 5, 128 | "metadata": {}, 129 | "output_type": "execute_result" 130 | } 131 | ], 132 | "source": [ 133 | "Calculator.FV(PV=4321.5, R=0.056, n=10, m=12)" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "Compound weekly" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 6, 146 | "metadata": {}, 147 | "outputs": [ 148 | { 149 | "data": { 150 | "text/plain": [ 151 | "7563.251891342945" 152 | ] 153 | }, 154 | "execution_count": 6, 155 | "metadata": {}, 156 | "output_type": "execute_result" 157 | } 158 | ], 159 | "source": [ 160 | "Calculator.FV(PV=4321.5, R=0.056, n=10, m=52)" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "Compound daily" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 7, 173 | "metadata": {}, 174 | "outputs": [ 175 | { 176 | "data": { 177 | "text/plain": [ 178 | "7565.206243320116" 179 | ] 180 | }, 181 | "execution_count": 7, 182 | "metadata": {}, 183 | "output_type": "execute_result" 184 | } 185 | ], 186 | "source": [ 187 | "Calculator.FV(PV=4321.5, R=0.056, n=10, m=365)" 188 | ] 189 | }, 190 | { 191 | "cell_type": "heading", 192 | "metadata": {}, 193 | "level": 2, 194 | "source": [ 195 | "Present Value" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "You want to have $10.000 USD in 5 years, how much do you need so have right now? (with an annual rate of 3.2%)" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 8, 208 | "metadata": {}, 209 | "outputs": [ 210 | { 211 | "data": { 212 | "text/plain": [ 213 | "8542.825071288185" 214 | ] 215 | }, 216 | "execution_count": 8, 217 | "metadata": {}, 218 | "output_type": "execute_result" 219 | } 220 | ], 221 | "source": [ 222 | "Calculator.PV(FV=10000, n=5, R=0.032)" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "What happens if we compounding is daily?" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 9, 235 | "metadata": {}, 236 | "outputs": [ 237 | { 238 | "data": { 239 | "text/plain": [ 240 | "8521.49765317482" 241 | ] 242 | }, 243 | "execution_count": 9, 244 | "metadata": {}, 245 | "output_type": "execute_result" 246 | } 247 | ], 248 | "source": [ 249 | "Calculator.PV(FV=10000, n=5, R=0.032, m=365)" 250 | ] 251 | }, 252 | { 253 | "cell_type": "heading", 254 | "metadata": {}, 255 | "level": 2, 256 | "source": [ 257 | "Rate/Return" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": {}, 263 | "source": [ 264 | "You have $$1.250 and want to have $2.000 in 10 months what montly rate do you need? (Compounded monthly)" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 10, 270 | "metadata": {}, 271 | "outputs": [ 272 | { 273 | "data": { 274 | "text/plain": [ 275 | "0.04812238946895775" 276 | ] 277 | }, 278 | "execution_count": 10, 279 | "metadata": {}, 280 | "output_type": "execute_result" 281 | } 282 | ], 283 | "source": [ 284 | "Calculator.R(FV=2000, PV=1250, n=10)" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "Testing the previous result" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": 11, 297 | "metadata": {}, 298 | "outputs": [ 299 | { 300 | "data": { 301 | "text/plain": [ 302 | "1999.9544052399096" 303 | ] 304 | }, 305 | "execution_count": 11, 306 | "metadata": {}, 307 | "output_type": "execute_result" 308 | } 309 | ], 310 | "source": [ 311 | "Calculator.FV(PV=1250, n=10, R=0.04812)" 312 | ] 313 | }, 314 | { 315 | "cell_type": "heading", 316 | "metadata": {}, 317 | "level": 2, 318 | "source": [ 319 | "Number of Periods" 320 | ] 321 | }, 322 | { 323 | "cell_type": "markdown", 324 | "metadata": {}, 325 | "source": [ 326 | "Your bank gives you an annual rate of 1.2% and you have $$300. How many years you have to wait to have $500? (compounding monthly)" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 12, 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "42.590082835866575" 338 | ] 339 | }, 340 | "execution_count": 12, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | } 344 | ], 345 | "source": [ 346 | "Calculator.n(R=0.012, PV=300, FV=500, m=12)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "If the compounding is annual" 354 | ] 355 | }, 356 | { 357 | "cell_type": "code", 358 | "execution_count": 13, 359 | "metadata": {}, 360 | "outputs": [ 361 | { 362 | "data": { 363 | "text/plain": [ 364 | "42.82370700861532" 365 | ] 366 | }, 367 | "execution_count": 13, 368 | "metadata": {}, 369 | "output_type": "execute_result" 370 | } 371 | ], 372 | "source": [ 373 | "Calculator.n(R=0.012, PV=300, FV=500)" 374 | ] 375 | }, 376 | { 377 | "cell_type": "heading", 378 | "metadata": {}, 379 | "level": 2, 380 | "source": [ 381 | "Different Rates each period" 382 | ] 383 | }, 384 | { 385 | "cell_type": "markdown", 386 | "metadata": {}, 387 | "source": [ 388 | "What happens if the interest rate changes each period? First year: 1%, then 2%, then 1.5% and finally 0.98%" 389 | ] 390 | }, 391 | { 392 | "cell_type": "markdown", 393 | "metadata": {}, 394 | "source": [ 395 | "This can be done step by step" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 14, 401 | "metadata": {}, 402 | "outputs": [ 403 | { 404 | "data": { 405 | "text/plain": [ 406 | "1055.9003994" 407 | ] 408 | }, 409 | "execution_count": 14, 410 | "metadata": {}, 411 | "output_type": "execute_result" 412 | } 413 | ], 414 | "source": [ 415 | "fv1 = Calculator.FV(PV=1000, R=0.01)\n", 416 | "fv2 = Calculator.FV(PV=fv1, R=0.02)\n", 417 | "fv3 = Calculator.FV(PV=fv2, R=0.015)\n", 418 | "Calculator.FV(PV=fv3, R=0.0098)" 419 | ] 420 | }, 421 | { 422 | "cell_type": "markdown", 423 | "metadata": {}, 424 | "source": [ 425 | "Or more in one steo" 426 | ] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "execution_count": 15, 431 | "metadata": {}, 432 | "outputs": [ 433 | { 434 | "data": { 435 | "text/plain": [ 436 | "1055.9003994" 437 | ] 438 | }, 439 | "execution_count": 15, 440 | "metadata": {}, 441 | "output_type": "execute_result" 442 | } 443 | ], 444 | "source": [ 445 | "Calculator.FV(PV=1000, R=[0.01, 0.02, 0.015, 0.0098])" 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": {}, 451 | "source": [ 452 | "The previous was compounded annually but what if it is compounded monthly?" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": 16, 458 | "metadata": {}, 459 | "outputs": [ 460 | { 461 | "data": { 462 | "text/plain": [ 463 | "1056.2932237984253" 464 | ] 465 | }, 466 | "execution_count": 16, 467 | "metadata": {}, 468 | "output_type": "execute_result" 469 | } 470 | ], 471 | "source": [ 472 | "Calculator.FV(PV=1000, R=[0.01, 0.02, 0.015, 0.0098], m=12)" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 17, 478 | "metadata": {}, 479 | "outputs": [], 480 | "source": [] 481 | }, 482 | { 483 | "cell_type": "code", 484 | "execution_count": 17, 485 | "metadata": {}, 486 | "outputs": [], 487 | "source": [] 488 | }, 489 | { 490 | "cell_type": "code", 491 | "execution_count": 17, 492 | "metadata": {}, 493 | "outputs": [], 494 | "source": [] 495 | }, 496 | { 497 | "cell_type": "code", 498 | "execution_count": 17, 499 | "metadata": {}, 500 | "outputs": [], 501 | "source": [] 502 | }, 503 | { 504 | "cell_type": "code", 505 | "execution_count": 17, 506 | "metadata": {}, 507 | "outputs": [], 508 | "source": [] 509 | }, 510 | { 511 | "cell_type": "code", 512 | "execution_count": null, 513 | "metadata": {}, 514 | "outputs": [], 515 | "source": [] 516 | } 517 | ], 518 | "metadata": { 519 | "name": "FV_PV_R_n" 520 | }, 521 | "nbformat": 4, 522 | "nbformat_minor": 0 523 | } 524 | -------------------------------------------------------------------------------- /examples/Basic/ListUtils.py: -------------------------------------------------------------------------------- 1 | from finance.utils import ListUtils 2 | 3 | sp500_2012 = ListUtils.SP500(year=2012) 4 | print(len(sp500_2012), sp500_2012) 5 | -------------------------------------------------------------------------------- /examples/Basic/MarketSimulator.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | import matplotlib.pyplot as plt 3 | from finance.utils import Calculator 4 | from finance.sim import MarketSimulator 5 | 6 | # from finance.utils import DataAccess 7 | # DataAccess.path = 'data' 8 | 9 | sim = MarketSimulator() 10 | sim.initial_cash = 1000000 11 | sim.load_trades("MarketSimulator_orders.csv") 12 | sim.simulate() 13 | 14 | print(sim.portfolio.tail()) 15 | 16 | print('Total Return:', Calculator.ret(sim.portfolio)) 17 | print('Sharpe Ratio:', Calculator.sharpe_ratio(sim.portfolio)) 18 | 19 | sim.portfolio.plot() 20 | plt.grid(True) 21 | plt.show() -------------------------------------------------------------------------------- /examples/Basic/MarketSimulator_orders.csv: -------------------------------------------------------------------------------- 1 | year,month,day,symbol,action,num_of_shares 2015,1,9,AAPL,Buy,1500 2015,1,13,AAPL,Sell,1500 2015,1,13,IBM,Buy,4000 2015,1,26,GOOG,Buy,1000 2015,2,2,XOM,Sell,4000 2015,2,10,XOM,Buy,4000 2015,3,3,GOOG,Sell,1000 2015,3,3,IBM,Sell,2200 2015,6,3,IBM,Sell,3300 2015,5,4,IBM,Buy,1500 2015,6,10,AAPL,Buy,1200 2015,8,3,GOOG,Buy,55 2015,8,3,GOOG,Sell,55 2015,12,21,AAPL,Sell,1200 -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 1 - Excel/Q&A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/examples/ItCFaFE/Assignment 1 - Excel/Q&A.pdf -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 1 - Excel/Solution.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from datetime import datetime 3 | import matplotlib.pyplot as plt 4 | from finance.utils import DataAccess 5 | from finance.utils import Calculator 6 | 7 | da = DataAccess() 8 | 9 | # Question 1 10 | symbols = ['SBUX'] 11 | start_date = datetime(1993, 3, 31) 12 | end_date = datetime(2008, 3, 31) 13 | fields = 'adjusted_close' 14 | data = da.get_data(symbols, start_date, end_date, fields) 15 | monthly = data.asfreq('M', method='ffill') 16 | 17 | monthly.plot() 18 | plt.title('Montly Data') 19 | plt.draw() 20 | 21 | # Question 2 and 3 22 | total_return = Calculator.ret(data) 23 | q2 = Calculator.FV(PV=10000, R=total_return) 24 | print(2, q2) 25 | 26 | # Question 3 27 | q3 = Calculator.ann_ret(R=total_return, m=1/15) 28 | print(3, q3) 29 | 30 | # Question 4 31 | monthly_ln = monthly.apply(np.log) 32 | monthly_ln.plot() 33 | plt.title('Montly Natural Logarithm') 34 | plt.draw() 35 | 36 | # Question 5 37 | monthly_returns = Calculator.returns(monthly) 38 | monthly_returns.plot() 39 | plt.title('Montly Returns') 40 | plt.draw() 41 | 42 | # Question 7 43 | cc_monthly_returns = Calculator.returns(monthly, cc=True) 44 | cc_monthly_returns.plot() 45 | plt.title('Continuously compounded Montly Returns') 46 | plt.draw() 47 | 48 | # Question 6 49 | annual_returns = Calculator.returns(monthly, basedOn=12) 50 | annual_returns.plot() 51 | plt.title('Annual Returns') 52 | plt.draw() 53 | 54 | # Question 8 55 | cc_annual_returns = Calculator.returns(monthly, basedOn=12, cc=True) 56 | cc_annual_returns.plot() 57 | plt.title('Continuously compounded Annual Returns') 58 | plt.draw() 59 | 60 | # At the end for continous computation 61 | plt.show() 62 | -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 1/Q&A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/examples/ItCFaFE/Assignment 1/Q&A.pdf -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 1/Solution.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from finance.utils import Calculator 3 | 4 | # Create the data 5 | 6 | data = [['December, 2004', 31.18], ['January, 2005', 27.00],['February, 2005', 25.91], 7 | ['March, 2005', 25.83],['April, 2005', 24.76],['May, 2005', 27.40], 8 | ['June, 2005', 25.83],['July, 2005', 26.27],['August, 2005', 24.51], 9 | ['September, 2005', 25.05],['October, 2005', 28.28],['November, 2005', 30.45], 10 | ['December, 2005', 30.51]] 11 | 12 | starbucks = pd.DataFrame(data, columns=['Date', 'Value']).set_index('Date')['Value'] 13 | 14 | ''' 15 | Question 1: Using the data in the table, what is the simple monthly return between the 16 | end of December 2004 and the end of January 2005? 17 | Ans: -13.40% 18 | ''' 19 | q1 = Calculator.ret(starbucks, pos=1) 20 | # q1 = Calculator.R(PV=data[0][1], FV=data[1][1]) # Other option 21 | print(1, q1) 22 | ''' 23 | Question 2: If you invested $10,000 in Starbucks at the end of December 2004, how much 24 | would the investment be worth at the end of January 2005? 25 | Ans: $8659.39 26 | ''' 27 | q2 = Calculator.FV(PV=10000, R=q1) 28 | print(2, q2) 29 | 30 | ''' 31 | Question 3: Using the data in the table, what is the continuously compounded monthly 32 | return between December 2004 and January 2005? 33 | Ans: -14.39% 34 | ''' 35 | q3 = Calculator.ret(starbucks, pos=1, cc=True) 36 | print(3, q3) 37 | 38 | ''' 39 | Question 4: Assuming that the simple monthly return you computed in Question 1 is 40 | the same for 12 months, what is the annual return with monthly compounding? 41 | Ans: -82.22% 42 | ''' 43 | q4 = Calculator.ann_ret(R=q1, m=12) 44 | print(4, q4) 45 | 46 | ''' 47 | Question 5: Assuming that the continuously compounded monthly return you computed 48 | in Question 3 is the same for 12 months, what is the continuously compounded annual return? 49 | Ans: -172.72% 50 | ''' 51 | q5 = Calculator.ann_ret(R=q3, m=12, cc=True) 52 | print(5, q5) 53 | 54 | ''' 55 | Question 6: Using the data in the table, compute the actual simple annual return between 56 | December 2004 and December 2005. 57 | Ans: -2.14% 58 | ''' 59 | q6 = Calculator.ret(starbucks) # pos=-1 is the default 60 | print(6, q6) 61 | 62 | ''' 63 | Question 7: If you invested $10,000 in Starbucks at the end of December 2004, how much 64 | would the investment be worth at the end of December 2005? 65 | Ans: $9785.11 66 | ''' 67 | q7 = Calculator.FV(PV=10000, R=q6) 68 | print(7, q7) 69 | 70 | ''' 71 | Question 8: Using the data in the table, compute the actual annual continuously compounded 72 | return between December 2004 and December 2005. 73 | Ans: -2.17% 74 | ''' 75 | q8 = Calculator.ret(starbucks, cc=True) 76 | print(8, q8) -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 2/Questions: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/examples/ItCFaFE/Assignment 2/Questions -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 2/Solution.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy as np 3 | from scipy import stats 4 | import matplotlib.pyplot as plt 5 | from finance.utils import Calculator 6 | 7 | norm = stats.norm(loc=0.05, scale=0.1) 8 | print(1, 1 - norm.cdf(0.1)) 9 | 10 | print(2, norm.cdf(-0.1)) 11 | 12 | print(3, norm.cdf(0.15) - norm.cdf(-0.05)) 13 | 14 | print(4, norm.ppf(0.01)) 15 | 16 | print(5, norm.ppf(0.05)) 17 | 18 | print(6, norm.ppf(0.95)) 19 | 20 | print(7, norm.ppf(0.99)) 21 | 22 | # Question 8 23 | X_msft = stats.norm(loc=0.05, scale=0.1) 24 | Y_sbux = stats.norm(loc=0.025, scale=0.05) 25 | x = np.linspace(-0.25, 0.35, 100) 26 | 27 | plt.plot(x, X_msft.pdf(x), label='X_msft') 28 | plt.plot(x, Y_sbux.pdf(x), label='Y_sbux') 29 | plt.title('Question 8') 30 | plt.legend() 31 | plt.show() 32 | 33 | # Question 9 34 | W0 = 100000 35 | R = stats.norm(loc=0.04, scale=0.09) 36 | print(9, W0 * R.ppf(0.01), W0 * R.ppf(0.05)) 37 | 38 | # Question 10 39 | W0 = 100000 40 | r = stats.norm(loc=0.04, scale=0.09) 41 | r_1, r_5 = r.ppf(0.01), r.ppf(0.05) 42 | R_1, R_5 = math.exp(r_1) - 1, math.exp(r_5) - 1 43 | print(10, W0 * R_1, W0 * R_5) 44 | 45 | # Question 11 46 | q11_amzn = Calculator.ret([38.23, 41.29]) 47 | # q11_amzn = Calculator.R(PV=38.23, FV=41.29) # Other option 48 | q11_cost = Calculator.ret([41.11, 41.74]) 49 | print(11, q11_amzn, q11_cost) 50 | 51 | # Question 12 52 | q12_amzn = Calculator.ret([38.23, 41.29], cc=True) 53 | q12_cost = Calculator.ret([41.11, 41.74], cc=True) 54 | print(12, q12_amzn, q12_cost) 55 | 56 | # Question 13 57 | q13_amzn = Calculator.ret([38.23, 41.29], dividends=[0, 0.1]) 58 | print(13, q13_amzn, 0.1/41.29) 59 | print(13, (41.29 + 0.1)/38.23 - 1, 0.1/41.29) 60 | 61 | # Question 14 62 | q14_ann_ret = Calculator.ann_ret(R=q12_amzn, m=12) 63 | q14_cc_ann_ret = Calculator.ann_ret(R=q12_amzn, cc=True) 64 | print(14, q14_ann_ret, q14_cc_ann_ret) 65 | 66 | # Question 15 67 | q15_amzn = 8000/10000 68 | q15_cost = 2000/10000 69 | print(15, q15_amzn, q15_cost) 70 | 71 | # Question 16 72 | q16 = q11_amzn * q15_amzn + q11_cost * q15_cost 73 | print(16, q16) 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 3 - Computations/Questions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/examples/ItCFaFE/Assignment 3 - Computations/Questions.pdf -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 3 - Computations/Solution.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy as np 3 | from scipy import stats 4 | 5 | def E(x, prob): 6 | return np.dot(x, prob) 7 | 8 | def VAR(x, prob): 9 | return E( (x - E(x, prob)) * (x - E(x, prob)) , prob) 10 | 11 | x = np.array([1,2,3]) 12 | y = np.array([1,2,3]) 13 | mat = np.array([[0.1, 0.2, 0], [0.1, 0, 0.2], [0, 0.1, 0.3]]) 14 | 15 | # Question 1 16 | x_vals = [x, mat.sum(axis=1)] 17 | X = stats.rv_discrete(values=x_vals) 18 | q1 = X.expect() 19 | print(1, q1) 20 | 21 | # Question 2 22 | y_vals = [y, mat.sum(axis=0)] 23 | Y = stats.rv_discrete(values=y_vals) 24 | q2 = Y.expect() 25 | print(2, q2) 26 | 27 | # Question 3 28 | q3 = X.var() 29 | print(3, q3) 30 | 31 | # Question 4 32 | q4 = Y.var() 33 | print(4, q4) 34 | 35 | # Question 5 36 | q5 = X.std() 37 | print(5, q5) 38 | 39 | # Question 6 40 | q6 = Y.std() 41 | print(6, q6) 42 | 43 | # Question 7 44 | X_Ex = np.zeros(9) 45 | Y_Ey = np.zeros(9) 46 | p_XY = np.zeros(9) 47 | it = 0 48 | for i in range(mat.shape[0]): 49 | for j in range(mat.shape[1]): 50 | X_Ex[it] = x[i] - q1 51 | Y_Ey[it] = y[j] - q2 52 | p_XY[it] = mat[i,j] 53 | it = it + 1 54 | q7 = (X_Ex * Y_Ey * p_XY).sum() 55 | print(7, q7) 56 | 57 | # Question 8 58 | q8 = q7 / (q5 * q6) 59 | print(8, q8) 60 | 61 | # Question 9 62 | q9 = y_vals[1][0] == mat[0,0] # One test is enough: P(X=0) != P(X=0|Y=0) 63 | print(9, q9) 64 | 65 | # Question 10 66 | W0 = 100000 67 | r = stats.norm(loc=12*0.04, scale=math.sqrt(12) * 0.09) 68 | r_1, r_5 = r.ppf(0.01), r.ppf(0.05) 69 | R_1, R_5 = math.exp(r_1) - 1, math.exp(r_5) - 1 70 | print(10, W0 * R_1, W0 * R_5) 71 | 72 | 73 | -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 4 - Matrix Algebra/Questions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/examples/ItCFaFE/Assignment 4 - Matrix Algebra/Questions.pdf -------------------------------------------------------------------------------- /examples/ItCFaFE/Assignment 4 - Matrix Algebra/Solution.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy as np 3 | from scipy import stats 4 | 5 | A = np.array([[1,4,7], [2,4,8], [6,1,3]]) 6 | B = np.array([[4,4,0], [5,9,1], [2,2,5]]) 7 | x = np.array([1,2,3]) 8 | y = np.array([5,2,7]) 9 | 10 | # Question 1 11 | print(1, A.T) 12 | 13 | # Question 2 14 | print(2, B.T) 15 | 16 | # Question 3 17 | print(3, x.T) 18 | 19 | # Question 4 20 | print(4, y.T) 21 | 22 | # Question 5 23 | print(5, A+B) 24 | 25 | # Question 6 26 | print(6, A-B) 27 | 28 | # Question 7 29 | print(7, 2*A) 30 | 31 | # Question 8 32 | print(8, np.dot(A,x)) 33 | 34 | # Question 9 35 | print(9, np.dot(y,np.dot(A,x))) 36 | 37 | # Question 10 38 | A2 = np.array([[1,1], [2,4]]) 39 | x2 = np.array([1,2]) 40 | print(10, np.linalg.solve(A2, x2)) 41 | 42 | # Question 11 43 | x = [1/3,1/3,1/3] 44 | u = np.array([0.01,0.04,0.02]) 45 | print(11, (x*u).sum()) 46 | 47 | # Question 12 48 | V = np.array([[0.1, 0.3, 0.1], [0.3,0.15,-0.2],[0.1,-0.2,0.08]]) 49 | print(12, np.dot(x,np.dot(V,x))) 50 | 51 | 52 | -------------------------------------------------------------------------------- /examples/ItCFaFE/README.md: -------------------------------------------------------------------------------- 1 | Introduction to Computational Finance and Financial Econometrics 2 | ---------------------------------------------------------------- 3 | 4 | This are the assignments from the Coursera course "Introduction to Computational Finance and Financial Econometrics". The course uses R and this are the python ported solution to the assignments. -------------------------------------------------------------------------------- /finance.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "build_systems": 4 | [ 5 | { 6 | "name": "Python Virtual env", 7 | "env": 8 | { 9 | "PYTHONPATH":"/home/dfrodriguez/projects/packages/", 10 | "FINANCEPATH":"/home/dfrodriguez/projects/packages/finance/data" 11 | }, 12 | "cmd": ["/home/dfrodriguez/.virtualenvs/finance/bin/python", "-u", "$file"] 13 | } 14 | ], 15 | "folders": 16 | [ 17 | { 18 | "path": "/home/dfrodriguez/projects/packages/finance", 19 | "folder_exclude_patterns": ["__pycache__"] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /finance.sublime-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "auto_complete": 3 | { 4 | "selected_items": 5 | [ 6 | [ 7 | "it", 8 | "it" 9 | ], 10 | [ 11 | "p", 12 | "p_XY" 13 | ], 14 | [ 15 | "Y", 16 | "Y_Ey" 17 | ], 18 | [ 19 | "E", 20 | "X_Ex" 21 | ], 22 | [ 23 | "X", 24 | "X_Ex" 25 | ], 26 | [ 27 | "x", 28 | "x" 29 | ], 30 | [ 31 | "q15", 32 | "q15_cost" 33 | ], 34 | [ 35 | "q11_", 36 | "q11_cost" 37 | ], 38 | [ 39 | "q", 40 | "q15_amzn" 41 | ], 42 | [ 43 | "q12_", 44 | "q12_amzn" 45 | ], 46 | [ 47 | "err", 48 | "errorfill" 49 | ], 50 | [ 51 | "y_", 52 | "y_cos" 53 | ], 54 | [ 55 | "order", 56 | "orders" 57 | ], 58 | [ 59 | "test", 60 | "testName" 61 | ], 62 | [ 63 | "np", 64 | "np_test" 65 | ], 66 | [ 67 | "Mul", 68 | "MultipleEventTest" 69 | ], 70 | [ 71 | "returns", 72 | "returns" 73 | ], 74 | [ 75 | "asse", 76 | "assertEqual" 77 | ], 78 | [ 79 | "Da", 80 | "DataFrame" 81 | ], 82 | [ 83 | "data", 84 | "data_access" 85 | ], 86 | [ 87 | "sel", 88 | "self_dir" 89 | ], 90 | [ 91 | "da", 92 | "data_access" 93 | ], 94 | [ 95 | "em", 96 | "empty_dir" 97 | ], 98 | [ 99 | "tes", 100 | "testName" 101 | ], 102 | [ 103 | "de", 104 | "decrease" 105 | ], 106 | [ 107 | "asser", 108 | "assertFrameEqual" 109 | ], 110 | [ 111 | "ass", 112 | "assertArray" 113 | ], 114 | [ 115 | "as", 116 | "assertArrayEqual" 117 | ], 118 | [ 119 | "d1", 120 | "d1_array2" 121 | ], 122 | [ 123 | "an", 124 | "ans" 125 | ], 126 | [ 127 | "re", 128 | "ret_list" 129 | ], 130 | [ 131 | "ret", 132 | "ret_list" 133 | ], 134 | [ 135 | "sim", 136 | "simple_returns" 137 | ], 138 | [ 139 | "t", 140 | "t" 141 | ], 142 | [ 143 | "pd", 144 | "pd_test" 145 | ], 146 | [ 147 | "get", 148 | "getenv" 149 | ], 150 | [ 151 | "col", 152 | "column" 153 | ], 154 | [ 155 | "to", 156 | "today" 157 | ], 158 | [ 159 | "con", 160 | "continuouslyCompounded" 161 | ], 162 | [ 163 | "n", 164 | "n" 165 | ], 166 | [ 167 | "emp", 168 | "empty_dirs" 169 | ], 170 | [ 171 | "en", 172 | "environ" 173 | ], 174 | [ 175 | "sym", 176 | "symbols" 177 | ], 178 | [ 179 | "loo", 180 | "lookforward_days" 181 | ], 182 | [ 183 | "sy", 184 | "symbol_s" 185 | ], 186 | [ 187 | "symbo", 188 | "symbol" 189 | ], 190 | [ 191 | "Data", 192 | "DataAccess" 193 | ], 194 | [ 195 | "past", 196 | "pastEvent" 197 | ], 198 | [ 199 | "d2_", 200 | "d1_array_2_dr" 201 | ], 202 | [ 203 | "port", 204 | "Portfolio" 205 | ], 206 | [ 207 | "colu", 208 | "column" 209 | ], 210 | [ 211 | "pr", 212 | "prices" 213 | ], 214 | [ 215 | "afte", 216 | "after_date" 217 | ], 218 | [ 219 | "days", 220 | "daysAfter" 221 | ], 222 | [ 223 | "idx", 224 | "idx" 225 | ], 226 | [ 227 | "event", 228 | "eventList" 229 | ], 230 | [ 231 | "act", 232 | "actionAfter" 233 | ], 234 | [ 235 | "fil", 236 | "field" 237 | ], 238 | [ 239 | "mar", 240 | "market" 241 | ], 242 | [ 243 | "ev", 244 | "evt_idx2" 245 | ], 246 | [ 247 | "evt", 248 | "evt_idx" 249 | ], 250 | [ 251 | "evt_", 252 | "evt_date" 253 | ], 254 | [ 255 | "end", 256 | "end_date" 257 | ], 258 | [ 259 | "star", 260 | "start" 261 | ], 262 | [ 263 | "fill", 264 | "fillna" 265 | ], 266 | [ 267 | "ex", 268 | "expected_return" 269 | ], 270 | [ 271 | "dr_market", 272 | "dr_market_window" 273 | ], 274 | [ 275 | "equi", 276 | "equities_window" 277 | ], 278 | [ 279 | "cus", 280 | "customDates" 281 | ], 282 | [ 283 | "NYSE", 284 | "NYSE_dates" 285 | ], 286 | [ 287 | "nt", 288 | "nyse_dates" 289 | ], 290 | [ 291 | "look", 292 | "lookforwardDays" 293 | ], 294 | [ 295 | "id", 296 | "idx_start_date" 297 | ], 298 | [ 299 | "date", 300 | "datetime" 301 | ], 302 | [ 303 | "all", 304 | "all_dates" 305 | ], 306 | [ 307 | "get_", 308 | "get_idx_date" 309 | ], 310 | [ 311 | "arr", 312 | "array" 313 | ], 314 | [ 315 | "ab", 316 | "abnormal_return" 317 | ], 318 | [ 319 | "dr_", 320 | "dr_data_window" 321 | ], 322 | [ 323 | "slo", 324 | "slope_std_error" 325 | ], 326 | [ 327 | "reg", 328 | "reg_estimation" 329 | ], 330 | [ 331 | "dr", 332 | "dr_market_estimation" 333 | ], 334 | [ 335 | "dail", 336 | "daily_returns" 337 | ], 338 | [ 339 | "e", 340 | "end_date" 341 | ], 342 | [ 343 | "return", 344 | "return" 345 | ], 346 | [ 347 | "lo", 348 | "lookback_days" 349 | ], 350 | [ 351 | "Mar", 352 | "MarketSimulatorTest" 353 | ], 354 | [ 355 | "BasicUtils", 356 | "BasicUtilsTest" 357 | ], 358 | [ 359 | "sta", 360 | "start_window" 361 | ], 362 | [ 363 | "sat", 364 | "start_period" 365 | ], 366 | [ 367 | "for", 368 | "forward_days" 369 | ], 370 | [ 371 | "ar", 372 | "ar" 373 | ], 374 | [ 375 | "excep", 376 | "exception" 377 | ], 378 | [ 379 | "estimi", 380 | "estimation_period" 381 | ], 382 | [ 383 | "es", 384 | "estimation_period" 385 | ], 386 | [ 387 | "st", 388 | "std_error" 389 | ], 390 | [ 391 | "set", 392 | "setUp1" 393 | ], 394 | [ 395 | "shar", 396 | "sharpe" 397 | ], 398 | [ 399 | "load", 400 | "load_trades" 401 | ], 402 | [ 403 | "por", 404 | "portfolio" 405 | ], 406 | [ 407 | "valu", 408 | "value_equities" 409 | ], 410 | [ 411 | "num", 412 | "num_of_shares" 413 | ], 414 | [ 415 | "ow", 416 | "own_each_stock" 417 | ], 418 | [ 419 | "cas", 420 | "cash_change" 421 | ], 422 | [ 423 | "init", 424 | "initial_cash" 425 | ], 426 | [ 427 | "fir", 428 | "first_row" 429 | ], 430 | [ 431 | "clo", 432 | "close_loaded" 433 | ], 434 | [ 435 | "ca", 436 | "cache_dir" 437 | ], 438 | [ 439 | "fiel", 440 | "field" 441 | ], 442 | [ 443 | "down", 444 | "downloadMissing" 445 | ], 446 | [ 447 | "symbol_s", 448 | "symbol_s" 449 | ], 450 | [ 451 | "start", 452 | "start_date" 453 | ], 454 | [ 455 | "dow", 456 | "downloadMissing" 457 | ], 458 | [ 459 | "do", 460 | "downloadMissing" 461 | ], 462 | [ 463 | "fi", 464 | "field_s" 465 | ], 466 | [ 467 | "field", 468 | "field_s" 469 | ], 470 | [ 471 | "dir", 472 | "dir_path" 473 | ], 474 | [ 475 | "exis", 476 | "exists_single" 477 | ], 478 | [ 479 | "exi", 480 | "exists_single" 481 | ], 482 | [ 483 | "stock", 484 | "stock_file" 485 | ], 486 | [ 487 | "ya", 488 | "yahoo_pull_single" 489 | ], 490 | [ 491 | "tur", 492 | "turn_it" 493 | ], 494 | [ 495 | "turn", 496 | "turn_stdout" 497 | ], 498 | [ 499 | "s", 500 | "start_date" 501 | ], 502 | [ 503 | "eve", 504 | "eventMatrix" 505 | ], 506 | [ 507 | "m", 508 | "m" 509 | ], 510 | [ 511 | "wi", 512 | "weight" 513 | ], 514 | [ 515 | "perce", 516 | "Percentage" 517 | ] 518 | ] 519 | }, 520 | "buffers": 521 | [ 522 | ], 523 | "build_system": "Python Virtual env", 524 | "command_palette": 525 | { 526 | "height": 217.0, 527 | "selected_items": 528 | [ 529 | [ 530 | "conver", 531 | "Indentation: Convert to Spaces" 532 | ], 533 | [ 534 | "install", 535 | "Package Control: Install Package" 536 | ], 537 | [ 538 | "packa", 539 | "Package Control: Remove Package" 540 | ], 541 | [ 542 | "disable", 543 | "Package Control: Disable Package" 544 | ], 545 | [ 546 | "enable", 547 | "Package Control: Enable Package" 548 | ], 549 | [ 550 | "remove", 551 | "Package Control: Remove Package" 552 | ], 553 | [ 554 | "CONVER", 555 | "Indentation: Convert to Tabs" 556 | ], 557 | [ 558 | "python", 559 | "Set Syntax: Python" 560 | ], 561 | [ 562 | "package", 563 | "Package Control: List Packages" 564 | ], 565 | [ 566 | "packagre", 567 | "Package Control: Discover Packages" 568 | ], 569 | [ 570 | "disa", 571 | "Package Control: Disable Package" 572 | ], 573 | [ 574 | "disabl", 575 | "Package Control: Disable Package" 576 | ], 577 | [ 578 | "pac", 579 | "Package Control: Enable Package" 580 | ], 581 | [ 582 | "insta", 583 | "Package Control: Install Package" 584 | ], 585 | [ 586 | "instal", 587 | "Package Control: Install Package" 588 | ] 589 | ], 590 | "width": 435.0 591 | }, 592 | "console": 593 | { 594 | "height": 155.0 595 | }, 596 | "distraction_free": 597 | { 598 | "menu_visible": true, 599 | "show_minimap": false, 600 | "show_open_files": false, 601 | "show_tabs": false, 602 | "side_bar_visible": false, 603 | "status_bar_visible": false 604 | }, 605 | "file_history": 606 | [ 607 | "/home/dfrodriguez/projects/packages/finance/finance.sublime-workspace", 608 | "/home/dfrodriguez/projects/packages/finance/finance.sublime-project", 609 | "/home/dfrodriguez/projects/packages/finance/examples/ItCFaFE/Assignment 3 - Computations/Solution.py", 610 | "/home/dfrodriguez/projects/packages/finance/examples/ItCFaFE/README.md", 611 | "/home/dfrodriguez/projects/packages/finance/examples/Combining/Example 5/Solution.py", 612 | "/home/dfrodriguez/projects/packages/finance/examples/Combining/Example 3/Solution.py", 613 | "/home/dfrodriguez/projects/packages/finance/examples/Basic/EventStudy_Multiple.py", 614 | "/home/dfrodriguez/.virtualenvs/finance/lib/python3.2/site-packages/matplotlib/mpl-data/matplotlibrc", 615 | "//usr/lib/python3.2/tkinter/__init__.py", 616 | "/home/dfrodriguez/.virtualenvs/finance/lib/python3.2/site-packages/matplotlib/backends/tkagg.py", 617 | "/home/dfrodriguez/.config/sublime-text-2/Packages/Python/Python.sublime-build", 618 | "/home/dfrodriguez/.virtualenvs/finance/bin/activate", 619 | "/home/dfrodriguez/.bashrc", 620 | "/home/dfrodriguez/Documents/packages/finance/utils/Calculator.py", 621 | "/home/dfrodriguez/Documents/packages/finance/examples/Combining/Example 3/Solution.py", 622 | "/home/dfrodriguez/Documents/packages/finance/examples/Combining/Example 3/solution.py", 623 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/EventStudy_Multiple.py", 624 | "/home/dfrodriguez/Documents/packages/finance/README.md", 625 | "/home/dfrodriguez/Documents/packages/finance/CHANGELOG.md", 626 | "/etc/fonts/conf.d/90-fonts-nanum.conf", 627 | "/etc/fonts/conf.d/65-droid-sans-fonts.conf", 628 | "/home/dfrodriguez/Documents/packages/finance/plots/errorfill.py", 629 | "/home/dfrodriguez/Documents/packages/finance/events/MultipleEvents.py", 630 | "/home/dfrodriguez/Documents/packages/finance/plots/__init__.py", 631 | "/home/dfrodriguez/.matplotlib/matplotlibrc", 632 | "/home/dfrodriguez/Documents/packages/finance/test/AllTets.py", 633 | "/home/dfrodriguez/Documents/packages/finance/test/events/EventFinder.py", 634 | "/home/dfrodriguez/Documents/packages/finance/test/events/MultipleEvents.py", 635 | "/home/dfrodriguez/Documents/packages/finance/events/EventFinder.py", 636 | "/home/dfrodriguez/Documents/packages/finance/events/Condition.py", 637 | "/home/dfrodriguez/Documents/packages/finance/events/SampleConditions.py", 638 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/EventStudy_Finder.py", 639 | "/home/dfrodriguez/Documents/packages/finance/utils/FileManager.py", 640 | "/home/dfrodriguez/Documents/packages/finance/utils/DataAccess.py", 641 | "/home/dfrodriguez/Documents/packages/finance/examples/Combining/Example 2/Solution.py", 642 | "/home/dfrodriguez/Documents/packages/finance/examples/Combining/Example 1/Solution.py", 643 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/ListUtils.py", 644 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/EventStudy_Past.py", 645 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/MarketSimulator.py", 646 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/DateUtils.py", 647 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/DataAccess.py", 648 | "/home/dfrodriguez/Documents/packages/finance/test/sim/MarketSimulator.py", 649 | "/home/dfrodriguez/Documents/packages/finance/test/events/PastEvent.py", 650 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorValues.py", 651 | "/home/dfrodriguez/Documents/packages/finance/test/FinanceTest.py", 652 | "/home/dfrodriguez/Documents/packages/finance/test/utils/DataAccess.py", 653 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorTypes.py", 654 | "/home/dfrodriguez/Documents/packages/finance/test/utils/FileManager.py", 655 | "/home/dfrodriguez/Documents/packages/finance/test/events/__init__.py", 656 | "/home/dfrodriguez/Documents/packages/finance/.gitignore", 657 | "/home/dfrodriguez/Documents/packages/finance/test/events/PastEventTest.py", 658 | "/home/dfrodriguez/Documents/packages/finance/test/events/MultipleEventTest.py", 659 | "/home/dfrodriguez/Documents/packages/finance/events/PastEvent.py", 660 | "/home/dfrodriguez/Documents/packages/finance/events/EventStudy.py", 661 | "/home/dfrodriguez/Documents/packages/finance/test/events/docs/PastEvent_window_1.csv", 662 | "/home/dfrodriguez/Documents/packages/finance/test/events/EventFinderTest.py", 663 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorValuesTest.py", 664 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorTypesTest.py", 665 | "/home/dfrodriguez/Documents/packages/finance/sim/MarketSimulator.py", 666 | "/home/dfrodriguez/Documents/packages/finance/test/sim/MarketSimulatorTest.py", 667 | "/home/dfrodriguez/Documents/packages/finance/test/sim/docs/Test1.csv", 668 | "/home/dfrodriguez/Documents/packages/finance/utils/ListUtils.py", 669 | "/home/dfrodriguez/Documents/packages/finance/test/utils/DataAccessTest.py", 670 | "/home/dfrodriguez/Documents/packages/finance/test/utils/FileManagerTest.py", 671 | "/home/dfrodriguez/Documents/packages/finance/test/utils/DateUtilsTest.py", 672 | "/home/dfrodriguez/Documents/packages/finance/events/SampleEvents.py", 673 | "/home/dfrodriguez/Documents/packages/finance/events/Event.py", 674 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorTest_TVM_3.csv", 675 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorTest_TVM_2.csv", 676 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorTest_TVM.csv", 677 | "/home/dfrodriguez/Documents/packages/finance/test/utils/CalculatorTest.py", 678 | "/home/dfrodriguez/Documents/packages/finance/finance.sublime-project", 679 | "/home/dfrodriguez/Documents/packages/finance/utils/test/CalculatorTypesTest.py", 680 | "/home/dfrodriguez/Documents/packages/finance/test/__init__.py", 681 | "/home/dfrodriguez/Documents/packages/finance/utils/test/CalculatorValuesTest.py", 682 | "/home/dfrodriguez/Documents/packages/finance/utils/test/CalculatorTest1.csv", 683 | "/home/dfrodriguez/Documents/packages/finance/utils/test/CalculatorTest.py", 684 | "/home/dfrodriguez/Documents/packages/finance/sim/test/MarketSimulatorTest.py", 685 | "/home/dfrodriguez/Dropbox/Documents/Coursera/Intro to Computational Finance/Week 1/returnCalculations.csv", 686 | "/home/dfrodriguez/Documents/QSTK-master/qstkutil/tsutil.py", 687 | "/home/dfrodriguez/Documents/QSTK-master/Examples/EventProfiler/SP500port.csv", 688 | "/home/dfrodriguez/Documents/QSTK-master/Tools/investors_report.py", 689 | "/home/dfrodriguez/Documents/QSTK-master/Tools/Data_CSV.py", 690 | "/home/dfrodriguez/Documents/QSTK-master/qstkstrat/strategies.py", 691 | "/home/dfrodriguez/Documents/QSTK-master/qstkutil/DataEvolved.py", 692 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/Calculator_FV.py", 693 | "/home/dfrodriguez/Documents/packages/finance/examples/Basic/Calculator_FV_PV_R_n.py", 694 | "/home/dfrodriguez/Documents/packages/finance/examples/Example 2/Solution.py", 695 | "/home/dfrodriguez/Documents/QSTK-master/qstkutil/qsdateutil.py", 696 | "/home/dfrodriguez/Documents/QSTK-master/qstkutil/utils.py", 697 | "/home/dfrodriguez/Documents/QSTK-master/qstkutil/fundutil.py", 698 | "/home/dfrodriguez/Documents/packages/finance/examples/DataManagement.py", 699 | "/home/dfrodriguez/Documents/packages/finance/examples/Calculator/Solution.py", 700 | "/home/dfrodriguez/Documents/packages/finance/examples/MarketSimulator.py", 701 | "/home/dfrodriguez/Documents/packages/finance/utils/test/FileManagerTest.py", 702 | "/home/dfrodriguez/Documents/packages/finance/utils/test/DataAccessTest.py", 703 | "/home/dfrodriguez/Documents/packages/finance/utils/DateUtils.py", 704 | "/home/dfrodriguez/Documents/packages/finance/utils/test/DateUtilsTest.py", 705 | "/home/dfrodriguez/Documents/packages/finance/events/test/MultipleEventTest.py", 706 | "/home/dfrodriguez/Documents/packages/finance/events/test/EventFinderTest.py", 707 | "/home/dfrodriguez/Documents/packages/finance/events/test/PastEventTest.py", 708 | "/home/dfrodriguez/Documents/packages/finance/examples/Calculator/Example1.py", 709 | "/home/dfrodriguez/Dropbox/Documents/UTD/Bussiness Intelligence/Project - Term/data/training_clean2.csv", 710 | "/home/dfrodriguez/Documents/packages/finance/examples/EventStudy_Finder.py", 711 | "/home/dfrodriguez/Documents/packages/finance/examples/EventStudy_Multiple.py", 712 | "/home/dfrodriguez/Documents/packages/finance/examples/EventStudy_Past.py", 713 | "/home/dfrodriguez/Documents/packages/finance/examples/DateUtils.py", 714 | "/home/dfrodriguez/Documents/packages/finance/utils/test/BasicUtilsTest.py", 715 | "/home/dfrodriguez/Documents/packages/finance/utils/BasicUtils.py", 716 | "/home/dfrodriguez/Documents/packages/finance/examples/ListUtils.py", 717 | "/home/dfrodriguez/Documents/packages/finance/events/__init__.py", 718 | "/home/dfrodriguez/Documents/packages/finance/events/SimpleEvent.py", 719 | "/home/dfrodriguez/Documents/packages/finance/evtstudy/EventFinder.py", 720 | "/home/dfrodriguez/Documents/packages/finance/utils/lists/NYSE_dates.txt", 721 | "/home/dfrodriguez/Documents/packages/finance/utils/lists/NYSE_dates.py", 722 | "/home/dfrodriguez/Documents/packages/finance/utils/lists/__init__.py", 723 | "/home/dfrodriguez/Documents/packages/finance/evtstudy/MultipleEvents.py", 724 | "/home/dfrodriguez/Documents/packages/finance/examples/MultipleEvents/data/SUN_2009-12-10_2012-1-19.csv", 725 | "/home/dfrodriguez/Documents/packages/finance/utils/SP500_2012.py", 726 | "/home/dfrodriguez/Documents/packages/finance/examples/MultipleEvents/data/SPY_2009-12-17_2012-1-19.csv", 727 | "/home/dfrodriguez/Documents/packages/finance/examples/MultipleEvents/data/FTR_2011-1-1_2011-12-31.csv", 728 | "/home/dfrodriguez/Documents/packages/finance/examples/MultipleEvents/data/FTR_2009-12-17_2012-1-19.csv", 729 | "/home/dfrodriguez/Documents/packages/finance/evtstudy/test/MultipleEventTest.py", 730 | "/home/dfrodriguez/Documents/packages/finance/evtstudy/test/MultipleEventTest.ods", 731 | "/home/dfrodriguez/Documents/packages/finance/utils/SP500_2008.py", 732 | "/home/dfrodriguez/Documents/packages/finance/evtstudy/test/EventFinderTest.py", 733 | "/home/dfrodriguez/Documents/packages/finance/examples/EventFinder.py", 734 | "/home/dfrodriguez/Documents/packages/finance/evtstudy/SimpleEvent.py" 735 | ], 736 | "find": 737 | { 738 | "height": 34.0 739 | }, 740 | "find_in_files": 741 | { 742 | "height": 0.0, 743 | "where_history": 744 | [ 745 | ] 746 | }, 747 | "find_state": 748 | { 749 | "case_sensitive": false, 750 | "find_history": 751 | [ 752 | "X_Ex", 753 | "var", 754 | "ev", 755 | "amzn", 756 | "cost", 757 | "test", 758 | "나눔고딕", 759 | "7", 760 | "SampleEvents", 761 | "event", 762 | "self.event", 763 | ".total_return", 764 | "total_return", 765 | "pevt", 766 | "MultipleEventTest", 767 | "utils", 768 | "CalculatorTestValues", 769 | "cumulative_ar", 770 | "abnormal_return", 771 | "expected_return", 772 | "elf.evt", 773 | "std_abnormal_return", 774 | "mean_abnormal_return", 775 | "std_expected_return", 776 | "mean_expected_return", 777 | "expected_returns", 778 | "abnormal_returns", 779 | "cumulative_abnormal_returns", 780 | "mean_cumulative_abnormal_return", 781 | "assert_almost_equal", 782 | "assert_equal", 783 | "np_test", 784 | "mevt", 785 | "self.mevt", 786 | "self.evtf", 787 | "self.setUp", 788 | "assertFrameEqual", 789 | "assertSeriesEqual", 790 | "assertArrayEqual", 791 | "assertSeriesEqual", 792 | "self.sim", 793 | "assert_frame_equal", 794 | "pd_test", 795 | "nyse_add_substract", 796 | "self", 797 | "funcion_name", 798 | "test_time_value_of_money", 799 | "assert_series_equal", 800 | "pd_test", 801 | "CalculatorValues", 802 | "np_test", 803 | "> Returns", 804 | "Returns", 805 | "assert_frame_equal", 806 | "pd_test", 807 | "matrix_dr", 808 | "array_2_dr", 809 | "assertEquals", 810 | "d2_array", 811 | "array2", 812 | "d1_array", 813 | "CalculatorTypes", 814 | "BasicUtilsTest", 815 | "d1_array_1_dr", 816 | "total_return", 817 | "test_pv_fv_R_effret_with_m", 818 | "solution", 819 | "test_pv_fv_R_eff_ret_with_m", 820 | "ear", 821 | "grid", 822 | "plt.grid(True)", 823 | "grid", 824 | "backend", 825 | "rate", 826 | "inf", 827 | "daily_returns", 828 | "daily", 829 | "BasicUtils", 830 | "Questio", 831 | "(10) ", 832 | "continuouslyCompounded", 833 | "ans = Calculator.FV(PV=1000, R=0.03, n=1)\n self.assertEquals(1030, ans)\n ans = Calculator.FV(PV=1000, R=0.03, n=5)\n self.assertAlmostEquals(1159.27, ans, 2)\n ans = Calculator.FV(PV=1000, R=0.03, n=10)\n self.assertAlmostEquals(1343.92, ans, 2)", 834 | "BasicUtils.", 835 | "BasicUtils", 836 | "self.fm", 837 | "self.da", 838 | "self.da.", 839 | "da", 840 | "self.da ", 841 | "self.da", 842 | "self.current_cash", 843 | "current_stocks", 844 | "self.own", 845 | "self.da", 846 | "da", 847 | "field_s", 848 | "symbol_s", 849 | "n_data", 850 | "end_date", 851 | "start_date", 852 | "get_data", 853 | "import", 854 | "list", 855 | "0.9175", 856 | "sr", 857 | "d,", 858 | "d", 859 | "tr", 860 | "equities", 861 | "print", 862 | "Adj", 863 | ")\n", 864 | "))\n", 865 | "columns", 866 | "CFN", 867 | "bwa", 868 | "self.car", 869 | "self.ar", 870 | "er", 871 | "print", 872 | "mevt", 873 | "evtf", 874 | "delete", 875 | "values", 876 | "53", 877 | "]]\n", 878 | "data_estimation", 879 | "data_window" 880 | ], 881 | "highlight": true, 882 | "in_selection": false, 883 | "preserve_case": false, 884 | "regex": false, 885 | "replace_history": 886 | [ 887 | ], 888 | "reverse": false, 889 | "show_context": true, 890 | "use_buffer2": true, 891 | "whole_word": false, 892 | "wrap": true 893 | }, 894 | "groups": 895 | [ 896 | { 897 | "sheets": 898 | [ 899 | ] 900 | } 901 | ], 902 | "incremental_find": 903 | { 904 | "height": 37.0 905 | }, 906 | "input": 907 | { 908 | "height": 37.0 909 | }, 910 | "layout": 911 | { 912 | "cells": 913 | [ 914 | [ 915 | 0, 916 | 0, 917 | 1, 918 | 1 919 | ] 920 | ], 921 | "cols": 922 | [ 923 | 0.0, 924 | 1.0 925 | ], 926 | "rows": 927 | [ 928 | 0.0, 929 | 1.0 930 | ] 931 | }, 932 | "menu_visible": true, 933 | "output.exec": 934 | { 935 | "height": 154.0 936 | }, 937 | "replace": 938 | { 939 | "height": 0.0 940 | }, 941 | "save_all_on_build": true, 942 | "select_file": 943 | { 944 | "height": 0.0, 945 | "selected_items": 946 | [ 947 | [ 948 | "sun", 949 | "examples/MultipleEvents/data/SUN_2009-12-10_2012-1-19.csv" 950 | ], 951 | [ 952 | "amd", 953 | "finance/evtstudy/data/AMD_2007-10-5_2010-1-15.csv" 954 | ], 955 | [ 956 | "oke", 957 | "assignment1/data/OKE.csv" 958 | ], 959 | [ 960 | "cmd", 961 | "assignment1/data/CMD.csv" 962 | ], 963 | [ 964 | "isr", 965 | "assignment1/data/ISRG.csv" 966 | ], 967 | [ 968 | "ep", 969 | "assignment1/data/EP.csv" 970 | ], 971 | [ 972 | "isrg", 973 | "assignment1/data/ISRG.csv" 974 | ] 975 | ], 976 | "width": 0.0 977 | }, 978 | "select_project": 979 | { 980 | "height": 500.0, 981 | "selected_items": 982 | [ 983 | ], 984 | "width": 380.0 985 | }, 986 | "show_minimap": true, 987 | "show_open_files": false, 988 | "show_tabs": true, 989 | "side_bar_visible": true, 990 | "side_bar_width": 220.0, 991 | "status_bar_visible": true 992 | } 993 | -------------------------------------------------------------------------------- /plots/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/plots/__init__.py -------------------------------------------------------------------------------- /plots/errorfill.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | 4 | # __all__ = ['errorfill'] 5 | 6 | ''' 7 | Heavily based on the errorfill from mpltools: 8 | Updated to python 3 9 | https://github.com/tonysyu/mpltools 10 | ''' 11 | 12 | def errorfill(x, y, yerr=None, xerr=None, color=None, ls=None, lw=None, 13 | alpha=1, alpha_fill=0.3, label='', label_fill='', ax=None): 14 | '''Plot data with errors marked by a filled region. 15 | 16 | Parameters 17 | ---------- 18 | x, y : arrays 19 | Coordinates of data. 20 | yerr, xerr: [scalar | N, (N, 1), or (2, N) array] 21 | Error for the input data. 22 | - If scalar, then filled region spans `y +/- yerr` or `x +/- xerr`. 23 | color : Matplotlib color 24 | Color of line and fill region. 25 | ls : Matplotlib line style 26 | Style of the line 27 | lw : Matplotlib line width, float value in points 28 | Width of the line 29 | alpha : float 30 | Opacity used for plotting. 31 | alpha_fill : float 32 | Opacity of filled region. Note: the actual opacity of the fill is 33 | `alpha * alpha_fill`. 34 | label : str 35 | Label for line. 36 | label_fill : str 37 | Label for filled region. 38 | ax : Axis instance 39 | The plot is drawn on axis `ax`. If `None` the current axis is used 40 | ''' 41 | ax = ax if ax is not None else plt.gca() 42 | 43 | alpha_fill *= alpha 44 | 45 | if color is None: 46 | color = next(ax._get_lines.prop_cycler)['color'] 47 | if ls is None: 48 | ls = plt.rcParams['lines.linestyle'] 49 | if lw is None: 50 | lw = plt.rcParams['lines.linewidth'] 51 | 52 | # Regular plot 53 | ax.plot(x, y, color, linestyle=ls, linewidth=lw, alpha=alpha, label=label) 54 | 55 | # Fill 56 | kwargs_fill = dict(color=color, alpha=alpha_fill, label=label_fill) 57 | 58 | if yerr is not None: 59 | z, zerr = y, yerr 60 | elif xerr is not None: 61 | z, zerr = x, xerr 62 | 63 | if np.isscalar(zerr) or len(zerr) == len(z): 64 | zmin = z - zerr 65 | zmax = z + zerr 66 | elif len(zerr) == 2: 67 | zmin, zmax = z - zerr[0], z + zerr[1] 68 | 69 | if yerr is not None: 70 | ax.fill_between(x, zmax, zmin, **kwargs_fill) 71 | elif xerr is not None: 72 | ax.fill_betweenx(z, zmax, zmin, **kwargs_fill) 73 | 74 | ax.add_patch(plt.Rectangle((0, 0), 0, 0, **kwargs_fill)) 75 | 76 | if __name__ == '__main__': 77 | x = np.linspace(0, 2 * np.pi) 78 | y_sin = np.sin(x) 79 | y_cos = np.cos(x) 80 | 81 | errorfill(x, y_sin, 0.2) 82 | errorfill(x, y_cos, 0.2) 83 | plt.legend() 84 | 85 | plt.show() -------------------------------------------------------------------------------- /sim/MarketSimulator.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | from datetime import datetime 4 | from finance.utils import DataAccess 5 | from finance.utils import DateUtils 6 | 7 | class MarketSimulator(object): 8 | ''' 9 | Market Simulator 10 | 11 | Needs a list of trades to simulate, options are: 12 | 1. Provide a custom pandas.DataFrame(index=DatetimeIndex): 13 | symbol action num_of_shares 14 | 2011-01-10 AAPL Buy 1500 15 | 2011-01-13 AAPL Sell 1500 16 | 2011-01-13 IBM Buy 4000 17 | 2011-01-26 GOOG Buy 1000 18 | 2. Load the trades from a csv file: 19 | year,month,day,symbol,action,num_of_shares 20 | 2011,1,10,AAPL,Buy,1500 21 | 2011,1,13,AAPL,Sell,1500 22 | 2011,1,13,IBM,Buy,4000 23 | 2011,1,26,GOOG,Buy,1000 24 | 3. Create trades from an event list: usually from EventFinder 25 | 26 | ''' 27 | def __init__(self): 28 | self.da = DataAccess() 29 | 30 | self.initial_cash = 0 31 | self.field = 'adjusted_close' 32 | 33 | self.trades = None 34 | self.prices = None 35 | self.num_of_shares = None 36 | self.cash = None 37 | self.equities = None 38 | self.portfolio = None 39 | 40 | def load_trades(self, file_path): 41 | ''' 42 | Load trades from a csv file 43 | 44 | csv file example: 45 | year,month,day,symbol,action,num_of_shares 46 | 2011,1,10,AAPL,Buy,1500 47 | 2011,1,13,AAPL,Sell,1500 48 | 2011,1,13,IBM,Buy,4000 49 | 2011,1,26,GOOG,Buy,1000 50 | 51 | Parameters 52 | ---------- 53 | file_path: str, path to the csv containing the orders 54 | 55 | ''' 56 | # 1. Read the .csv file 57 | self.trades = pd.read_csv(file_path) 58 | 59 | # 2. Set the indexes as the value of a the columns (year, month, day) 60 | dates = list() 61 | for idx, row in self.trades.iterrows(): 62 | date = datetime(row['year'], row['month'], row['day']) 63 | dates.append(date) 64 | dates = pd.Series(dates) 65 | self.trades = self.trades.set_index(dates) 66 | 67 | # 3. Delete unnescessary columns 68 | self.trades = self.trades[['symbol', 'action', 'num_of_shares']] 69 | 70 | # 4. Sort the DataFrame by the index (dates) 71 | self.trades = self.trades.sort_index() 72 | 73 | def create_trades_from_event(self, eventList, 74 | eventDayAction='Buy', eventDayShares=100, 75 | actionAfter='Sell', daysAfter=5, sharesAfter=100, 76 | actionBefore=None, daysBefore=5, sharesBefore=100): 77 | ''' 78 | Creates trades using an event list; usually from the EventFinder. 79 | Also creates aditional order after and before of the event as defined by the user 80 | 81 | Parameters 82 | ---------- 83 | eventList: pandas.Series 84 | ''' 85 | self.trades = pd.DataFrame(index=eventList.index, columns=['symbol', 'action', 'num_of_shares']) 86 | self.trades['symbol'] = eventList 87 | self.trades['action'] = eventDayAction 88 | self.trades['num_of_shares'] = eventDayShares 89 | 90 | # TODO: Actions BEFORE 91 | 92 | if actionAfter is not None: 93 | dicts = [] 94 | for idx, row in self.trades.iterrows(): 95 | after_date = DateUtils.nyse_add(idx.to_pydatetime(), daysAfter) 96 | after = pd.DataFrame([ {'symbol': row['symbol'], 97 | 'action': actionAfter, 98 | 'num_of_shares': sharesAfter}], 99 | index=[after_date], columns=self.trades.columns) 100 | self.trades = self.trades.append(after) 101 | 102 | self.trades = self.trades.sort() 103 | 104 | 105 | def simulate(self): 106 | ''' 107 | Simulates the trades 108 | 109 | Parameters 110 | ---------- 111 | trades: str(filepath) or pandas.DataFrame, if str loads the orders from a csv file 112 | 113 | Returns 114 | ------- 115 | Nothing: Fills the DataFrames: cash, equities, porfolio 116 | ''' 117 | # 0.1 Load/Download required data 118 | symbols = list(set(self.trades['symbol'])) 119 | start_date = self.trades.index[0].to_pydatetime() # Convert from TimeStamp to datetime 120 | end_date = self.trades.index[-1].to_pydatetime() # Convert from TimeStamp to datetime 121 | self.prices = self.da.get_data(symbols, start_date, end_date, self.field) 122 | # 0.2 Init DataFrames 123 | self.cash = pd.Series(index=self.prices.index, name='Cash', dtype=np.float64) 124 | self.num_of_shares = pd.DataFrame(index=self.prices.index, columns=self.prices.columns, dtype=np.float64) 125 | 126 | # 1. Fill the DataFrames 127 | current_cash = self.initial_cash 128 | current_shares = dict([(symbol, 0) for symbol in symbols]) 129 | for idx, row in self.trades.iterrows(): 130 | # 1.2.0 Get info of the row 131 | symbol = row['symbol'] 132 | action = row['action'].lower()[0:1] 133 | num_of_shares = row['num_of_shares'] 134 | 135 | # 1.2.1 Fill the self.cash DataFrame - ammount of cash on each date 136 | # NOTE: but stocks spends cash, sell stocks wins cash 137 | cash_change = self.prices[symbol][idx] * num_of_shares 138 | if action == 'b': 139 | current_cash = current_cash - cash_change 140 | elif action == 's': 141 | current_cash = current_cash + cash_change 142 | # Modify self.cash DataFrame 143 | self.cash.ix[idx] = current_cash 144 | 145 | # 1.2.3 Fill the self.num_of_shares DataFrame - num of each stocks on each date 146 | if action == 'b': 147 | current_shares[symbol] = current_shares[symbol] + num_of_shares 148 | elif action == 's': 149 | current_shares[symbol] = current_shares[symbol] - num_of_shares 150 | # Modify self.num_of_shares DataFrame 151 | self.num_of_shares.ix[idx][symbol] = current_shares[symbol] 152 | 153 | # Fill forward missing values 154 | self.cash = self.cash.fillna(method='ffill') 155 | self.prices = self.prices.fillna(method='ffill').fillna(method='bfill') 156 | self.num_of_shares = self.num_of_shares.fillna(method='ffill').fillna(0) 157 | 158 | # 2. Get the value of the equitues 159 | self.equities = pd.Series(index=self.prices.index, name='Equities value') 160 | equities = self.num_of_shares * self.prices 161 | self.equities = equities.sum(axis=1) 162 | self.equities.name = 'Equities value' 163 | # 3. Get the value of the porfolio = cash + equities_value 164 | self.portfolio = pd.Series(index=self.prices.index, name='Portfolio value') 165 | self.portfolio = self.cash + self.equities 166 | self.portfolio.name = 'Portfolio value' 167 | -------------------------------------------------------------------------------- /sim/__init__.py: -------------------------------------------------------------------------------- 1 | from finance.sim.MarketSimulator import MarketSimulator 2 | -------------------------------------------------------------------------------- /test/AllTets.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from finance.test.utils.DateUtils import DateUtilsTest 4 | from finance.test.utils.CalculatorTypes import CalculatorTypesTest 5 | from finance.test.utils.CalculatorValues import CalculatorValuesTest 6 | from finance.test.utils.FileManager import FileManagerTest 7 | from finance.test.utils.DataAccess import DataAccessTest 8 | 9 | from finance.test.sim.MarketSimulator import MarketSimulatorTest 10 | 11 | from finance.test.events.PastEvent import PastEventTest 12 | from finance.test.events.EventFinder import EventFinderTest 13 | from finance.test.events.MultipleEvents import MultipleEventsTest 14 | 15 | suite = unittest.TestSuite() 16 | 17 | suite.addTest(DateUtilsTest().suite()) 18 | suite.addTest(CalculatorTypesTest().suite()) 19 | suite.addTest(CalculatorValuesTest().suite()) 20 | suite.addTest(FileManagerTest().suite()) 21 | suite.addTest(DataAccessTest().suite()) 22 | 23 | # This tests won't run because alpha vantange doesn't have data for google before 2014 24 | # and the test data is all precalculated. 25 | #suite.addTest(MarketSimulatorTest().suite()) 26 | 27 | 28 | #suite.addTest(PastEventTest().suite()) 29 | 30 | suite.addTest(EventFinderTest().suite()) 31 | 32 | #suite.addTest(MultipleEventsTest().suite()) 33 | 34 | unittest.TextTestRunner(verbosity=2).run(suite) -------------------------------------------------------------------------------- /test/FinanceTest.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | import pandas as pd 4 | import numpy.testing as np_test 5 | import pandas.util.testing as pd_test 6 | 7 | import os, inspect 8 | from finance.utils import DataAccess 9 | 10 | class FinanceTest(unittest.TestCase): 11 | 12 | def setUpDataAccess(self, delete=False): 13 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 14 | DataAccess.path = os.path.join(self_dir, 'data') 15 | self.data_access = DataAccess() 16 | 17 | self.data_access.empty_cache(delete=delete) 18 | self.data_access.empty_dir(delete=delete) 19 | 20 | @staticmethod 21 | def delete_data(): 22 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 23 | DataAccess.path = os.path.join(self_dir, 'data') 24 | data_access = DataAccess() 25 | data_access.empty_dirs() 26 | 27 | def assertEqual(self, ans, sol, digits=0): 28 | if type(ans) == np.ndarray and type(sol) == np.ndarray: 29 | self.assertArrayEqual(ans, sol, digits) 30 | elif type(ans) == pd.Series and type(sol) == pd.Series: 31 | self.assertSeriesEqual(ans, sol) 32 | elif type(ans) == pd.Series and type(sol) == pd.Series: 33 | self.assertSeriesEqual(ans, sol, digits) 34 | elif type(ans) == pd.DataFrame and type(sol) == pd.DataFrame: 35 | self.assertFrameEqual(ans, sol, digits) 36 | else: 37 | if digits == 0: 38 | super().assertEqual(ans, sol) 39 | else: 40 | super().assertAlmostEqual(ans, sol, digits) 41 | 42 | 43 | def assertFloat(self, obj): 44 | self.assertIs(type(obj), (np.float64)) 45 | 46 | def assertArray(self, obj): 47 | self.assertIs(type(obj), np.ndarray) 48 | 49 | def assertArrayEqual(self, ans, sol, digits=0): 50 | self.assertArray(ans) 51 | self.assertArray(sol) 52 | if digits == 0: 53 | np_test.assert_array_equal(ans, sol) 54 | else: 55 | np_test.assert_array_almost_equal(ans, sol, digits) 56 | 57 | def assertSeries(self, obj): 58 | if type(obj) is pd.Series or type(obj) is pd.Series: 59 | return 60 | else: 61 | self.assertIs(type(obj), pd.Series) 62 | 63 | def assertSeriesEqual(self, ans, sol, digits=0): 64 | self.assertSeries(ans) 65 | self.assertSeries(sol) 66 | self.assertEqual(ans.name, sol.name) 67 | 68 | if digits == 0: 69 | pd_test.assert_series_equal(ans, sol, digits) 70 | else: 71 | np_test.assert_array_almost_equal(ans.values, sol.values, digits) 72 | 73 | def assertFrame(self, obj): 74 | self.assertIs(type(obj), pd.DataFrame) 75 | 76 | def assertFrameEqual(self, ans, sol, digits=0): 77 | self.assertFrame(ans) 78 | self.assertFrame(sol) 79 | self.assertEqual(ans.columns.name, sol.columns.name) 80 | 81 | if digits == 0: 82 | pd_test.assert_frame_equal(ans, sol) 83 | else: 84 | np_test.assert_array_almost_equal(ans.values, sol.values, digits) 85 | 86 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | from finance.test.FinanceTest import FinanceTest -------------------------------------------------------------------------------- /test/events/EventFinder.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | import pandas as pd 4 | import numpy.testing as np_test 5 | import pandas.util.testing as pd_test 6 | from datetime import datetime 7 | 8 | from finance.test import FinanceTest 9 | from finance.events import EventFinder 10 | from finance.events import SampleConditions 11 | 12 | class EventFinderTest(FinanceTest): 13 | 14 | def suite(self): 15 | suite = unittest.TestSuite() 16 | suite.addTest(EventFinderTest('test_oneEventPerEquity')) 17 | return suite 18 | 19 | def test_oneEventPerEquity(self): 20 | ''' 21 | Equities: AMD 22 | Function: went_below(3) 23 | Period: 2008-1-1 -> 2009-12-31 24 | 25 | Tests: oneEventPerEquity=True and oneEventPerEquity=False 26 | ''' 27 | self.setUpDataAccess() 28 | 29 | evtf = EventFinder() 30 | evtf.symbols = ['AMD'] 31 | evtf.start_date = datetime(2008, 1, 1) 32 | evtf.end_date = datetime(2009, 12, 31) 33 | evtf.condition = SampleConditions.went_below(3) 34 | evtf.search(oneEventPerEquity=True) 35 | # Test: number of events found = 1 36 | self.assertEqual(evtf.num_events, 1) 37 | # Test: date of the event is 2008-10-27 38 | date1 = evtf.matrix['AMD'][evtf.matrix['AMD'] == 1].index[0].to_pydatetime() 39 | self.assertEqual(date1, datetime(2008,10,27)) 40 | 41 | # Test: oneEventPerEquity=False 42 | evtf.search(oneEventPerEquity=False) 43 | # Test: number of events found = 2 44 | self.assertEqual(evtf.num_events, 2) 45 | # Test: date of the events 46 | date1 = evtf.matrix['AMD'][evtf.matrix['AMD'] == 1].index[0].to_pydatetime() 47 | date2 = evtf.matrix['AMD'][evtf.matrix['AMD'] == 1].index[1].to_pydatetime() 48 | self.assertEqual(date1, datetime(2008,10,27)) 49 | self.assertEqual(date2, datetime(2008,11,11)) 50 | 51 | if __name__ == '__main__': 52 | suite = EventFinderTest().suite() 53 | unittest.TextTestRunner(verbosity=2).run(suite) 54 | 55 | FinanceTest.delete_data() -------------------------------------------------------------------------------- /test/events/MultipleEvents.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os, inspect 3 | import numpy as np 4 | import pandas as pd 5 | from datetime import datetime 6 | 7 | from finance.test import FinanceTest 8 | from finance.events import EventFinder 9 | from finance.events import SampleConditions 10 | from finance.events import MultipleEvents 11 | 12 | class MultipleEventsTest(FinanceTest): 13 | 14 | def suite(self): 15 | suite = unittest.TestSuite() 16 | suite.addTest(MultipleEventsTest('test_window')) 17 | return suite 18 | 19 | def test_window(self): 20 | ''' 21 | Two events on two different equities 22 | 23 | Tests 24 | ----- 25 | 1. Expected returns 26 | 2. Abnormal returns 27 | 3. Cumulative abnormal returns 28 | 4. Mean of ER, AR, CAR 29 | ''' 30 | # Set Up 31 | self.setUpDataAccess() 32 | 33 | evt_fin = EventFinder() 34 | evt_fin.symbols = ['AMD', 'CBG'] 35 | evt_fin.start_date = datetime(2008, 1, 1) 36 | evt_fin.end_date = datetime(2009, 12, 31) 37 | evt_fin.condition = SampleConditions.went_below(3) 38 | evt_fin.search() 39 | 40 | mul_evt = MultipleEvents() 41 | mul_evt.list = evt_fin.list 42 | mul_evt.market = 'SPY' 43 | mul_evt.lookback_days = 20 44 | mul_evt.lookforward_days = 20 45 | mul_evt.estimation_period = 200 46 | mul_evt.run() 47 | 48 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 49 | tests = ['MultipleEvents_window_1.csv'] 50 | tests = [os.path.join(self_dir, 'docs', test) for test in tests] 51 | 52 | for test_file in tests: 53 | # Set up 54 | solution = pd.read_csv(test_file).set_index('index') 55 | # Test 1 56 | sol_er = solution[solution.columns[0:2]] 57 | sol_er.columns = mul_evt.er.columns 58 | sol_er.columns.name = 'Expected return' 59 | self.assertEqual(mul_evt.er, sol_er) 60 | # Test 2 61 | sol_ar = solution[solution.columns[3:5]] 62 | sol_ar.columns = mul_evt.ar.columns 63 | sol_ar.columns.name = 'Abnormal return' 64 | self.assertEqual(mul_evt.ar, sol_ar) 65 | # Test 3 66 | sol_car = solution[solution.columns[6:8]] 67 | sol_car.columns = mul_evt.car.columns 68 | sol_car.columns.name = 'Cum abnormal return' 69 | self.assertEqual(mul_evt.car, sol_car) 70 | # Test 4 71 | self.assertEqual(mul_evt.mean_er, solution['Mean ER']) 72 | self.assertEqual(mul_evt.mean_ar, solution['Mean AR']) 73 | self.assertEqual(mul_evt.mean_car, solution['Mean CAR']) 74 | 75 | if __name__ == '__main__': 76 | suite = MultipleEventsTest().suite() 77 | unittest.TextTestRunner(verbosity=2).run(suite) 78 | 79 | # FinanceTest.delete_data() 80 | -------------------------------------------------------------------------------- /test/events/PastEvent.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os, inspect 3 | import numpy as np 4 | import pandas as pd 5 | from datetime import datetime 6 | 7 | from finance.test import FinanceTest 8 | from finance.events import PastEvent 9 | 10 | class PastEventTest(FinanceTest): 11 | 12 | def suite(self): 13 | suite = unittest.TestSuite() 14 | suite.addTest(PastEventTest('test_window')) 15 | return suite 16 | 17 | def test_window(self): 18 | ''' 19 | Tests 20 | ----- 21 | 1. Expected returns 22 | 2. Abnormal returns 23 | 3. Cumulative abnormal returns 24 | 4. t-test 25 | ''' 26 | self.setUpDataAccess() 27 | 28 | evt = PastEvent() 29 | evt.symbol = 'AAPL' 30 | evt.market = "^gspc" 31 | evt.lookback_days = 10 32 | evt.lookforward_days = 10 33 | evt.estimation_period = 252 34 | evt.date = datetime(2009, 1, 5) 35 | evt.run() 36 | 37 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 38 | tests = ['PastEvent_window_1.csv'] 39 | tests = [os.path.join(self_dir, 'docs', test) for test in tests] 40 | 41 | for test_file in tests: 42 | # Set up 43 | solution = pd.read_csv(test_file) 44 | solution.index = evt.er.index 45 | # Test 1 46 | self.assertEqual(evt.er, solution['Expected return'], 3) 47 | # Test 2 48 | self.assertEqual(evt.ar, solution['Abnormal return'], 3) 49 | # Test 3 50 | self.assertEqual(evt.car, solution['Cum abnormal return'], 2) 51 | # Test 4 52 | self.assertEqual(evt.t_test, solution['t-test'], 2) 53 | 54 | if __name__ == '__main__': 55 | suite = PastEventTest().suite() 56 | unittest.TextTestRunner(verbosity=2).run(suite) 57 | 58 | # FinanceTest.delete_data() -------------------------------------------------------------------------------- /test/events/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/events/__init__.py -------------------------------------------------------------------------------- /test/events/docs/MultipleEvents_1.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/events/docs/MultipleEvents_1.ods -------------------------------------------------------------------------------- /test/events/docs/MultipleEvents_window_1.csv: -------------------------------------------------------------------------------- 1 | index,ER AMD,ER CBG,Mean ER,AR AMD,AR CBG,Mean AR,CAR AMD,CAR CBG,Mean CAR 2 | -20,-0.118648654183,-0.068507123632,-0.093577888908,-0.049955996979,-0.078814304940,-0.064385150960,-0.049955996979,-0.078814304940,-0.064385150960 3 | -19,0.061374628686,-0.042773578115,0.009300525286,0.162401595090,-0.014818044922,0.073791775084,0.112445598111,-0.093632349862,0.009406624125 4 | -18,0.000016279819,-0.006146680716,-0.003065200449,-0.097159136962,-0.018853319284,-0.058006228123,0.015286461149,-0.112485669145,-0.048599603998 5 | -17,-0.055282787600,0.029795387390,-0.012743700105,-0.071299490882,-0.021248378843,-0.046273934862,-0.056013029732,-0.133734047989,-0.094873538861 6 | -16,-0.021191899239,-0.009926699118,-0.015559299178,0.115394797790,0.125745908157,0.120570352974,0.059381768058,-0.007988139832,0.025696814113 7 | -15,-0.077392919159,0.031739062611,-0.022826928274,0.011167753596,-0.041865644889,-0.015348945646,0.070549521654,-0.049853784721,0.010347868467 8 | -14,-0.068109657577,0.060402664093,-0.003853496742,0.153216040556,0.054686849974,0.103951445265,0.223765562210,0.004833065253,0.114299313732 9 | -13,-0.038770604394,0.003157077339,-0.017806763528,-0.078876454429,-0.000863499357,-0.039869976893,0.144889107781,0.003969565896,0.074429336839 10 | -12,-0.105739882900,-0.096491682821,-0.101115782861,0.103270747097,-0.040808088346,0.031231329376,0.248159854879,-0.036838522450,0.105660666214 11 | -11,-0.037397414220,0.012709839844,-0.012343787188,-0.019533278849,0.104001035488,0.042233878319,0.228626576029,0.067162513038,0.147894544534 12 | -10,0.217467992501,0.001622459740,0.109545226120,-0.112481115860,-0.039627210334,-0.076054163097,0.116145460169,0.027535302705,0.071840381437 13 | -9,-0.023138655884,-0.022594212943,-0.022866434414,0.037390437357,-0.049010725328,-0.005810143986,0.153535897526,-0.021475422624,0.066030237451 14 | -8,-0.148723645278,-0.090164176059,-0.119443910668,0.064414511788,0.002398218612,0.033406365200,0.217950409315,-0.019077204012,0.099436602651 15 | -7,0.061656861098,-0.004694700780,0.028481080159,-0.007948421201,0.048426479205,0.020239029002,0.210001988114,0.029349275193,0.119675631654 16 | -6,-0.009810672177,-0.022474990069,-0.016142831123,0.031655332371,-0.066910484791,-0.017627576210,0.241657320485,-0.037561209598,0.102048055444 17 | -5,0.089614121640,-0.020366145963,0.034623987838,-0.113367090761,0.041838538601,-0.035764276080,0.128290229725,0.004277329004,0.066283779364 18 | -4,-0.045749794885,-0.075282009501,-0.060515902193,-0.002912005601,0.030236964456,0.013662479427,0.125378224123,0.034514293460,0.079946258791 19 | -3,-0.082758559333,0.080112912423,-0.001322823455,0.008589761379,0.011082056130,0.009835908755,0.133967985503,0.045596349590,0.089782167546 20 | -2,0.016637172222,-0.016394403615,0.000121384304,-0.110559824156,-0.049888017134,-0.080223920645,0.023408161346,-0.004291667544,0.009558246901 21 | -1,-0.077128452799,-0.033897455296,-0.055512954048,0.000908940604,-0.024744520013,-0.011917789704,0.024317101951,-0.029036187557,-0.002359542803 22 | 0,-0.054101514624,-0.047243319859,-0.050672417242,0.024398544327,-0.005215696534,0.009591423896,0.048715646278,-0.034251884091,0.007231881093 23 | 1,0.174652106653,-0.094734548820,0.039958778916,-0.208665712096,-0.029832925228,-0.119249318662,-0.159950065818,-0.064084809319,-0.112017437568 24 | 2,-0.011747417245,-0.015731110112,-0.013739263678,0.061043191893,0.067114509321,0.064078850607,-0.098906873925,0.003029700002,-0.047938586961 25 | 3,0.051276954526,0.050183609560,0.050730282043,0.143353917958,-0.005070827605,0.069141545176,0.044447044032,-0.002041127603,0.021202958215 26 | 4,0.007386183497,-0.086092291691,-0.039353054097,-0.024240116082,0.010552723346,-0.006843696368,0.020206927951,0.008511595743,0.014359261847 27 | 5,0.003592925150,0.003926511508,0.003759718329,0.027835646279,-0.023381764427,0.002226940926,0.048042574229,-0.014870168684,0.016586202773 28 | 6,0.050128778943,-0.024473344007,0.012827717468,0.002502800004,0.099870169404,0.051186484704,0.050545374234,0.085000000721,0.067772687477 29 | 7,-0.063934148539,0.126316662551,0.031191257006,-0.001855325145,0.124605846674,0.061375260764,0.048690049089,0.209605847394,0.129147948241 30 | 8,-0.084193281540,0.013961542673,-0.035115869433,-0.022848971981,-0.131955642968,-0.077402307475,0.025841077107,0.077650204426,0.051745640767 31 | 9,0.048916958247,0.083595129259,0.066256043753,-0.052071532380,0.013394837297,-0.019338347542,-0.026230455273,0.091045041723,0.032407293225 32 | 10,-0.020698749351,0.016710237092,-0.001994256129,-0.017275934194,-0.083783407824,-0.050529671009,-0.043506389466,0.007261633899,-0.018122377784 33 | 11,-0.047148342671,-0.006107749297,-0.026628045984,0.020832553197,-0.140951074232,-0.060059260518,-0.022673836269,-0.133689440333,-0.078181638301 34 | 12,-0.066998739209,0.064881679090,-0.001058530059,-0.064758017548,0.000252420526,-0.032252798511,-0.087431853817,-0.133437019807,-0.110434436812 35 | 13,0.092785624781,0.047652838294,0.070219231537,-0.042201967193,0.049469463864,0.003633748336,-0.129633821010,-0.083967555943,-0.106800688477 36 | 14,-0.075759615217,-0.025962104513,-0.050860859865,-0.024240384783,-0.088791993848,-0.056516189316,-0.153874205794,-0.172759549790,-0.163316877792 37 | 15,-0.020836030710,-0.044954170952,-0.032895100831,0.049642615072,-0.080971754974,-0.015664569951,-0.104231590722,-0.253731304765,-0.178981447743 38 | 16,0.027538841091,0.152216295517,0.089877568304,-0.027538841091,0.097783704483,0.035122431696,-0.131770431813,-0.155947600281,-0.143859016047 39 | 17,-0.097270942099,-0.041454521906,-0.069362732002,-0.054729057901,0.058403674448,0.001837308274,-0.186499489714,-0.097543925833,-0.142021707774 40 | 18,-0.112384384195,0.022649601262,-0.044867391466,0.013327780421,0.617350398738,0.315339089579,-0.173171709293,0.519806472905,0.173317381806 41 | 19,0.080290360671,0.043180647280,0.061735503975,-0.127410779519,-0.024887964353,-0.076149371936,-0.300582488812,0.494918508552,0.097168009870 42 | 20,0.103315202198,-0.037984351622,0.032665425288,-0.081337180220,-0.113712255164,-0.097524717692,-0.381919669032,0.381206253387,-0.000356707822 43 | -------------------------------------------------------------------------------- /test/events/docs/PastEvent_1.csv: -------------------------------------------------------------------------------- 1 | Slope,Intercept,STD Error,ER,AR,CAR,T-test 2 | 0.9790229046,-0.0006478696,0.0267687789,-0.021366671007,0.024308513053,0.024308513053,0.908091965491 3 | ,,,0.002227446205,0.004203059210,0.028511572263,0.157013482918 4 | ,,,-0.018565969090,-0.028738144799,-0.000226572536,-1.073569507841 5 | ,,,-0.010161452173,0.017574088954,0.017347516418,0.656514404841 6 | ,,,0.005011943549,-0.020545697344,-0.003198180926,-0.767524638104 7 | ,,,0.004595989791,0.004420500896,0.001222319970,0.165136441649 8 | ,,,-0.004439227750,0.013845459379,0.015067779349,0.517224167228 9 | ,,,0.023247216847,-0.026974648414,-0.011906869065,-1.007690657300 10 | ,,,0.013213487234,-0.024086864997,-0.035993734062,-0.899811869590 11 | ,,,0.030297166603,0.032941604083,-0.003052129979,1.230597936308 12 | ,,,-0.005218324214,0.047464016265,0.044411886286,1.773110997217 13 | ,,,0.007005282681,-0.023538616015,0.020873270272,-0.879330958465 14 | ,,,-0.030027983484,0.008444469385,0.029317739656,0.315459641004 15 | ,,,0.002677989961,0.015834370088,0.045152109744,0.591523809953 16 | ,,,-0.021504017980,-0.001351881019,0.043800228726,-0.050502154887 17 | ,,,-0.022738699194,0.001575856690,0.045376085415,0.058869203374 18 | ,,,0.001073345977,-0.011769750164,0.033606335251,-0.439681996862 19 | ,,,-0.033405871071,0.006260713491,0.039867048742,0.233881176003 20 | ,,,0.000653435468,-0.023472068714,0.016394980028,-0.876844954125 21 | ,,,0.006755081729,-0.019338263822,-0.002943283794,-0.722418601457 22 | ,,,-0.052356014794,0.002117073488,-0.000826210306,0.079087413545 23 | -------------------------------------------------------------------------------- /test/events/docs/PastEvent_1.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/events/docs/PastEvent_1.ods -------------------------------------------------------------------------------- /test/events/docs/PastEvent_window_1.csv: -------------------------------------------------------------------------------- 1 | Slope,Intercept,STD Error,Expected return,Abnormal return,Cum abnormal return,t-test 2 | 0.9790229046,-0.0006478696,0.0654485242,-0.021366671007,0.024308513053,0.024308513053,0.371414227279 3 | ,,,0.002227446205,0.004203059210,0.028511572263,0.064219312191 4 | ,,,-0.018565969090,-0.028738144799,-0.000226572536,-0.439095382778 5 | ,,,-0.010161452173,0.017574088954,0.017347516418,0.268517726879 6 | ,,,0.005011943549,-0.020545697344,-0.003198180926,-0.313921476251 7 | ,,,0.004595989791,0.004420500896,0.001222319970,0.067541643580 8 | ,,,-0.004439227750,0.013845459379,0.015067779349,0.211547312058 9 | ,,,0.023247216847,-0.026974648414,-0.011906869065,-0.412150598221 10 | ,,,0.013213487234,-0.024086864997,-0.035993734062,-0.368027625990 11 | ,,,0.030297166603,0.032941604083,-0.003052129979,0.503320807775 12 | ,,,-0.005218324214,0.047464016265,0.044411886286,0.725211405823 13 | ,,,0.007005282681,-0.023538616015,0.020873270272,-0.359650829290 14 | ,,,-0.030027983484,0.008444469385,0.029317739656,0.129024595805 15 | ,,,0.002677989961,0.015834370088,0.045152109744,0.241936243398 16 | ,,,-0.021504017980,-0.001351881019,0.043800228726,-0.020655637916 17 | ,,,-0.022738699194,0.001575856690,0.045376085415,0.024077803254 18 | ,,,0.001073345977,-0.011769750164,0.033606335251,-0.179832170439 19 | ,,,-0.033405871071,0.006260713491,0.039867048742,0.095658589175 20 | ,,,0.000653435468,-0.023472068714,0.016394980028,-0.358634040885 21 | ,,,0.006755081729,-0.019338263822,-0.002943283794,-0.295472878110 22 | ,,,-0.052356014794,0.002117073488,-0.000826210306,0.032347153929 23 | -------------------------------------------------------------------------------- /test/events/docs/test1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/events/docs/test1_1.png -------------------------------------------------------------------------------- /test/events/docs/test1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/events/docs/test1_2.png -------------------------------------------------------------------------------- /test/sim/MarketSimulator.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os, inspect 3 | import numpy as np 4 | import pandas as pd 5 | from datetime import datetime 6 | from finance.test import FinanceTest 7 | 8 | from finance.utils import DataAccess 9 | from finance.sim import MarketSimulator 10 | 11 | 12 | class MarketSimulatorTest(FinanceTest): 13 | 14 | def suite(self): 15 | suite = unittest.TestSuite() 16 | suite.addTest(MarketSimulatorTest('test_1')) 17 | return suite 18 | 19 | def test_1(self): 20 | ''' 21 | Loads solution from csv file and test the values 22 | Tests 23 | ----- 24 | 1. Name of the solution Series: cash, equities, portfolio 25 | 2. Values of the solution Series: cash, equities, portfolio 26 | ''' 27 | # Set up 28 | self.setUpDataAccess() 29 | 30 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 31 | tests = ['Test_1.csv'] 32 | tests = [os.path.join(self_dir, 'docs', test) for test in tests] 33 | 34 | orders = ['orders_1.csv'] 35 | orders = [os.path.join(self_dir, 'docs', order) for order in orders] 36 | 37 | for test_file, order in zip(tests, orders): 38 | solution = pd.read_csv(test_file) 39 | solution = solution.set_index(pd.to_datetime(solution['Date'])) 40 | 41 | simulator = MarketSimulator() 42 | simulator.initial_cash = 1000000 43 | simulator.load_trades(order) 44 | simulator.simulate() 45 | 46 | # Test 1 47 | self.assertEqual(simulator.cash.name, 'Cash') 48 | self.assertEqual(simulator.equities.name, 'Equities value') 49 | self.assertEqual(simulator.portfolio.name, 'Portfolio value') 50 | # Test 2 51 | self.assertEqual(simulator.cash, solution['Cash']) 52 | self.assertEqual(simulator.equities, solution['Equities value']) 53 | self.assertEqual(simulator.portfolio, solution['Portfolio value']) 54 | 55 | if __name__ == '__main__': 56 | suite = MarketSimulatorTest().suite() 57 | unittest.TextTestRunner(verbosity=2).run(suite) 58 | 59 | # FinanceTest.delete_data() -------------------------------------------------------------------------------- /test/sim/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/sim/__init__.py -------------------------------------------------------------------------------- /test/sim/docs/Test_1.csv: -------------------------------------------------------------------------------- 1 | Date,Cash,Equities value,Portfolio value 2 | 1/10/2015,490840.00,509160.00,1000000.00 3 | 1/11/2015,490840.00,507945.00,998785.00 4 | 1/12/2015,490840.00,512085.00,1002925.00 5 | 1/13/2015,429120.00,575680.00,1004800.00 6 | 1/14/2015,429120.00,580240.00,1009360.00 7 | 1/18/2015,429120.00,582760.00,1011880.00 8 | 1/19/2015,429120.00,602280.00,1031400.00 9 | 1/20/2015,429120.00,602680.00,1031800.00 10 | 1/21/2015,429120.00,601520.00,1030640.00 11 | 1/24/2015,429120.00,617520.00,1046640.00 12 | 1/25/2015,429120.00,624520.00,1053640.00 13 | 1/26/2015,-187380.00,1239460.00,1052080.00 14 | 1/27/2015,-187380.00,1239870.00,1052490.00 15 | 1/28/2015,-187380.00,1216870.00,1029490.00 16 | 1/31/2015,-187380.00,1227040.00,1039660.00 17 | 2/1/2015,-187380.00,1243760.00,1056380.00 18 | 2/2/2015,130460.00,925880.00,1056340.00 19 | 2/3/2015,130460.00,924790.00,1055250.00 20 | 2/4/2015,130460.00,928020.00,1058480.00 21 | 2/7/2015,130460.00,932050.00,1062510.00 22 | 2/8/2015,130460.00,945380.00,1075840.00 23 | 2/9/2015,130460.00,939700.00,1070160.00 24 | 2/10/2015,-188260.00,1253720.00,1065460.00 25 | 2/11/2015,-188260.00,1260820.00,1072560.00 26 | 2/14/2015,-188260.00,1262030.00,1073770.00 27 | 2/15/2015,-188260.00,1256550.00,1068290.00 28 | 2/16/2015,-188260.00,1258820.00,1070560.00 29 | 2/17/2015,-188260.00,1263100.00,1074840.00 30 | 2/18/2015,-188260.00,1270280.00,1082020.00 31 | 2/22/2015,-188260.00,1239170.00,1050910.00 32 | 2/23/2015,-188260.00,1233400.00,1045140.00 33 | 2/24/2015,-188260.00,1233180.00,1044920.00 34 | 2/25/2015,-188260.00,1240280.00,1052020.00 35 | 2/28/2015,-188260.00,1242080.00,1053820.00 36 | 3/1/2015,-188260.00,1222040.00,1033780.00 37 | 3/2/2015,-188260.00,1222790.00,1034530.00 38 | 3/3/2015,770506.00,285714.00,1056220.00 39 | 3/4/2015,770506.00,282816.00,1053322.00 40 | 3/7/2015,770506.00,279504.00,1050010.00 41 | 3/8/2015,770506.00,283608.00,1054114.00 42 | 3/9/2015,770506.00,289872.00,1060378.00 43 | 3/10/2015,770506.00,283158.00,1053664.00 44 | 3/11/2015,770506.00,283878.00,1054384.00 45 | 3/14/2015,770506.00,282060.00,1052566.00 46 | 3/15/2015,770506.00,277920.00,1048426.00 47 | 3/16/2015,770506.00,267390.00,1037896.00 48 | 3/17/2015,770506.00,269460.00,1039966.00 49 | 3/18/2015,770506.00,272448.00,1042954.00 50 | 3/21/2015,770506.00,275562.00,1046068.00 51 | 3/22/2015,770506.00,276120.00,1046626.00 52 | 3/23/2015,770506.00,278802.00,1049308.00 53 | 3/24/2015,770506.00,279702.00,1050208.00 54 | 3/25/2015,770506.00,283428.00,1053934.00 55 | 3/28/2015,770506.00,282024.00,1052530.00 56 | 3/29/2015,770506.00,284652.00,1055158.00 57 | 3/30/2015,770506.00,285912.00,1056418.00 58 | 3/31/2015,770506.00,284994.00,1055500.00 59 | 4/1/2015,770506.00,287082.00,1057588.00 60 | 4/4/2015,770506.00,287046.00,1057552.00 61 | 4/5/2015,770506.00,286596.00,1057102.00 62 | 4/6/2015,770506.00,286686.00,1057192.00 63 | 4/7/2015,770506.00,287280.00,1057786.00 64 | 4/8/2015,770506.00,286704.00,1057210.00 65 | 4/11/2015,770506.00,286524.00,1057030.00 66 | 4/12/2015,770506.00,285300.00,1055806.00 67 | 4/13/2015,770506.00,286524.00,1057030.00 68 | 4/14/2015,770506.00,288306.00,1058812.00 69 | 4/15/2015,770506.00,290484.00,1060990.00 70 | 4/18/2015,770506.00,289998.00,1060504.00 71 | 4/19/2015,770506.00,289062.00,1059568.00 72 | 4/20/2015,770506.00,287928.00,1058434.00 73 | 4/21/2015,770506.00,294102.00,1064608.00 74 | 4/25/2015,770506.00,293022.00,1063528.00 75 | 4/26/2015,770506.00,294462.00,1064968.00 76 | 4/27/2015,770506.00,297756.00,1068262.00 77 | 4/28/2015,770506.00,298458.00,1068964.00 78 | 4/29/2015,770506.00,298116.00,1068622.00 79 | 5/2/2015,770506.00,300852.00,1071358.00 80 | 5/3/2015,518746.00,553872.00,1072618.00 81 | 5/4/2015,518746.00,546678.00,1065424.00 82 | 5/5/2015,518746.00,539748.00,1058494.00 83 | 5/6/2015,518746.00,543543.00,1062289.00 84 | 5/9/2015,518746.00,544236.00,1062982.00 85 | 5/10/2015,518746.00,548328.00,1067074.00 86 | 5/11/2015,518746.00,545523.00,1064269.00 87 | 5/12/2015,518746.00,554334.00,1073080.00 88 | 5/13/2015,518746.00,546876.00,1065622.00 89 | 5/16/2015,518746.00,543444.00,1062190.00 90 | 5/17/2015,518746.00,548724.00,1067470.00 91 | 5/18/2015,518746.00,548526.00,1067272.00 92 | 5/19/2015,518746.00,549021.00,1067767.00 93 | 5/20/2015,518746.00,547635.00,1066381.00 94 | 5/23/2015,518746.00,541530.00,1060276.00 95 | 5/24/2015,518746.00,540639.00,1059385.00 96 | 5/25/2015,518746.00,539880.00,1058626.00 97 | 5/26/2015,518746.00,538032.00,1056778.00 98 | 5/27/2015,518746.00,539088.00,1057834.00 99 | 5/31/2015,518746.00,543675.00,1062421.00 100 | 6/1/2015,518746.00,536052.00,1054798.00 101 | 6/2/2015,518746.00,534534.00,1053280.00 102 | 6/3/2015,1049947.00,0.00,1049947.00 103 | 6/6/2015,1049947.00,0.00,1049947.00 104 | 6/7/2015,1049947.00,0.00,1049947.00 105 | 6/8/2015,1049947.00,0.00,1049947.00 106 | 6/9/2015,1049947.00,0.00,1049947.00 107 | 6/10/2015,662311.00,387636.00,1049947.00 108 | 6/13/2015,662311.00,388476.00,1050787.00 109 | 6/14/2015,662311.00,395412.00,1057723.00 110 | 6/15/2015,662311.00,388644.00,1050955.00 111 | 6/16/2015,662311.00,386760.00,1049071.00 112 | 6/17/2015,662311.00,380928.00,1043239.00 113 | 6/20/2015,662311.00,375048.00,1037359.00 114 | 6/21/2015,662311.00,386928.00,1049239.00 115 | 6/22/2015,662311.00,383724.00,1046035.00 116 | 6/23/2015,662311.00,393972.00,1056283.00 117 | 6/24/2015,662311.00,388176.00,1050487.00 118 | 6/27/2015,662311.00,394944.00,1057255.00 119 | 6/28/2015,662311.00,398772.00,1061083.00 120 | 6/29/2015,662311.00,397320.00,1059631.00 121 | 6/30/2015,662311.00,399264.00,1061575.00 122 | 7/1/2015,662311.00,408288.00,1070599.00 123 | 7/5/2015,662311.00,415620.00,1077931.00 124 | 7/6/2015,662311.00,418392.00,1080703.00 125 | 7/7/2015,662311.00,424872.00,1087183.00 126 | 7/8/2015,662311.00,427848.00,1090159.00 127 | 7/11/2015,662311.00,421056.00,1083367.00 128 | 7/12/2015,662311.00,420768.00,1083079.00 129 | 7/13/2015,662311.00,425844.00,1088155.00 130 | 7/14/2015,662311.00,425544.00,1087855.00 131 | 7/15/2015,662311.00,434052.00,1096363.00 132 | 7/18/2015,662311.00,444612.00,1106923.00 133 | 7/19/2015,662311.00,448236.00,1110547.00 134 | 7/20/2015,662311.00,460188.00,1122499.00 135 | 7/21/2015,662311.00,460656.00,1122967.00 136 | 7/22/2015,662311.00,467808.00,1130119.00 137 | 7/25/2015,662311.00,473988.00,1136299.00 138 | 7/26/2015,662311.00,479832.00,1142143.00 139 | 7/27/2015,662311.00,466956.00,1129267.00 140 | 7/28/2015,662311.00,466044.00,1128355.00 141 | 7/29/2015,662311.00,464448.00,1126759.00 142 | 8/1/2015,662311.00,471912.00,1134223.00 143 | 8/2/2015,662311.00,462588.00,1124899.00 144 | 8/3/2015,662311.00,466932.00,1129243.00 145 | 8/4/2015,662311.00,448860.00,1111171.00 146 | 8/5/2015,662311.00,444396.00,1106707.00 147 | 8/8/2015,662311.00,420120.00,1082431.00 148 | 8/9/2015,662311.00,444864.00,1107175.00 149 | 8/10/2015,662311.00,432588.00,1094899.00 150 | 8/11/2015,662311.00,444492.00,1106803.00 151 | 8/12/2015,662311.00,448404.00,1110715.00 152 | 8/15/2015,662311.00,456048.00,1118359.00 153 | 8/16/2015,662311.00,452556.00,1114867.00 154 | 8/17/2015,662311.00,452508.00,1114819.00 155 | 8/18/2015,662311.00,435396.00,1097707.00 156 | 8/19/2015,662311.00,423480.00,1085791.00 157 | 8/22/2015,662311.00,423960.00,1086271.00 158 | 8/23/2015,662311.00,444372.00,1106683.00 159 | 8/24/2015,662311.00,447444.00,1109755.00 160 | 8/25/2015,662311.00,444516.00,1106827.00 161 | 8/26/2015,662311.00,456240.00,1118551.00 162 | 8/29/2015,662311.00,463848.00,1126159.00 163 | 8/30/2015,662311.00,463872.00,1126183.00 164 | 8/31/2015,662311.00,457728.00,1120039.00 165 | 9/1/2015,662311.00,453216.00,1115527.00 166 | 9/2/2015,662311.00,444912.00,1107223.00 167 | 9/6/2015,662311.00,451680.00,1113991.00 168 | 9/7/2015,662311.00,456660.00,1118971.00 169 | 9/8/2015,662311.00,456912.00,1119223.00 170 | 9/9/2015,662311.00,448992.00,1111303.00 171 | 9/12/2015,662311.00,451920.00,1114231.00 172 | 9/13/2015,662311.00,457476.00,1119787.00 173 | 9/14/2015,662311.00,463044.00,1125355.00 174 | 9/15/2015,662311.00,467400.00,1129711.00 175 | 9/16/2015,662311.00,476364.00,1138675.00 176 | 9/19/2015,662311.00,489612.00,1151923.00 177 | 9/20/2015,662311.00,491772.00,1154083.00 178 | 9/21/2015,662311.00,490212.00,1152523.00 179 | 9/22/2015,662311.00,477936.00,1140247.00 180 | 9/23/2015,662311.00,480888.00,1143199.00 181 | 9/26/2015,662311.00,479544.00,1141855.00 182 | 9/27/2015,662311.00,474900.00,1137211.00 183 | 9/28/2015,662311.00,472224.00,1134535.00 184 | 9/29/2015,662311.00,464556.00,1126867.00 185 | 9/30/2015,662311.00,453552.00,1115863.00 186 | 10/3/2015,662311.00,445560.00,1107871.00 187 | 10/4/2015,662311.00,443064.00,1105375.00 188 | 10/5/2015,662311.00,449904.00,1112215.00 189 | 10/6/2015,662311.00,448860.00,1111171.00 190 | 10/7/2015,662311.00,439848.00,1102159.00 191 | 10/10/2015,662311.00,462468.00,1124779.00 192 | 10/11/2015,662311.00,476124.00,1138435.00 193 | 10/12/2015,662311.00,478380.00,1140691.00 194 | 10/13/2015,662311.00,485796.00,1148107.00 195 | 10/14/2015,662311.00,501948.00,1164259.00 196 | 10/17/2015,662311.00,499548.00,1161859.00 197 | 10/18/2015,662311.00,502224.00,1164535.00 198 | 10/19/2015,662311.00,474132.00,1136443.00 199 | 10/20/2015,662311.00,470196.00,1132507.00 200 | 10/21/2015,662311.00,467292.00,1129603.00 201 | 10/24/2015,662311.00,482640.00,1144951.00 202 | 10/25/2015,662311.00,473124.00,1135435.00 203 | 10/26/2015,662311.00,476484.00,1138795.00 204 | 10/27/2015,662311.00,481356.00,1143667.00 205 | 10/28/2015,662311.00,481668.00,1143979.00 206 | 10/31/2015,662311.00,481464.00,1143775.00 207 | 11/1/2015,662311.00,471624.00,1133935.00 208 | 11/2/2015,662311.00,472692.00,1135003.00 209 | 11/3/2015,662311.00,479424.00,1141735.00 210 | 11/4/2015,662311.00,476064.00,1138375.00 211 | 11/7/2015,662311.00,475452.00,1137763.00 212 | 11/8/2015,662311.00,483180.00,1145491.00 213 | 11/9/2015,662311.00,470160.00,1132471.00 214 | 11/10/2015,662311.00,458196.00,1120507.00 215 | 11/11/2015,662311.00,457476.00,1119787.00 216 | 11/14/2015,662311.00,451104.00,1113415.00 217 | 11/15/2015,662311.00,462492.00,1124803.00 218 | 11/16/2015,662311.00,457656.00,1119967.00 219 | 11/17/2015,662311.00,448908.00,1111219.00 220 | 11/18/2015,662311.00,445968.00,1108279.00 221 | 11/21/2015,662311.00,438912.00,1101223.00 222 | 11/22/2015,662311.00,447840.00,1110151.00 223 | 11/23/2015,662311.00,436512.00,1098823.00 224 | 11/25/2015,662311.00,432444.00,1094755.00 225 | 11/28/2015,662311.00,447372.00,1109683.00 226 | 11/29/2015,662311.00,443892.00,1106203.00 227 | 11/30/2015,662311.00,454608.00,1116919.00 228 | 12/1/2015,662311.00,461424.00,1123735.00 229 | 12/2/2015,662311.00,463524.00,1125835.00 230 | 12/5/2015,662311.00,467460.00,1129771.00 231 | 12/6/2015,662311.00,465012.00,1127323.00 232 | 12/7/2015,662311.00,462804.00,1125115.00 233 | 12/8/2015,662311.00,464664.00,1126975.00 234 | 12/9/2015,662311.00,468192.00,1130503.00 235 | 12/12/2015,662311.00,466068.00,1128379.00 236 | 12/13/2015,662311.00,462468.00,1124779.00 237 | 12/14/2015,662311.00,452208.00,1114519.00 238 | 12/15/2015,662311.00,450720.00,1113031.00 239 | 12/16/2015,662311.00,453204.00,1115515.00 240 | 12/19/2015,662311.00,454620.00,1116931.00 241 | 12/20/2015,1133263.00,0.00,1133263.00 242 | -------------------------------------------------------------------------------- /test/sim/docs/Test_1.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/sim/docs/Test_1.ods -------------------------------------------------------------------------------- /test/sim/docs/orders_1.csv: -------------------------------------------------------------------------------- 1 | year,month,day,symbol,action,num_of_shares 2011,1,10,AAPL,Buy,1500 2011,1,13,AAPL,Sell,1500 2011,1,13,IBM,Buy,4000 2011,1,26,GOOG,Buy,1000 2011,2,2,XOM,Sell,4000 2011,2,10,XOM,Buy,4000 2011,3,3,GOOG,Sell,1000 2011,3,3,IBM,Sell,2200 2011,6,3,IBM,Sell,3300 2011,5,3,IBM,Buy,1500 2011,6,10,AAPL,Buy,1200 2011,8,1,GOOG,Buy,55 2011,8,1,GOOG,Sell,55 2011,12,20,AAPL,Sell,1200 -------------------------------------------------------------------------------- /test/utils/CalculatorTypes.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import numpy as np 3 | import pandas as pd 4 | from finance.test import FinanceTest 5 | 6 | from finance.utils import Calculator 7 | 8 | class CalculatorTypesTest(FinanceTest): 9 | ''' 10 | Tests output types for different input types of the functions 11 | If there outputs are Series or DataFrames checks its column names 12 | Also tests very basic output values 13 | ''' 14 | 15 | def suite(self): 16 | suite = unittest.TestSuite() 17 | suite.addTest(CalculatorTypesTest('test_ret')) 18 | suite.addTest(CalculatorTypesTest('test_returns')) 19 | suite.addTest(CalculatorTypesTest('test_sharpe_ratio')) 20 | return suite 21 | 22 | def test_ret(self): 23 | # Variables 24 | array = np.array([1,2,3,4,5]) 25 | array_2 = np.array([5,4,3,2,1]) 26 | matrix = np.array([array, array_2]).T 27 | series = pd.Series(array, index=[5,7,8,10,11]) 28 | time_series = pd.Series(array) 29 | df = pd.DataFrame(matrix, columns=['c1', 'c2'], index=[5,7,8,10,11]) 30 | 31 | # Input is numpy.ndarray of 1 dimmension => float 32 | ans = Calculator.ret(array) 33 | self.assertFloat(ans) 34 | self.assertEqual(ans, 4) 35 | # Input is numpy.ndarray of 2 dimmensions => np.ndarray 36 | ans = Calculator.ret(matrix) 37 | self.assertArray(ans) 38 | self.assertEqual(ans, np.array([4, -0.8])) 39 | # Input is pandas.Series => float 40 | ans = Calculator.ret(series) 41 | self.assertFloat(ans) 42 | self.assertEqual(ans, 4) 43 | # Input is pandas.TimeSeries => float 44 | ans = Calculator.ret(time_series) 45 | self.assertFloat(ans) 46 | self.assertEqual(ans, 4) 47 | # Input is pandas.DataFrame with col parameter => float 48 | ans = Calculator.ret(df, col='c1') 49 | self.assertFloat(ans) 50 | self.assertEqual(ans, 4) 51 | # -- 52 | ans = Calculator.ret(df, col='c2') 53 | self.assertFloat(ans) 54 | self.assertEqual(ans, -0.8) 55 | # Input is pandas.DataFrame without col parameter => Return pd.Series 56 | ans = Calculator.ret(df) 57 | self.assertSeries(ans) 58 | sol = pd.Series([4, -0.8], index=['c1', 'c2'], name='Total Returns') 59 | self.assertEqual(ans, sol) 60 | 61 | 62 | def test_returns(self): 63 | # Variables 64 | array_1 = np.array([1,1.5,3,4,4.3]) 65 | array_2 = np.array([5,4.3,3,3.5,1]) 66 | matrix = np.array([array_1, array_2]).T 67 | ser = pd.Series(array_1, name='TEST') 68 | df = pd.DataFrame(matrix, columns=['c1', 'c2']) 69 | 70 | sol_array_1 = np.array([0, 0.5, 1, 0.33333333, 0.075]) 71 | sol_array_2 = np.array([ 0., -0.14, -0.30232558, 0.16666667, -0.71428571]) 72 | sol_matrix = np.array([sol_array_1, sol_array_2]).T 73 | 74 | # Input is numpy.array of 1 dimmension => np.ndarray 75 | ans = Calculator.returns(array_1) 76 | self.assertArray(ans) 77 | self.assertEqual(ans, sol_array_1, 5) 78 | # Input is numpy.ndarray of 2 dimmension 2 => np.ndarray 79 | ans = Calculator.returns(matrix) 80 | self.assertArray(ans) 81 | self.assertEqual(ans, sol_matrix, 5) 82 | # Input is pandas.Series => pd.Series 83 | ans = Calculator.returns(ser) 84 | self.assertSeries(ans) 85 | sol = pd.Series(sol_array_1, index=ser.index, name='TEST returns') 86 | self.assertEqual(ans, sol) 87 | # Input is pandas.DataFrame with col parameter => pd.Series 88 | ans = Calculator.returns(df, col='c1') 89 | self.assertSeries(ans) 90 | sol = pd.Series(sol_array_1, index=df.index, name='c1 returns') 91 | self.assertEqual(ans, sol) 92 | # -- 93 | ans = Calculator.returns(df, col='c2') 94 | self.assertSeries(ans) 95 | sol = pd.Series(sol_array_2, index=df.index, name='c2 returns') 96 | self.assertEqual(ans, sol) 97 | # Test: Input is pandas.DataFrame without col parameter => pd.DataFrame 98 | ans = Calculator.returns(df) 99 | sol = pd.DataFrame(sol_matrix, index=df.index, columns=df.columns) 100 | self.assertEqual(ans, sol) 101 | 102 | def test_sharpe_ratio(self): 103 | array = np.array([1,1.5,3,4,4.3]) 104 | array_2 = np.array([5,4.3,3,3.5,1]) 105 | matrix = np.array([array, array_2]).T 106 | series = pd.Series(array) 107 | time_series = pd.Series(array_2) 108 | df = pd.DataFrame(matrix, columns=['c1', 'c2']) 109 | 110 | # Input is np.array of 1 dimmension => float 111 | ans = Calculator.sharpe_ratio(array) 112 | self.assertFloat(ans) 113 | self.assertAlmostEquals(ans, 2.38842, 5) 114 | # Input is np.array of 2 dimmensions => array 115 | ans = Calculator.sharpe_ratio(matrix) 116 | self.assertArray(ans) 117 | sol = np.array([2.38842482, -1.4708528]) 118 | self.assertEqual(ans, sol, 5) 119 | # Input is pandas.Series => float 120 | ans = Calculator.sharpe_ratio(series) 121 | self.assertFloat(ans) 122 | self.assertAlmostEquals(ans, 2.38842, 5) 123 | # Input is pandas.TimeSeries => float 124 | ans = Calculator.sharpe_ratio(time_series) 125 | self.assertFloat(ans) 126 | self.assertAlmostEquals(ans, -1.4708528, 5) 127 | # Input is pandas.DataFrame with col parameter => float 128 | ans = Calculator.sharpe_ratio(df, col='c1') 129 | self.assertFloat(ans) 130 | self.assertAlmostEquals(ans, 2.38842, 5) 131 | # -- 132 | ans = Calculator.sharpe_ratio(df, col='c2') 133 | self.assertFloat(ans) 134 | self.assertAlmostEqual(ans, -1.4708528, 5) 135 | # Input is pandas.DataFrame without col parameter => pd.Series 136 | ans = Calculator.sharpe_ratio(df) 137 | self.assertSeries(ans) 138 | sol = pd.Series([2.38842482, -1.4708528], index=['c1', 'c2'], name='Sharpe Ratios') 139 | self.assertEqual(ans, sol) 140 | 141 | 142 | if __name__ == '__main__': 143 | suite = CalculatorTypesTest().suite() 144 | unittest.TextTestRunner(verbosity=2).run(suite) -------------------------------------------------------------------------------- /test/utils/CalculatorValues.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os, inspect 3 | import numpy as np 4 | import pandas as pd 5 | from finance.test import FinanceTest 6 | 7 | from finance.utils import Calculator 8 | 9 | class CalculatorValuesTest(FinanceTest): 10 | ''' 11 | Tests the values of the functions 12 | ''' 13 | 14 | def suite(self): 15 | 16 | suite = unittest.TestSuite() 17 | suite.addTest(CalculatorValuesTest('test_assets')) 18 | suite.addTest(CalculatorValuesTest('test_tvm')) 19 | return suite 20 | 21 | def test_assets(self): 22 | ''' 23 | Tests 24 | ----- 25 | 1. Calculator.returns w/ basedOn=1 cc=False 26 | 2. Calculator.returns w/ basedOn=1 cc=True 27 | 3. Calculator.returns w/ basedOn=2 cc=False 28 | 4. Calculator.returns w/ basedOn=2 cc=True 29 | 5. Calculator.FV w/ R=list ret_list=True 30 | 6. Calculator.PV w/ R=list ret_list=True 31 | ''' 32 | # Load Data 33 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 34 | tests = ['Calculator_Assets_1.csv'] 35 | tests = [os.path.join(self_dir, 'docs', test) for test in tests] 36 | 37 | for test_file in tests: 38 | # Set up 39 | solution = pd.read_csv(test_file).set_index('Date').fillna(value=0) 40 | data = solution['Adj. Close'] 41 | 42 | # Test 1 43 | simple_returns = Calculator.returns(data) 44 | self.assertEqual(solution['Adj. Close returns'], simple_returns) 45 | # Test 2 46 | cc_returns = Calculator.returns(data, cc=True) 47 | self.assertEqual(solution['Adj. Close CC returns'], cc_returns) 48 | # Test 3 49 | simple_returns_2 = Calculator.returns(data, basedOn=2) 50 | self.assertEqual(solution['Adj. Close returns (2)'], simple_returns_2) 51 | # Test 4 52 | cc_returns_2 = Calculator.returns(data, basedOn=2, cc=True) 53 | self.assertEqual(solution['Adj. Close CC returns (2)'], cc_returns_2) 54 | # Test 5 55 | fv = Calculator.FV(PV=1, R=simple_returns, ret_list=True) 56 | self.assertEqual(solution['Future value'], fv) 57 | # Test 6 58 | pv = Calculator.PV(FV=fv[-1], R=simple_returns, ret_list=True) 59 | pv_sol = solution['Future value'] 60 | pv_sol.name = 'Present value' 61 | self.assertEqual(solution['Future value'], pv) 62 | 63 | def test_tvm(self): 64 | ''' 65 | Tests 66 | ----- 67 | 1. FV w/ PV, R, n, m and ret_list=False 68 | 2. PV w/ PV, R, n, m and ret_list=False 69 | 3. R w/ PV, FV, n, m 70 | 4. n w/ PV, FV, R, m 71 | 5. ear w/ R, m 72 | ''' 73 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 74 | tests = ['Calculator_TVM_1.csv', 'Calculator_TVM_2.csv', 75 | 'Calculator_TVM_3.csv'] 76 | tests = [os.path.join(self_dir, 'docs',test) for test in tests] 77 | 78 | for test_file in tests: 79 | # Set up 80 | solution = pd.read_csv(test_file) 81 | 82 | for idx, row in solution.iterrows(): 83 | # Test 1 84 | FV = Calculator.FV(PV=row['PV'], R=row['R'], n=row['n'], m=row['m']) 85 | self.assertAlmostEqual(FV, row['FV'], 4) 86 | # Test 2 87 | PV = Calculator.PV(FV=row['FV'], R=row['R'], n=row['n'], m=row['m']) 88 | self.assertAlmostEqual(PV, row['PV'], 4) 89 | # Test 3 90 | R = Calculator.R(PV=row['PV'], FV=row['FV'], n=row['n'], m=row['m']) 91 | self.assertAlmostEqual(R, row['R'], 4) 92 | # Test 4 93 | n = Calculator.n(PV=row['PV'], FV=row['FV'], R=row['R'], m=row['m']) 94 | self.assertAlmostEqual(n, row['n'], 4) 95 | # Test 5 96 | ear = Calculator.eff_ret(R=row['R'], m=row['m']) 97 | self.assertAlmostEqual(ear, row['EAR'], 4, "R(%s),m(%s)" % (row['R'], row['m'])) 98 | 99 | if __name__ == '__main__': 100 | suite = CalculatorValuesTest().suite() 101 | unittest.TextTestRunner(verbosity=2).run(suite) 102 | -------------------------------------------------------------------------------- /test/utils/DataAccess.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from datetime import datetime 3 | 4 | from finance.test import FinanceTest 5 | from finance.utils import DataAccess 6 | 7 | class DataAccessTest(FinanceTest): 8 | 9 | def suite(self): 10 | suite = unittest.TestSuite() 11 | suite.addTest(DataAccessTest('test_get_data')) 12 | suite.addTest(DataAccessTest('test_save_load_custom_name')) 13 | return suite 14 | 15 | def test_get_data(self): 16 | ''' 17 | Tests the length the data frame 18 | Tets the number of columns and their names 19 | 20 | Note 1: File downloads are managed by finance.utils.FileManager 21 | Test for that on FileManagerTest.py 22 | Note 2: Other tests were done on the benchmark 23 | ''' 24 | self.setUpDataAccess() 25 | 26 | start_date = datetime(2015, 1, 1) 27 | end_date = datetime(2017, 12, 31) 28 | 29 | # Single symbol, single field 30 | symbols = "AAPL" 31 | fields = 'close' 32 | df = self.data_access.get_data(symbols, start_date, end_date, fields) 33 | self.assertEqual(len(df), 755) 34 | self.assertEqual(len(df.columns), 1) 35 | names = [fields] 36 | self.assertEqual(list(df.columns), names) 37 | 38 | # Multiple symbols, single field 39 | symbols = ["AAPL","GLD","GOOG","SPY","XOM"] 40 | fields = 'close' 41 | df = self.data_access.get_data(symbols, start_date, end_date, fields) 42 | self.assertEqual(len(df), 755) 43 | self.assertEqual(len(df.columns), 5) 44 | names = symbols 45 | self.assertEqual(list(df.columns), names) 46 | 47 | # Single symbol, multiple fields 48 | symbols = "AAPL" 49 | fields = ['close', 'volume'] 50 | df = self.data_access.get_data(symbols, start_date, end_date, fields) 51 | self.assertEqual(len(df), 755) 52 | self.assertEqual(len(df.columns), 2) 53 | names = ['close', 'volume'] 54 | self.assertEqual(list(df.columns), names) 55 | 56 | # Multiple symbol, multiple fields 57 | symbols = ["AAPL","GLD","GOOG","SPY","XOM"] 58 | fields = ['close', 'volume'] 59 | df = self.data_access.get_data(symbols, start_date, end_date, fields) 60 | self.assertEqual(len(df), 755) 61 | self.assertEqual(len(df.columns), 10) 62 | names = ['AAPL close', 'AAPL volume', 'GLD close', 'GLD volume', 'GOOG close', 63 | 'GOOG volume', 'SPY close', 'SPY volume', 'XOM close', 'XOM volume'] 64 | self.assertEqual(list(df.columns), names) 65 | 66 | def test_save_load_custom_name(self): 67 | self.setUpDataAccess() 68 | 69 | symbols = ["AAPL", "GLD", "GOOG", "SPY", "XOM"] 70 | start_date = datetime(2015, 1, 1) 71 | end_date = datetime(2017, 12, 31) 72 | fields = 'close' 73 | 74 | close = self.data_access.get_data(symbols, start_date, end_date, fields, save=False) 75 | self.data_access.save(close, "customName", extension='.custom') 76 | 77 | close_loaded = self.data_access.load("customName", extension='.custom') 78 | 79 | self.assertEqual(list(close.columns), list(close_loaded.columns)) 80 | self.assertEqual(len(close), len(close_loaded)) 81 | 82 | 83 | def benchmark(): 84 | from time import clock, time 85 | da = DataAccess('./data') 86 | da.empty_dirs(delete=False) 87 | 88 | print ('Directory empty: Download and save 5 stocks') 89 | t1, t2 = clock(), time() 90 | symbols = ["AAPL","GLD","GOOG","SPY","XOM"] 91 | start_date = datetime(2015, 1, 1) 92 | end_date = datetime(2017, 12, 31) 93 | fields = 'close' 94 | da.get_data(symbols, start_date, end_date, fields) 95 | t1_f, t2_f = clock(), time() 96 | print (" ", t1_f - t1, t2_f - t2) 97 | 98 | print ('Load 5 stocks from .csv') 99 | t1, t2 = clock(), time() 100 | symbols = ["AAPL","GLD","GOOG","SPY","XOM"] 101 | start_date = datetime(2015, 1, 1) 102 | end_date = datetime(2017, 12, 31) 103 | fields = 'close' 104 | da.get_data(symbols, start_date, end_date, fields, useCache=False) 105 | t1_f, t2_f = clock(), time() 106 | print (" ", t1_f - t1, t2_f - t2) 107 | 108 | print ('Load 5 stocks from serialized') 109 | t1, t2 = clock(), time() 110 | symbols = ["AAPL","GLD","GOOG","SPY","XOM"] 111 | start_date = datetime(2015, 1, 1) 112 | end_date = datetime(2017, 12, 31) 113 | fields = 'close' 114 | da.get_data(symbols, start_date, end_date, fields, useCache=True) 115 | t1_f, t2_f = clock(), time() 116 | print (" ", t1_f - t1, t2_f - t2) 117 | 118 | if __name__ == '__main__': 119 | suite = DataAccessTest().suite() 120 | unittest.TextTestRunner(verbosity=2).run(suite) 121 | 122 | # benchmark() 123 | FinanceTest.delete_data() 124 | -------------------------------------------------------------------------------- /test/utils/DateUtils.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import pandas as pd 3 | from datetime import datetime 4 | 5 | from finance.test import FinanceTest 6 | from finance.utils import DateUtils 7 | 8 | class DateUtilsTest(FinanceTest): 9 | 10 | def suite(self): 11 | suite = unittest.TestSuite() 12 | suite.addTest(DateUtilsTest('nyse_dates_basic')) 13 | suite.addTest(DateUtilsTest('nyse_dates_advanced')) 14 | suite.addTest(DateUtilsTest('nyse_dates_event')) 15 | suite.addTest(DateUtilsTest('nyse_add_and_substract')) 16 | return suite 17 | 18 | def nyse_dates_basic(self): 19 | ''' 20 | Tests the dates without the lookBack and lookForward parameters 21 | ''' 22 | # We assume this works: because sometime today is not and open day 23 | today = datetime(datetime.today().year, datetime.today().month, datetime.today().day) 24 | dates = DateUtils.nyse_dates() 25 | today = DateUtils.search_closer_date(today, dates) 26 | today = dates[today] 27 | # End of assumssion 28 | 29 | # Test: Returns a list 30 | dates = DateUtils.nyse_dates() 31 | self.assertEquals(type(dates), list) 32 | # Test: Returns a pd.Series if requested 33 | dates = DateUtils.nyse_dates(series=True) 34 | self.assertEquals(type(dates), pd.Series) 35 | 36 | # Test: Default startdate is 2007-1-1 37 | dates = DateUtils.nyse_dates() 38 | ans = dates[0] 39 | self.assertEquals(ans, datetime(2007,1,3)) 40 | # Test: Default enddate is today 41 | ans = dates[-1] 42 | self.assertEquals(ans, today) 43 | 44 | # Test: Values: start date after 2007-1-1 45 | start = datetime(2008, 1, 1) 46 | # Test: returns list 47 | dates = DateUtils.nyse_dates(start=start) 48 | self.assertEquals(type(dates), list) 49 | self.assertEquals(dates[0], datetime(2008, 1, 2)) 50 | self.assertEquals(dates[-1], today) 51 | # Test: returns pd.Series 52 | dates = DateUtils.nyse_dates(start=start, series=True) 53 | self.assertEquals(type(dates), pd.Series) 54 | self.assertEquals(dates[0], datetime(2008, 1, 2)) 55 | self.assertEquals(dates[-1], today) 56 | 57 | # Test: Values: start date before 2007-1-1 58 | start = datetime(1995, 1, 1) 59 | # Test: with list 60 | dates = DateUtils.nyse_dates(start=start) 61 | self.assertEquals(type(dates), list) 62 | self.assertEquals(dates[0], datetime(1995, 1, 3)) 63 | self.assertEquals(dates[-1], today) 64 | # Test: with pd.Series 65 | dates = DateUtils.nyse_dates(start=start, series=True) 66 | self.assertEquals(type(dates), pd.Series) 67 | self.assertEquals(dates[0], datetime(1995, 1, 3)) 68 | self.assertEquals(dates[-1], today) 69 | 70 | # Test: end date after 2007-1-1 71 | end = datetime(2009, 6, 6) 72 | dates = DateUtils.nyse_dates(end=end) 73 | self.assertEquals(type(dates), list) 74 | self.assertEquals(dates[0], datetime(2007, 1, 3)) 75 | self.assertEquals(dates[-1], datetime(2009, 6, 5)) 76 | 77 | # Test: end date before 2007-1-1 78 | end = datetime(2005, 6, 6) 79 | dates = DateUtils.nyse_dates(end=end) 80 | self.assertEquals(type(dates), list) 81 | self.assertEquals(dates[0], datetime(1962, 7, 5)) 82 | self.assertEquals(dates[-1], datetime(2005, 6, 6)) 83 | 84 | # Test: Values and lenght between 2 dates - No. 1 85 | start = datetime(2000, 1, 1) 86 | end = datetime(2002, 1, 1) 87 | # Test: with list 88 | dates = DateUtils.nyse_dates(start=start, end=end) 89 | self.assertEquals(type(dates), list) 90 | self.assertEquals(dates[0], datetime(2000, 1, 3)) 91 | self.assertEquals(dates[-1], datetime(2001, 12, 31)) 92 | self.assertEquals(len(dates), 500) 93 | # Test: with pd.Series 94 | dates = DateUtils.nyse_dates(start=start, end=end, series=True) 95 | self.assertEquals(type(dates), pd.Series) 96 | self.assertEquals(dates[0], datetime(2000, 1, 3)) 97 | self.assertEquals(dates[-1], datetime(2001, 12, 31)) 98 | self.assertEquals(len(dates), 500) 99 | 100 | # Test: Values and lenght between 2 dates - No. 2 101 | start = datetime(2009, 1, 1) 102 | end = datetime(2011, 1, 1) 103 | # Test: Lenght: Section - list 104 | dates = DateUtils.nyse_dates(start=start, end=end) 105 | self.assertEquals(type(dates), list) 106 | self.assertEquals(dates[0], datetime(2009, 1, 2)) 107 | self.assertEquals(dates[-1], datetime(2010, 12, 31)) 108 | self.assertEquals(len(dates), 504) 109 | # Test: Lenght: Section - pd.Series 110 | dates = DateUtils.nyse_dates(start=start, end=end, series=True) 111 | self.assertEquals(type(dates), pd.Series) 112 | self.assertEquals(dates[0], datetime(2009, 1, 2)) 113 | self.assertEquals(dates[-1], datetime(2010, 12, 31)) 114 | self.assertEquals(len(dates), 504) 115 | 116 | def nyse_dates_advanced(self): 117 | ''' 118 | Tests the dates between two dates with the lookBack and lookForward parameters 119 | ''' 120 | # Test: with lookbackDays without lookforwardDays 121 | start = datetime(2009, 1, 1) 122 | end = datetime(2011, 1, 1) 123 | dates = DateUtils.nyse_dates(start=start, end=end, 124 | lookbackDays=10, lookforwardDays=0) 125 | self.assertEquals(dates[0], datetime(2008, 12, 17)) 126 | self.assertEquals(dates[-1], datetime(2010, 12, 31)) 127 | 128 | # Test: without lookbackDays with lookforwardDays 129 | start = datetime(2009, 1, 1) 130 | end = datetime(2011, 1, 1) 131 | dates = DateUtils.nyse_dates(start=start, end=end, 132 | lookbackDays=0, lookforwardDays=10) 133 | self.assertEquals(dates[0], datetime(2009, 1, 2)) 134 | self.assertEquals(dates[-1], datetime(2011, 1, 14)) 135 | 136 | # Test: with lookbackDays with lookforwardDays 137 | start = datetime(2009, 1, 1) 138 | end = datetime(2011, 1, 1) 139 | dates = DateUtils.nyse_dates(start=start, end=end, 140 | lookbackDays=10, lookforwardDays=10) 141 | self.assertEquals(dates[0], datetime(2008, 12, 17)) 142 | self.assertEquals(dates[-1], datetime(2011, 1, 14)) 143 | 144 | def nyse_dates_event(self): 145 | dates = DateUtils.nyse_dates_event(datetime(2009, 1, 5), 10, 10, 250) 146 | self.assertEquals(dates[0], datetime(2007, 12, 21)) 147 | self.assertEquals(dates[-1], datetime(2009, 1, 20)) 148 | self.assertEquals(len(dates), 271) 149 | 150 | def nyse_add_and_substract(self): 151 | ans = DateUtils.nyse_add(datetime(2009, 4, 13), 5) 152 | self.assertEquals(ans, datetime(2009, 4, 20)) 153 | 154 | ans = DateUtils.nyse_substract(datetime(2009, 4, 13), 5) 155 | self.assertEquals(ans, datetime(2009, 4, 3)) 156 | 157 | ans = DateUtils.nyse_add(datetime(1990, 10, 1), 7) 158 | self.assertEquals(ans, datetime(1990, 10, 10)) 159 | 160 | ans = DateUtils.nyse_substract(datetime(1990, 10, 1), 3) 161 | self.assertEquals(ans, datetime(1990, 9, 26)) 162 | 163 | if __name__ == '__main__': 164 | suite = DateUtilsTest().suite() 165 | unittest.TextTestRunner(verbosity=2).run(suite) -------------------------------------------------------------------------------- /test/utils/FileManager.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from datetime import datetime 3 | 4 | from finance.test import FinanceTest 5 | from finance.utils import FileManager 6 | 7 | class FileManagerTest(FinanceTest): 8 | 9 | def setUp1(self): 10 | self.file_manager = FileManager('./data') 11 | self.file_manager.empty_dir(delete=False) 12 | 13 | def suite(self): 14 | suite = unittest.TestSuite() 15 | suite.addTest(FileManagerTest('test_get_filenames')) 16 | return suite 17 | 18 | def test_get_filenames(self): 19 | ''' 20 | Mainly tets the name of the files, more test on testExists() 21 | ''' 22 | self.setUp1() 23 | symbols = ["AAPL","GLD","GOOG","SPY","XOM"] 24 | 25 | # Test: return empty list on missing file and downloadMissing=False 26 | start_date = datetime(2008, 1, 1) 27 | end_date = datetime(2009, 12, 31) 28 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=False) 29 | self.assertEqual(ans, []) 30 | 31 | # Test: return None on missing file and downloadMissing=False and ignoreMissing=False 32 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=False, ignoreMissing=False) 33 | self.assertEqual(ans, None) 34 | 35 | # Test: Download file and test name 36 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=True) 37 | self.assertEqual(ans, "AAPL_2008-1-1_2009-12-31.csv") 38 | 39 | # Test: Smaller start date: don't download un-necessary information 40 | start_date = datetime(2008, 6, 6) # Smaller 41 | end_date = datetime(2009, 12, 31) 42 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=True) 43 | self.assertEqual(ans, "AAPL_2008-1-1_2009-12-31.csv") 44 | 45 | # Test: Smaller end date: don't download un-necessary files 46 | start_date = datetime(2008, 1, 1) 47 | end_date = datetime(2009, 6, 6) # Smaller 48 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=True) 49 | self.assertEqual(ans, "AAPL_2008-1-1_2009-12-31.csv") 50 | 51 | # Test: Bigger start date: download another file 52 | start_date = datetime(2007, 1, 1) # Bigger 53 | end_date = datetime(2009, 6, 6) # Smaller 54 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=True) 55 | self.assertEqual(ans, "AAPL_2007-1-1_2009-6-6.csv") 56 | 57 | # Test: Bigger end date: download another file 58 | start_date = datetime(2007, 1, 1) # Bigger 59 | end_date = datetime(2010, 6, 6) # Smaller 60 | ans = self.file_manager.get_filenames(symbols[0], start_date, end_date, downloadMissing=True) 61 | self.assertEqual(ans, "AAPL_2007-1-1_2010-6-6.csv") 62 | 63 | # Test: Download multiple files 64 | start_date = datetime(2015, 1, 1) 65 | end_date = datetime(2017, 1, 1) 66 | ans = self.file_manager.get_filenames(symbols, start_date, end_date, downloadMissing=True) 67 | sol = ["AAPL_2015-1-1_2017-1-1.csv", "GLD_2015-1-1_2017-1-1.csv", 68 | "GOOG_2015-1-1_2017-1-1.csv", "SPY_2015-1-1_2017-1-1.csv", 69 | "XOM_2015-1-1_2017-1-1.csv"] 70 | self.assertEqual(ans, sol) 71 | 72 | # Test: do not return missing filenames 73 | symbols = ["AAPL","FAKE1","GLD","FAKE1","GOOG","SPY","XOM","FAKE1"] 74 | ans = self.file_manager.get_filenames(symbols, start_date, end_date, downloadMissing=True) 75 | sol = ["AAPL_2015-1-1_2017-1-1.csv", "GLD_2015-1-1_2017-1-1.csv", 76 | "GOOG_2015-1-1_2017-1-1.csv", "SPY_2015-1-1_2017-1-1.csv", 77 | "XOM_2015-1-1_2017-1-1.csv"] 78 | self.assertEqual(ans, sol) 79 | 80 | # Test: Return missing filenames if requested 81 | symbols = ["AAPL","FAKE1","GLD","FAKE1","GOOG","SPY","XOM","FAKE1"] 82 | ans = self.file_manager.get_filenames(symbols, start_date, end_date, downloadMissing=True, ignoreMissing=False) 83 | sol = ["AAPL_2015-1-1_2017-1-1.csv", None, "GLD_2015-1-1_2017-1-1.csv", 84 | None, "GOOG_2015-1-1_2017-1-1.csv", "SPY_2015-1-1_2017-1-1.csv", 85 | "XOM_2015-1-1_2017-1-1.csv", None] 86 | self.assertEqual(ans, sol) 87 | 88 | if __name__ == '__main__': 89 | suite = FileManagerTest().suite() 90 | unittest.TextTestRunner(verbosity=2).run(suite) 91 | 92 | FinanceTest.delete_data() 93 | -------------------------------------------------------------------------------- /test/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/utils/__init__.py -------------------------------------------------------------------------------- /test/utils/docs/Calculator_Assets.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/utils/docs/Calculator_Assets.ods -------------------------------------------------------------------------------- /test/utils/docs/Calculator_Assets_1.csv: -------------------------------------------------------------------------------- 1 | Date,Adj. Close,log price,Adj. Close returns,Adj. Close CC returns,Adj. Close returns (2),Adj. Close CC returns (2),Future value 2 | Jul-92,1.66,0.5068176024,,,,,1.000000000000 3 | Aug-92,1.55,0.4382549309,-0.066265060241,-0.068562671437,,,0.933734939759 4 | Sep-92,1.89,0.6365768291,0.219354838710,0.198321898140,0.138554216867,0.129759226703,1.138554216867 5 | Oct-92,1.84,0.6097655716,-0.026455026455,-0.026811257451,0.187096774194,0.171510640690,1.108433734940 6 | Nov-92,2.36,0.858661619,0.282608695652,0.248896047417,0.248677248677,0.222084789966,1.421686746988 7 | Dec-92,2.31,0.8372475245,-0.021186440678,-0.021414094504,0.255434782609,0.227481952913,1.391566265060 8 | Jan-93,2.41,0.8796267475,0.043290043290,0.042379222969,0.021186440678,0.020965128465,1.451807228916 9 | Feb-93,2.27,0.8197798315,-0.058091286307,-0.059846916009,-0.017316017316,-0.017467693040,1.367469879518 10 | Mar-93,2.38,0.8671004877,0.048458149780,0.047320656190,-0.012448132780,-0.012526259819,1.433734939759 11 | Apr-93,2.42,0.8837675402,0.016806722689,0.016667052485,0.066079295154,0.063987708675,1.457831325301 12 | May-93,3,1.0986122887,0.239669421488,0.214844748500,0.260504201681,0.231511800985,1.807228915663 13 | Jun-93,3.06,1.118414916,0.020000000000,0.019802627296,0.264462809917,0.234647375796,1.843373493976 14 | Jul-93,2.97,1.0885619528,-0.029411764706,-0.029852963150,-0.010000000000,-0.010050335854,1.789156626506 15 | Aug-93,3.03,1.1085626195,0.020202020202,0.020000666707,-0.009803921569,-0.009852296443,1.825301204819 16 | Sep-93,3.42,1.2296405511,0.128712871287,0.121077931553,0.151515151515,0.141078598260,2.060240963855 17 | Oct-93,3.34,1.205970807,-0.023391812865,-0.023669744086,0.102310231023,0.097408187467,2.012048192771 18 | Nov-93,2.78,1.0224509277,-0.167664670659,-0.183519879286,-0.187134502924,-0.207189623372,1.674698795181 19 | Dec-93,2.78,1.0224509277,0.000000000000,0.000000000000,-0.167664670659,-0.183519879286,1.674698795181 20 | Jan-94,3,1.0986122887,0.079136690647,0.076161360966,0.079136690647,0.076161360966,1.807228915663 21 | Feb-94,2.91,1.0681530812,-0.030000000000,-0.030459207485,0.046762589928,0.045702153481,1.753012048193 22 | Mar-94,3.05,1.1151415906,0.048109965636,0.046988509436,0.016666666667,0.016529301951,1.837349397590 23 | Apr-94,3.72,1.3137236683,0.219672131148,0.198582077666,0.278350515464,0.245570587102,2.240963855422 24 | May-94,3.56,1.2697605449,-0.043010752688,-0.043963123421,0.167213114754,0.154618954245,2.144578313253 25 | Jun-94,3.16,1.1505720276,-0.112359550562,-0.119188517265,-0.150537634409,-0.163151640686,1.903614457831 26 | Jul-94,3.62,1.2864740258,0.145569620253,0.135901998239,0.016853932584,0.016713480974,2.180722891566 27 | Aug-94,3.53,1.2612978709,-0.024861878453,-0.025176154892,0.117088607595,0.110725843346,2.126506024096 28 | Sep-94,2.88,1.0577902941,-0.184135977337,-0.203507576797,-0.204419889503,-0.228683731690,1.734939759036 29 | Oct-94,3.39,1.2208299214,0.177083333333,0.163039627245,-0.039660056657,-0.040467949553,2.042168674699 30 | Nov-94,3.35,1.2089603458,-0.011799410029,-0.011869575555,0.163194444444,0.151170051689,2.018072289157 31 | Dec-94,3.44,1.2354714714,0.026865671642,0.026511125548,0.014749262537,0.014641549993,2.072289156627 32 | Jan-95,3,1.0986122887,-0.127906976744,-0.136859182717,-0.104477611940,-0.110348057169,1.807228915663 33 | Feb-95,2.98,1.0919233005,-0.006666666667,-0.006688988151,-0.133720930233,-0.143548170868,1.795180722892 34 | Mar-95,3,1.0986122887,0.006711409396,0.006688988151,0.000000000000,0.000000000000,1.807228915663 35 | Apr-95,2.94,1.0784095814,-0.020000000000,-0.020202707318,-0.013422818792,-0.013513719167,1.771084337349 36 | May-95,3.63,1.2892326483,0.234693877551,0.210823066926,0.210000000000,0.190620359609,2.186746987952 37 | Jun-95,4.45,1.4929040962,0.225895316804,0.203671447901,0.513605442177,0.414494514828,2.680722891566 38 | Jul-95,4.67,1.5411590717,0.049438202247,0.048254975503,0.286501377410,0.251926423404,2.813253012048 39 | Aug-95,5,1.6094379124,0.070663811563,0.068278840753,0.123595505618,0.116533816256,3.012048192771 40 | Sep-95,4.74,1.5560371357,-0.052000000000,-0.053400776727,0.014989293362,0.014878064026,2.855421686747 41 | Oct-95,4.91,1.5912739418,0.035864978903,0.035236806099,-0.018000000000,-0.018163970628,2.957831325301 42 | Nov-95,5.28,1.6639260977,0.075356415479,0.072652155912,0.113924050633,0.107888962011,3.180722891566 43 | Dec-95,5.25,1.6582280766,-0.005681818182,-0.005698021115,0.069246435845,0.066954134797,3.162650602410 44 | Jan-96,4.19,1.4327007339,-0.201904761905,-0.225527342669,-0.206439393939,-0.231225363784,2.524096385542 45 | Feb-96,4.41,1.4838746895,0.052505966587,0.051173955525,-0.160000000000,-0.174353387145,2.656626506024 46 | Mar-96,5.83,1.7630170004,0.321995464853,0.279142310904,0.391408114558,0.330316266428,3.512048192771 47 | Apr-96,6.78,1.913977102,0.162950257290,0.150960101590,0.537414965986,0.430102412494,4.084337349398 48 | May-96,6.78,1.913977102,0.000000000000,0.000000000000,0.162950257290,0.150960101590,4.084337349398 49 | Jun-96,7.06,1.9544450515,0.041297935103,0.040467949553,0.041297935103,0.040467949553,4.253012048193 50 | Jul-96,6.5,1.8718021769,-0.079320113314,-0.082642874604,-0.041297935103,-0.042174925051,3.915662650602 51 | Aug-96,8.19,2.1029138979,0.260000000000,0.231111720963,0.160056657224,0.148468846360,4.933734939759 52 | Sep-96,8.25,2.1102132003,0.007326007326,0.007299302482,0.269230769231,0.238411023445,4.969879518072 53 | Oct-96,8.12,2.0943301542,-0.015757575758,-0.015883046173,-0.008547008547,-0.008583743691,4.891566265060 54 | Nov-96,8.66,2.1587147226,0.066502463054,0.064384568401,0.049696969697,0.048501522228,5.216867469880 55 | Dec-96,7.16,1.968509981,-0.173210161663,-0.190204741602,-0.118226600985,-0.125820173201,4.313253012048 56 | Jan-97,8.56,2.1471001902,0.195530726257,0.178590209181,-0.011547344111,-0.011614532421,5.156626506024 57 | Feb-97,8.41,2.129421474,-0.017523364486,-0.017678716169,0.174581005587,0.160911493012,5.066265060241 58 | Mar-97,7.41,2.0028304393,-0.118906064209,-0.126591034677,-0.134345794393,-0.144269750846,4.463855421687 59 | Apr-97,7.47,2.0108949991,0.008097165992,0.008064559837,-0.111771700357,-0.118526474840,4.500000000000 60 | May-97,7.88,2.0643279039,0.054886211513,0.053432904725,0.063427800270,0.061497464562,4.746987951807 61 | Jun-97,9.73,2.2752138962,0.234771573604,0.210885992328,0.302543507363,0.264318897053,5.861445783133 62 | Jul-97,10.23,2.32532458,0.051387461459,0.050110683766,0.298223350254,0.260996676094,6.162650602410 63 | Aug-97,10.25,2.3272777056,0.001955034213,0.001953125621,0.053442959918,0.052063809387,6.174698795181 64 | Sep-97,10.45,2.3466019784,0.019512195122,0.019324272826,0.021505376344,0.021277398447,6.295180722892 65 | Oct-97,8.25,2.1102132003,-0.210526315789,-0.236388778064,-0.195121951220,-0.217064505238,4.969879518072 66 | Nov-97,8.72,2.1656192379,0.056969696970,0.055406037574,-0.165550239234,-0.180982740490,5.253012048193 67 | Dec-97,9.6,2.2617630985,0.100917431193,0.096143860553,0.163636363636,0.151549898127,5.783132530120 68 | Jan-98,9.14,2.2126603855,-0.047916666667,-0.049102713008,0.048165137615,0.047041147545,5.506024096386 69 | Feb-98,9.89,2.2915241456,0.082056892779,0.078863760169,0.030208333333,0.029761047161,5.957831325301 70 | Mar-98,11.33,2.427454075,0.145601617796,0.135929929405,0.239606126915,0.214793689574,6.825301204819 71 | Apr-98,12.03,2.48740353,0.061782877317,0.059949454947,0.216380182002,0.195879384352,7.246987951807 72 | May-98,12,2.4849066498,-0.002493765586,-0.002496880199,0.059135039718,0.057452574748,7.228915662651 73 | Jun-98,13.36,2.5922651681,0.113333333333,0.107358518321,0.110556940981,0.104861638122,8.048192771084 74 | Jul-98,10.47,2.3485140249,-0.216317365269,-0.243751143226,-0.127500000000,-0.136392624906,6.307228915663 75 | Aug-98,7.89,2.0655961349,-0.246418338109,-0.282917890025,-0.409431137725,-0.526669033251,4.753012048193 76 | Sep-98,9.05,2.2027647577,0.147021546261,0.137168622854,-0.135625596944,-0.145749267171,5.451807228916 77 | Oct-98,10.85,2.38416508,0.198895027624,0.181400322275,0.375158428390,0.318568945129,6.536144578313 78 | Nov-98,11.53,2.4449523343,0.062672811060,0.060787254294,0.274033149171,0.242187576569,6.945783132530 79 | Dec-98,14.03,2.6411978941,0.216825672160,0.196245559833,0.293087557604,0.257032814128,8.451807228916 80 | Jan-99,13.02,2.5664866368,-0.071988595866,-0.074711257334,0.129228100607,0.121534302499,7.843373493976 81 | Feb-99,13.22,2.5817308344,0.015360983103,0.015244197643,-0.057733428368,-0.059467059691,7.963855421687 82 | Mar-99,14.03,2.6411978941,0.061270801815,0.059467059691,0.077572964670,0.074711257334,8.451807228916 83 | Apr-99,18.47,2.9161477942,0.316464718460,0.274949900097,0.397125567322,0.334416959788,11.126506024096 84 | May-99,18.44,2.9145222181,-0.001624255550,-0.001625576083,0.314326443336,0.273324324014,11.108433734940 85 | Jun-99,18.78,2.9327924738,0.018438177874,0.018270255652,0.016783974012,0.016644679569,11.313253012048 86 | Jul-99,11.62,2.4527277514,-0.381256656017,-0.480064722356,-0.369848156182,-0.461794466705,7.000000000000 87 | Aug-99,11.44,2.437115986,-0.015490533563,-0.015611765472,-0.390841320554,-0.495676487828,6.891566265060 88 | Sep-99,12.39,2.5168896956,0.083041958042,0.079773709689,0.066265060241,0.064161944217,7.463855421687 89 | Oct-99,13.6,2.6100697927,0.097659402744,0.093180097101,0.188811188811,0.172953806790,8.192771084337 90 | Nov-99,13.28,2.586259144,-0.023529411765,-0.023810648694,0.071832122680,0.069369448407,8.000000000000 91 | Dec-99,12.12,2.4948569806,-0.087349397590,-0.091402163407,-0.108823529412,-0.115212812101,7.301204819277 92 | Jan-00,16,2.7725887222,0.320132013201,0.277731741599,0.204819277108,0.186329578191,9.638554216867 93 | Feb-00,17.57,2.8661929022,0.098125000000,0.093604179959,0.449669966997,0.371335921558,10.584337349398 94 | Mar-00,22.41,3.1095072878,0.275469550370,0.243314385614,0.400625000000,0.336918565573,13.500000000000 95 | Apr-00,15.11,2.7153567763,-0.325747434181,-0.394150511528,-0.140011383039,-0.150836125914,9.102409638554 96 | May-00,17,2.8332133441,0.125082726671,0.117856567772,-0.241410084784,-0.276293943757,10.240963855422 97 | Jun-00,19.09,2.9491646377,0.122941176471,0.115951293681,0.263401720715,0.233807861453,11.500000000000 98 | Jul-00,18.75,2.9311937524,-0.017810371922,-0.017970885321,0.102941176471,0.097980408360,11.295180722892 99 | Aug-00,18.32,2.9079933592,-0.022933333333,-0.023200393170,-0.040335254060,-0.041171278492,11.036144578313 100 | Sep-00,20.03,2.9972311497,0.093340611354,0.089237790432,0.068266666667,0.066037397261,12.066265060241 101 | Oct-00,22.34,3.1063787936,0.115327009486,0.109147643963,0.219432314410,0.198385434395,13.457831325301 102 | Nov-00,22.78,3.125882958,0.019695613250,0.019504164378,0.137294058912,0.128651808341,13.722891566265 103 | Dec-00,22.12,3.0964821767,-0.028972783143,-0.029400781365,-0.009847806625,-0.009896616987,13.325301204819 104 | Jan-01,24.97,3.2176751043,0.128842676311,0.121192927638,0.096136962248,0.091792146273,15.042168674699 105 | Feb-01,23.82,3.1705255639,-0.046055266320,-0.047149540365,0.076853526221,0.074043387273,14.349397590362 106 | Mar-01,21.22,3.0549441332,-0.109151973132,-0.115581430741,-0.150180216260,-0.162730971106,12.783132530121 107 | Apr-01,19.35,2.9626924195,-0.088124410933,-0.092251713710,-0.187657430730,-0.207833144451,11.656626506024 108 | May-01,19.52,2.971439581,0.008785529716,0.008747161509,-0.080113100848,-0.083504552201,11.759036144578 109 | Jun-01,23,3.1354942159,0.178278688525,0.164054634944,0.188630490956,0.172801796453,13.855421686747 110 | Jul-01,18.04,2.8925915146,-0.215652173913,-0.242902701295,-0.075819672131,-0.078848066350,10.867469879518 111 | Aug-01,16.87,2.8255368966,-0.064855875831,-0.067054618077,-0.266521739130,-0.309957319371,10.162650602410 112 | Sep-01,14.94,2.7040421797,-0.114404267931,-0.121494716853,-0.171840354767,-0.188549334930,9.000000000000 113 | Oct-01,17.12,2.8402473707,0.145917001339,0.136205191009,0.014819205691,0.014710474156,10.313253012048 114 | Nov-01,17.72,2.8746939452,0.035046728972,0.034446574463,0.186077643909,0.170651765472,10.674698795181 115 | Dec-01,19.05,2.9470671016,0.075056433409,0.072373156396,0.112733644860,0.106819730859,11.475903614458 116 | Jan-02,23.77,3.1684242814,0.247769028871,0.221357179799,0.341422121896,0.293730336195,14.319277108434 117 | Feb-02,23.01,3.135928904,-0.031973075305,-0.032495377325,0.207874015748,0.188861802475,13.861445783133 118 | Mar-02,23.13,3.1411304762,0.005215123859,0.005201572196,-0.026924694994,-0.027293805129,13.933734939759 119 | Apr-02,22.82,3.1276373444,-0.013402507566,-0.013493131809,-0.008257279444,-0.008291559613,13.746987951807 120 | May-02,24.28,3.1896529662,0.063978965819,0.062015621757,0.049718979680,0.048522489948,14.626506024096 121 | Jun-02,24.85,3.2128577525,0.023476112026,0.023204786351,0.088957055215,0.085220408109,14.969879518072 122 | Jul-02,19.63,2.9770590083,-0.210060362173,-0.235798744254,-0.191515650741,-0.212593957903,11.825301204819 123 | Aug-02,20.1,3.0007198151,0.023942944473,0.023660806777,-0.191146881288,-0.212137937478,12.108433734940 124 | Sep-02,20.66,3.0281994637,0.027860696517,0.027479648626,0.052470708100,0.051140455403,12.445783132530 125 | Oct-02,23.84,3.1713648422,0.153920619555,0.143165378506,0.186069651741,0.170645027132,14.361445783133 126 | Nov-02,21.74,3.0791538817,-0.088087248322,-0.092210960504,0.052274927396,0.050954418002,13.096385542169 127 | Dec-02,20.38,3.0145540278,-0.062557497700,-0.064599853898,-0.145134228188,-0.156810814403,12.277108433735 128 | Jan-03,22.72,3.1232455939,0.114818449460,0.108691566058,0.045078196872,0.044091712160,13.686746987952 129 | Feb-03,23.45,3.1548704949,0.032130281690,0.031624901039,0.150637880275,0.140316467098,14.126506024096 130 | Mar-03,25.76,3.2488229012,0.098507462687,0.093952406344,0.133802816901,0.125577307383,15.518072289157 131 | Apr-03,23.51,3.1574258626,-0.087344720497,-0.091397038684,0.002558635394,0.002555367660,14.162650602410 132 | May-03,24.67,3.2055879305,0.049340706083,0.048162067989,-0.042313664596,-0.043234970695,14.861445783133 133 | Jun-03,24.55,3.2007118542,-0.004864207540,-0.004876076301,0.044236495108,0.043285991689,14.789156626506 134 | Jul-03,27.33,3.3079849999,0.113238289206,0.107273145699,0.107823267126,0.102397069399,16.463855421687 135 | Aug-03,28.39,3.3460369705,0.038785217709,0.038051970545,0.156415478615,0.145325116244,17.102409638554 136 | Sep-03,28.8,3.3603753871,0.014441704826,0.014338416657,0.053787047201,0.052390387202,17.349397590362 137 | Oct-03,31.6,3.4531571206,0.097222222222,0.092781733451,0.113067981684,0.107120150108,19.036144578313 138 | Nov-03,32.17,3.4710343413,0.018037974684,0.017877220658,0.117013888889,0.110658954109,19.379518072289 139 | Dec-03,33.16,3.5013443303,0.030774013056,0.030309989016,0.049367088608,0.048187209674,19.975903614458 140 | Jan-04,36.61,3.6003214271,0.104041013269,0.098977096865,0.138016785825,0.129287085881,22.054216867470 141 | Feb-04,37.4,3.6216707044,0.021578803606,0.021349277288,0.127864897467,0.120326374153,22.530120481928 142 | Mar-04,37.87,3.6341592419,0.012566844920,0.012488537493,0.034416826004,0.033837814782,22.813253012048 143 | Apr-04,38.92,3.6615082573,0.027726432532,0.027349015404,0.040641711230,0.039837552897,23.445783132530 144 | May-04,40.6,3.7037680666,0.043165467626,0.042259809290,0.072088724584,0.069608824694,24.457831325301 145 | Jun-04,43.49,3.7725310266,0.071182266010,0.068762960002,0.117420349435,0.111022769292,26.198795180723 146 | Jul-04,46.99,3.8499348131,0.080478270867,0.077403786505,0.157389162562,0.146166746507,28.307228915663 147 | Aug-04,43.24,3.7667659928,-0.079804213662,-0.083168820344,-0.005748447919,-0.005765033839,26.048192771084 148 | Sep-04,45.46,3.8168328184,0.051341350601,0.050066825653,-0.032560119174,-0.033101994690,27.385542168675 149 | -------------------------------------------------------------------------------- /test/utils/docs/Calculator_TVM.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/test/utils/docs/Calculator_TVM.ods -------------------------------------------------------------------------------- /test/utils/docs/Calculator_TVM_1.csv: -------------------------------------------------------------------------------- 1 | PV,R,n,m,R/m,FV,EAR 2 | 1000,0.2,1,1,0.20000,1200.0000,0.200000 3 | 1000,0.2,1,2,0.10000,1210.0000,0.210000 4 | 1000,0.2,1,3,0.06667,1213.6296,0.213630 5 | 1000,0.2,1,4,0.05000,1215.5063,0.215506 6 | 1000,0.2,1,12,0.01667,1219.3911,0.219391 7 | 1000,0.2,1,52,0.00385,1220.9343,0.220934 8 | 1000,0.2,1,365,0.00055,1221.3359,0.221336 9 | 1000,0.2,1,inf,0.00000,1221.4028,0.221403 10 | 1000,0.2,2,1,0.20000,1440.0000,0.200000 11 | 1000,0.2,2,2,0.10000,1464.1000,0.210000 12 | 1000,0.2,2,3,0.06667,1472.8969,0.213630 13 | 1000,0.2,2,4,0.05000,1477.4554,0.215506 14 | 1000,0.2,2,12,0.01667,1486.9146,0.219391 15 | 1000,0.2,2,52,0.00385,1490.6805,0.220934 16 | 1000,0.2,2,365,0.00055,1491.6613,0.221336 17 | 1000,0.2,2,inf,0.00000,1491.8247,0.221403 18 | 1000,0.2,3,1,0.20000,1728.0000,0.200000 19 | 1000,0.2,3,2,0.10000,1771.5610,0.210000 20 | 1000,0.2,3,3,0.06667,1787.5513,0.213630 21 | 1000,0.2,3,4,0.05000,1795.8563,0.215506 22 | 1000,0.2,3,12,0.01667,1813.1304,0.219391 23 | 1000,0.2,3,52,0.00385,1820.0229,0.220934 24 | 1000,0.2,3,365,0.00055,1821.8194,0.221336 25 | 1000,0.2,3,inf,0.00000,1822.1188,0.221403 26 | 1000,0.2,4,1,0.20000,2073.6000,0.200000 27 | 1000,0.2,4,2,0.10000,2143.5888,0.210000 28 | 1000,0.2,4,3,0.06667,2169.4252,0.213630 29 | 1000,0.2,4,4,0.05000,2182.8746,0.215506 30 | 1000,0.2,4,12,0.01667,2210.9151,0.219391 31 | 1000,0.2,4,52,0.00385,2222.1284,0.220934 32 | 1000,0.2,4,365,0.00055,2225.0534,0.221336 33 | 1000,0.2,4,inf,0.00000,2225.5409,0.221403 34 | 1000,0.2,10,1,0.20000,6191.7364,0.200000 35 | 1000,0.2,10,2,0.10000,6727.4999,0.210000 36 | 1000,0.2,10,3,0.06667,6932.0503,0.213630 37 | 1000,0.2,10,4,0.05000,7039.9887,0.215506 38 | 1000,0.2,10,12,0.01667,7268.2550,0.219391 39 | 1000,0.2,10,52,0.00385,7360.7636,0.220934 40 | 1000,0.2,10,365,0.00055,7385.0099,0.221336 41 | 1000,0.2,10,inf,0.00000,7389.0561,0.221403 42 | 1000,0.2,22,1,0.20000,55206.1439,0.200000 43 | 1000,0.2,22,2,0.10000,66264.0761,0.210000 44 | 1000,0.2,22,3,0.06667,70777.5879,0.213630 45 | 1000,0.2,22,4,0.05000,73224.8209,0.215506 46 | 1000,0.2,22,12,0.01667,78550.0275,0.219391 47 | 1000,0.2,22,52,0.00385,80766.3239,0.220934 48 | 1000,0.2,22,365,0.00055,81352.7763,0.221336 49 | 1000,0.2,22,inf,0.00000,81450.8687,0.221403 50 | 1000,0.2,35,1,0.20000,590668.2292,0.200000 51 | 1000,0.2,35,2,0.10000,789746.9568,0.210000 52 | 1000,0.2,35,3,0.06667,877033.0873,0.213630 53 | 1000,0.2,35,4,0.05000,925767.3709,0.215506 54 | 1000,0.2,35,12,0.01667,1035155.3795,0.219391 55 | 1000,0.2,35,52,0.00385,1082006.9461,0.220934 56 | 1000,0.2,35,365,0.00055,1094532.8082,0.221336 57 | 1000,0.2,35,inf,0.00000,1096633.1584,0.221403 58 | 1000,0.2,47,1,0.20000,5266457.2627,0.200000 59 | 1000,0.2,47,2,0.10000,7778796.4060,0.210000 60 | 1000,0.2,47,3,0.06667,8954679.1114,0.213630 61 | 1000,0.2,47,4,0.05000,9629156.0547,0.215506 62 | 1000,0.2,47,12,0.01667,11187208.4341,0.219391 63 | 1000,0.2,47,52,0.00385,11872371.9473,0.220934 64 | 1000,0.2,47,365,0.00055,12057300.4014,0.221336 65 | 1000,0.2,47,inf,0.00000,12088380.7302,0.221403 66 | -------------------------------------------------------------------------------- /test/utils/docs/Calculator_TVM_2.csv: -------------------------------------------------------------------------------- 1 | PV,R,n,m,R/m,FV,EAR 2 | 2000,0.2,1,1,0.20000,2400.0000,0.200000 3 | 2000,0.2,1,2,0.10000,2420.0000,0.210000 4 | 2000,0.2,1,3,0.06667,2427.2593,0.213630 5 | 2000,0.2,1,4,0.05000,2431.0125,0.215506 6 | 2000,0.2,1,12,0.01667,2438.7822,0.219391 7 | 2000,0.2,1,52,0.00385,2441.8686,0.220934 8 | 2000,0.2,1,365,0.00055,2442.6717,0.221336 9 | 2000,0.2,1,inf,0.00000,2442.8055,0.221403 10 | 2000,0.2,2,1,0.20000,2880.0000,0.200000 11 | 2000,0.2,2,2,0.10000,2928.2000,0.210000 12 | 2000,0.2,2,3,0.06667,2945.7938,0.213630 13 | 2000,0.2,2,4,0.05000,2954.9109,0.215506 14 | 2000,0.2,2,12,0.01667,2973.8292,0.219391 15 | 2000,0.2,2,52,0.00385,2981.3610,0.220934 16 | 2000,0.2,2,365,0.00055,2983.3226,0.221336 17 | 2000,0.2,2,inf,0.00000,2983.6494,0.221403 18 | 2000,0.2,3,1,0.20000,3456.0000,0.200000 19 | 2000,0.2,3,2,0.10000,3543.1220,0.210000 20 | 2000,0.2,3,3,0.06667,3575.1026,0.213630 21 | 2000,0.2,3,4,0.05000,3591.7127,0.215506 22 | 2000,0.2,3,12,0.01667,3626.2609,0.219391 23 | 2000,0.2,3,52,0.00385,3640.0459,0.220934 24 | 2000,0.2,3,365,0.00055,3643.6388,0.221336 25 | 2000,0.2,3,inf,0.00000,3644.2376,0.221403 26 | 2000,0.2,4,1,0.20000,4147.2000,0.200000 27 | 2000,0.2,4,2,0.10000,4287.1776,0.210000 28 | 2000,0.2,4,3,0.06667,4338.8504,0.213630 29 | 2000,0.2,4,4,0.05000,4365.7492,0.215506 30 | 2000,0.2,4,12,0.01667,4421.8302,0.219391 31 | 2000,0.2,4,52,0.00385,4444.2568,0.220934 32 | 2000,0.2,4,365,0.00055,4450.1067,0.221336 33 | 2000,0.2,4,inf,0.00000,4451.0819,0.221403 34 | 2000,0.2,10,1,0.20000,12383.4728,0.200000 35 | 2000,0.2,10,2,0.10000,13454.9999,0.210000 36 | 2000,0.2,10,3,0.06667,13864.1007,0.213630 37 | 2000,0.2,10,4,0.05000,14079.9774,0.215506 38 | 2000,0.2,10,12,0.01667,14536.5100,0.219391 39 | 2000,0.2,10,52,0.00385,14721.5272,0.220934 40 | 2000,0.2,10,365,0.00055,14770.0198,0.221336 41 | 2000,0.2,10,inf,0.00000,14778.1122,0.221403 42 | 2000,0.2,22,1,0.20000,110412.2878,0.200000 43 | 2000,0.2,22,2,0.10000,132528.1522,0.210000 44 | 2000,0.2,22,3,0.06667,141555.1757,0.213630 45 | 2000,0.2,22,4,0.05000,146449.6418,0.215506 46 | 2000,0.2,22,12,0.01667,157100.0551,0.219391 47 | 2000,0.2,22,52,0.00385,161532.6478,0.220934 48 | 2000,0.2,22,365,0.00055,162705.5526,0.221336 49 | 2000,0.2,22,inf,0.00000,162901.7373,0.221403 50 | 2000,0.2,35,1,0.20000,1181336.4583,0.200000 51 | 2000,0.2,35,2,0.10000,1579493.9136,0.210000 52 | 2000,0.2,35,3,0.06667,1754066.1745,0.213630 53 | 2000,0.2,35,4,0.05000,1851534.7417,0.215506 54 | 2000,0.2,35,12,0.01667,2070310.7589,0.219391 55 | 2000,0.2,35,52,0.00385,2164013.8921,0.220934 56 | 2000,0.2,35,365,0.00055,2189065.6165,0.221336 57 | 2000,0.2,35,inf,0.00000,2193266.3169,0.221403 58 | 2000,0.2,47,1,0.20000,10532914.5255,0.200000 59 | 2000,0.2,47,2,0.10000,15557592.8120,0.210000 60 | 2000,0.2,47,3,0.06667,17909358.2228,0.213630 61 | 2000,0.2,47,4,0.05000,19258312.1095,0.215506 62 | 2000,0.2,47,12,0.01667,22374416.8681,0.219391 63 | 2000,0.2,47,52,0.00385,23744743.8947,0.220934 64 | 2000,0.2,47,365,0.00055,24114600.8029,0.221336 65 | 2000,0.2,47,inf,0.00000,24176761.4604,0.221403 66 | -------------------------------------------------------------------------------- /test/utils/docs/Calculator_TVM_3.csv: -------------------------------------------------------------------------------- 1 | PV,R,n,m,R/m,FV,EAR 2 | 3312,0.2,1,1,0.20000,3974.4000,0.200000 3 | 3312,0.2,1,2,0.10000,4007.5200,0.210000 4 | 3312,0.2,1,3,0.06667,4019.5413,0.213630 5 | 3312,0.2,1,4,0.05000,4025.7567,0.215506 6 | 3312,0.2,1,12,0.01667,4038.6233,0.219391 7 | 3312,0.2,1,52,0.00385,4043.7343,0.220934 8 | 3312,0.2,1,365,0.00055,4045.0644,0.221336 9 | 3312,0.2,1,inf,0.00000,4045.2859,0.221403 10 | 3312,0.2,2,1,0.20000,4769.2800,0.200000 11 | 3312,0.2,2,2,0.10000,4849.0992,0.210000 12 | 3312,0.2,2,3,0.06667,4878.2345,0.213630 13 | 3312,0.2,2,4,0.05000,4893.3324,0.215506 14 | 3312,0.2,2,12,0.01667,4924.6612,0.219391 15 | 3312,0.2,2,52,0.00385,4937.1339,0.220934 16 | 3312,0.2,2,365,0.00055,4940.3822,0.221336 17 | 3312,0.2,2,inf,0.00000,4940.9234,0.221403 18 | 3312,0.2,3,1,0.20000,5723.1360,0.200000 19 | 3312,0.2,3,2,0.10000,5867.4100,0.210000 20 | 3312,0.2,3,3,0.06667,5920.3699,0.213630 21 | 3312,0.2,3,4,0.05000,5947.8762,0.215506 22 | 3312,0.2,3,12,0.01667,6005.0880,0.219391 23 | 3312,0.2,3,52,0.00385,6027.9160,0.220934 24 | 3312,0.2,3,365,0.00055,6033.8659,0.221336 25 | 3312,0.2,3,inf,0.00000,6034.8575,0.221403 26 | 3312,0.2,4,1,0.20000,6867.7632,0.200000 27 | 3312,0.2,4,2,0.10000,7099.5661,0.210000 28 | 3312,0.2,4,3,0.06667,7185.1363,0.213630 29 | 3312,0.2,4,4,0.05000,7229.6806,0.215506 30 | 3312,0.2,4,12,0.01667,7322.5507,0.219391 31 | 3312,0.2,4,52,0.00385,7359.6892,0.220934 32 | 3312,0.2,4,365,0.00055,7369.3768,0.221336 33 | 3312,0.2,4,inf,0.00000,7370.9916,0.221403 34 | 3312,0.2,10,1,0.20000,20507.0310,0.200000 35 | 3312,0.2,10,2,0.10000,22281.4798,0.210000 36 | 3312,0.2,10,3,0.06667,22958.9507,0.213630 37 | 3312,0.2,10,4,0.05000,23316.4426,0.215506 38 | 3312,0.2,10,12,0.01667,24072.4605,0.219391 39 | 3312,0.2,10,52,0.00385,24378.8491,0.220934 40 | 3312,0.2,10,365,0.00055,24459.1527,0.221336 41 | 3312,0.2,10,inf,0.00000,24472.5538,0.221403 42 | 3312,0.2,22,1,0.20000,182842.7486,0.200000 43 | 3312,0.2,22,2,0.10000,219466.6200,0.210000 44 | 3312,0.2,22,3,0.06667,234415.3710,0.213630 45 | 3312,0.2,22,4,0.05000,242520.6068,0.215506 46 | 3312,0.2,22,12,0.01667,260157.6912,0.219391 47 | 3312,0.2,22,52,0.00385,267498.0648,0.220934 48 | 3312,0.2,22,365,0.00055,269440.3951,0.221336 49 | 3312,0.2,22,inf,0.00000,269765.2770,0.221403 50 | 3312,0.2,35,1,0.20000,1956293.1750,0.200000 51 | 3312,0.2,35,2,0.10000,2615641.9209,0.210000 52 | 3312,0.2,35,3,0.06667,2904733.5850,0.213630 53 | 3312,0.2,35,4,0.05000,3066141.5323,0.215506 54 | 3312,0.2,35,12,0.01667,3428434.6168,0.219391 55 | 3312,0.2,35,52,0.00385,3583607.0054,0.220934 56 | 3312,0.2,35,365,0.00055,3625092.6609,0.221336 57 | 3312,0.2,35,inf,0.00000,3632049.0207,0.221403 58 | 3312,0.2,47,1,0.20000,17442506.4542,0.200000 59 | 3312,0.2,47,2,0.10000,25763373.6967,0.210000 60 | 3312,0.2,47,3,0.06667,29657897.2170,0.213630 61 | 3312,0.2,47,4,0.05000,31891764.8533,0.215506 62 | 3312,0.2,47,12,0.01667,37052034.3336,0.219391 63 | 3312,0.2,47,52,0.00385,39321295.8896,0.220934 64 | 3312,0.2,47,365,0.00055,39933778.9296,0.221336 65 | 3312,0.2,47,inf,0.00000,40036716.9785,0.221403 66 | -------------------------------------------------------------------------------- /utils/Calculator.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy as np 3 | import pandas as pd 4 | 5 | ''' ------------------------------------------------------------------------------------ ''' 6 | ''' TIME VALUE OF MONEY ''' 7 | ''' ------------------------------------------------------------------------------------ ''' 8 | 9 | def FV(PV=1, R=0.01, n=1, m=1, cc=False, ret_list=False): 10 | ''' 11 | Future Value calculation 12 | 13 | Parameters 14 | ---------- 15 | PV: int, Present Value 16 | R: float or list or pandas.Series, return(s) during each n period 17 | n: int, Number of compounding periods. No necesary if R is list 18 | m: int, compounding frequency. For continiously compounding use m='inf' 19 | Example: If n is years then for compund quarterly: m=4 20 | ret_list: boolean, if R is a list then return a list of each Future Value 21 | 22 | Returns 23 | ------- 24 | Future Value: int 25 | ''' 26 | if type(R) in [int, float, np.float64]: 27 | if m == 'inf' or m == float('inf') or cc: 28 | return PV * math.exp(R * n) 29 | else: 30 | return PV * math.pow(1 + R / m, n * m) 31 | elif type(R) in (list, np.ndarray): 32 | ans = [PV] 33 | for (r, i) in zip(R, range(1, len(R) + 1)): 34 | ans.append(FV(PV=ans[i-1], R=r, m=m)) 35 | 36 | if ret_list: 37 | return ans[1:] 38 | else: 39 | return ans[-1] 40 | elif type(R) in (pd.Series, pd.Series): 41 | ans = FV(PV=PV, R=R.values, ret_list=ret_list) 42 | if ret_list: 43 | return pd.Series(ans, index=R.index, name='Future value') 44 | return ans 45 | 46 | def PV(FV=1, R=0.01, n=1, m=1, cc=False, ret_list=True): 47 | ''' 48 | Present Value calculation 49 | 50 | Parameters 51 | ---------- 52 | FV: int, Future Value 53 | R: float or list, return(s) during each n period 54 | n: int, Number of compounding periods. No necesary if R is list 55 | m: int, compounding frequency. For continiously compounding use m='inf' 56 | Example: If n is years then for compund quarterly: m=4 57 | 58 | Returns 59 | ------- 60 | Present Value: int 61 | ''' 62 | if type(R) in [int, float, np.float64]: 63 | if m == 'inf' or m == float('inf') or cc: 64 | return FV / math.exp(R * n) 65 | else: 66 | return FV / math.pow(1 + R / m, n * m) 67 | elif type(R) in (list, np.ndarray): 68 | ans = [FV] 69 | for (r, i) in zip(R[::-1], range(1, len(R) + 1)): 70 | ans.append(PV(FV=ans[i-1], R=r, m=m)) 71 | 72 | if ret_list: 73 | return ans[::-1][1:] 74 | else: 75 | return ans[-1] 76 | elif type(R) in (pd.Series, pd.Series): 77 | ans = PV(FV=FV, R=R.values, ret_list=ret_list) 78 | if ret_list: 79 | return pd.Series(ans, index=R.index, name='Present value') 80 | return ans 81 | 82 | def R(PV=1, FV=1, n=1, m=1, cc=False): 83 | ''' 84 | Compound return of each n period; usually annual 85 | Example: use it to calculate a Compound Annual Growth Return 86 | 87 | Parameters 88 | ---------- 89 | FV: int, Future Value 90 | PV: int, Present Value 91 | n: int, Number of periods 92 | m: int, compounding frequency. For continiously compounding use m='inf' 93 | Example: If n is years then for compund quarterly: m=4 94 | 95 | Returns 96 | ------- 97 | Return: float 98 | ''' 99 | if m == 'inf' or m == float('inf') or cc: 100 | return math.log(FV / PV) / n 101 | else: 102 | return m * ( math.pow(FV / PV , 1 / (m * n)) - 1 ) 103 | 104 | def n(PV=1, FV=1, R=0.1, m=1, cc=False): 105 | ''' 106 | Investment horizon: Number of periods (n) 107 | 108 | Parameters 109 | ---------- 110 | FV: int, Future Value 111 | PV: int, Present Value 112 | R: float, Return 113 | m: int, compounding frequency. For continiously compounding use m='inf' 114 | Example: If n is years then for compund quarterly: m=4 115 | 116 | Returns 117 | ------- 118 | Investment horizon: int 119 | ''' 120 | if m == 'inf' or m == float('inf') or cc: 121 | return math.log(FV / PV) / R 122 | else: 123 | return math.log(FV / PV) / (m * math.log(1 + R / m)) 124 | 125 | def eff_ret(R=0.01, m=2, cc=False): 126 | ''' 127 | Efective Return 128 | Use for: What is the Annual rate that equates a rate R with a frequency of m 129 | 130 | Parameters 131 | ---------- 132 | R: float, Return; for 10%% use 0.1 133 | m: int, compounding frequency. For continiously compounding use m='inf' 134 | Example: if R is annual, m=2 is semmiannual compounding 135 | 136 | Returns 137 | ------- 138 | Efective Annual Return: float 139 | ''' 140 | if m == 'inf' or m == float('inf') or cc: 141 | return math.exp(R) - 1 142 | else: 143 | return math.pow(1 + (R / m), m) - 1 144 | 145 | def ann_ret(R=0.1, m=1, cc=False): 146 | ''' 147 | Annualize Return 148 | Example: Convert a semmiannual return to an annual return 149 | 150 | Parameters 151 | ---------- 152 | R: float, Return; for 10%% use 0.1 153 | n: int, Number of periods. For continiously compounding use m='inf' 154 | m: int, compounding frequency 155 | 156 | Returns 157 | ------- 158 | Annual Return: float 159 | ''' 160 | if cc: 161 | return R * m 162 | if m == 'inf': 163 | return math.exp(R) - 1 164 | else: 165 | return math.pow(1 + R, m) - 1 166 | 167 | ''' ------------------------------------------------------------------------------------ ''' 168 | ''' ASSET RETURNS ''' 169 | ''' ------------------------------------------------------------------------------------ ''' 170 | 171 | def ret(data, pos=-1, cc=False, col=None, dividends=None): 172 | ''' 173 | Calculates the total return 174 | 175 | Parameters 176 | ---------- 177 | data: numpy.array or pandas.Series or pandas.DataFrame 178 | pos: int, calculate the return of that position (index): if 1 then calculates the total return 179 | cc: boolean, if want the continuously compounded return 180 | col=None: if data is pandas.DataFrame use this column to calculate the Total Return 181 | 182 | Returns 183 | ------- 184 | if data is numpy.array of 1 dim: int with the total return 185 | if data is numpy.array of 2 dim: numpy.array with the total return of each column 186 | if data is pandas.Series: int with the total return 187 | if data is pandas.DataFrame and col is None and column == 1: int with the total return 188 | if data is pandas.DataFrame and col is None and columns > 1: pandas.DataFrame with the total return of each column 189 | if data is pandas.DataFrame and col is not None: int with the total return 190 | ''' 191 | if type(data) is np.ndarray or type(data) is list: 192 | if dividends is not None: 193 | _data = np.array(data) + np.array(dividends) 194 | else: 195 | _data = data 196 | if cc: 197 | return math.log(_data[pos] / _data[0]) 198 | else: 199 | return _data[pos] / _data[0] - 1 200 | 201 | if type(data) is pd.Series or type(data) is pd.Series: 202 | return ret(data.values, pos=pos, cc=cc) 203 | 204 | if type(data) is pd.DataFrame: 205 | if col is None: 206 | if len(data.columns) == 1: 207 | return ret(data[data.columns[0]], pos=pos, cc=cc) 208 | else: 209 | series = data.apply(ret, pos=pos, cc=cc) 210 | series.name = 'Total Returns' 211 | return series 212 | else: 213 | return ret(data[col], pos=pos, cc=cc) 214 | 215 | 216 | def returns(data, basedOn=1, cc=False, col=None): 217 | ''' 218 | Computes stepwise returns; usually daily 219 | 220 | Parameters 221 | ---------- 222 | data: numpy.array or pandas.Series or pandas.DataFrame 223 | cc: boolean, if want the continuously compounded return 224 | basedOn: Calculate the returns basedOn the previously n entries 225 | For example if the data is monthly and basedOn=12 is an Annual Return 226 | col=None: if data is pandas.DataFrame use this column to calculate the Daily Returns 227 | 228 | Returns 229 | ------- 230 | if data is numpy.array of 1 dim: numpy.array with the daily returns 231 | if data is numpy.array of 2 dim: numpy.array with the daily returns of each column 232 | if data is pandas.Series: pandas.Series with the daily returns 233 | if data is pandas.DataFrame and col is None: pandas.DataFrame with the daily returns of each column 234 | if data is pandas.DataFrame and col is not None: pandas.Series with the daily returns 235 | ''' 236 | 237 | if type(data) is np.ndarray or type(data) is list: 238 | dr = np.zeros(shape=data.shape) 239 | if cc: 240 | # return np.log(data[basedOn:] / data[0:-basedOn]) 241 | dr[basedOn:] = np.log(data[basedOn:] / data[0:-basedOn]) 242 | return dr 243 | else: 244 | # return data[basedOn:] / data[0:-basedOn] - 1 245 | dr[basedOn:] = data[basedOn:] / data[0:-basedOn] - 1 246 | return dr 247 | 248 | if type(data) is pd.Series or type(data) is pd.Series: 249 | ans = returns(data.values, cc=cc, basedOn=basedOn) 250 | name = data.name 251 | if cc: 252 | name = name + ' CC' 253 | name = name + ' returns' 254 | if basedOn != 1: 255 | name = name + ' (' + str(basedOn) + ')' 256 | return pd.Series(ans, index=data.index, name=name) 257 | 258 | if type(data) is pd.DataFrame: 259 | if col is not None: 260 | return returns(data[col], cc=cc, basedOn=basedOn) 261 | else: 262 | return data.apply(returns, cc=cc, basedOn=basedOn) 263 | 264 | def sharpe_ratio(data, col=None, cc=False): 265 | ''' 266 | Calculates the sharpe ratio 267 | 268 | Parameters 269 | ---------- 270 | data - numpy.array or pandas.DataFrame or pandas.Series 271 | col=None: if data is pandas.DataFrame use this column to calculate the Sharpe Ratio 272 | 273 | Returns 274 | ------- 275 | if data is numpy.array of 1 dim: int with the sharpe ratio 276 | if data is numpy.array of 2 dim: numpy.array with the sharpe ratio of each column 277 | if data is pandas.Series: int with the sharpe ratio 278 | if data is pandas.DataFrame: pandas.DataFrame with the sharpe ratio of each column 279 | if data is pandas.DataFrame and col!=None: int with the sharpe ratio 280 | ''' 281 | if type(data) is np.ndarray or type(data) is list: 282 | dr = returns(data) 283 | mean = dr.mean(0) 284 | std = dr.std(0) 285 | return math.sqrt(len(data)) * mean / std 286 | 287 | if type(data) is pd.Series or type(data) is pd.Series: 288 | return sharpe_ratio(data.values, cc=cc) 289 | 290 | if type(data) is pd.DataFrame: 291 | if col is not None: 292 | return sharpe_ratio(data[col], cc=cc) 293 | else: 294 | series = data.apply(sharpe_ratio, cc=cc) 295 | series.name = 'Sharpe Ratios' 296 | return series 297 | -------------------------------------------------------------------------------- /utils/DataAccess.py: -------------------------------------------------------------------------------- 1 | import os 2 | import hashlib 3 | import pandas as pd 4 | from datetime import datetime 5 | from finance.utils.FileManager import FileManager 6 | 7 | class DataAccess(object): 8 | 9 | path = '' 10 | ''' 11 | Class to manage the Access to the Data 12 | 13 | Features 14 | -------- 15 | 1. Easy access to the data 16 | 2. Serialization of data 17 | 18 | How to use 19 | ---------- 20 | Use one: Note: Option 2 overwrites option 1 21 | 1. Set the enviroment variable: FINANCEPATH 22 | 2. Set the Static Variable DataAccess.path 23 | 24 | ''' 25 | def __init__(self): 26 | if self.path != '': 27 | self.set_dir(self.path) 28 | else: 29 | env_var = os.getenv("FINANCEPATH") 30 | if env_var is not None: 31 | self.set_dir(env_var) 32 | else: 33 | raise Exception('No path defined') 34 | 35 | 36 | def set_dir(self, dir_path): 37 | ''' 38 | Initialize the FileManager 39 | Creates the directories 40 | Set global variables with absolute paths to the directories 41 | 42 | Parameters 43 | ---------- 44 | dir_path: str 45 | ''' 46 | self.dir = os.path.realpath(dir_path) # Absolute Path 47 | self.cache_dir = os.path.join(self.dir, 'cached') 48 | self.file_manager = FileManager(dir_path) 49 | 50 | # Create paths if it doesn't exist 51 | if not (os.access(self.dir, os.F_OK)): 52 | os.makedirs(self.dir) 53 | if not (os.access(self.cache_dir, os.F_OK)): 54 | os.makedirs(self.cache_dir) 55 | 56 | def empty_dir(self, delete=True): 57 | ''' 58 | Empty the directory of csv files. Do not delete the cache files/folder 59 | 60 | Parameters 61 | ---------- 62 | delete:boolean, True if want to delete the folder too 63 | ''' 64 | self.file_manager.empty_dir(delete) 65 | 66 | def empty_cache(self, delete=True): 67 | ''' 68 | Empty the directory of cached files. Does not delete the csv files/folder 69 | 70 | Parameters 71 | ---------- 72 | delete: boolean, True if want to delete the folder too 73 | ''' 74 | list_files = os.listdir(self.cache_dir) # Get the list of files 75 | for f in list_files: 76 | try: 77 | os.remove(os.path.join(self.cache_dir, f)) 78 | except: 79 | pass 80 | 81 | if delete: 82 | os.rmdir(self.cache_dir) 83 | 84 | def empty_dirs(self, delete=True): 85 | ''' 86 | Delete both cached and csv files. 87 | 88 | Parameters 89 | ---------- 90 | delete:booelan, True if want to delete the folders too 91 | ''' 92 | self.empty_cache(delete) 93 | self.empty_dir(delete) 94 | 95 | def save(self, data, name, extension='.data'): 96 | ''' 97 | Saves a serialized (pickle) version of the data to the cache directory 98 | 99 | Parameters 100 | ---------- 101 | data: object 102 | name: str, identifier of the data 103 | extension: str, extension of the filename 104 | ''' 105 | h = hashlib.md5() 106 | h.update(name.encode('utf8')) 107 | filename = h.hexdigest() + extension 108 | 109 | f = os.path.join(self.cache_dir, filename) 110 | data.to_csv(f) 111 | 112 | def load(self, name, extension='.data'): 113 | ''' 114 | Checks for an existing file name and if exists returns the data saved 115 | 116 | Parameters 117 | ---------- 118 | name: str, identifier of the data 119 | extension: str, extension of the filename 120 | 121 | Returns 122 | ------- 123 | data: object (usually pandas.DataFrame), if file was available; None otherwise. 124 | ''' 125 | h = hashlib.md5() 126 | h.update(name.encode('utf8')) 127 | filename = h.hexdigest() + extension 128 | 129 | f = os.path.join(self.cache_dir, filename) 130 | if os.access(f, os.F_OK): 131 | return pd.read_csv(f, parse_dates=True, index_col='timestamp') 132 | 133 | 134 | def get_data(self, symbols, start, end, fields='adjusted_close', save=True, useCache=True, 135 | downloadMissing=True, ignoreMissing=True): 136 | ''' 137 | Returns a pandas DataFrame with the data of the symbols and field 138 | fields between the specified dates with the fields specified 139 | 140 | Optional: 141 | 1. Load a serialized version of the data 142 | 2. Saves a serialized version of the data 143 | 3. If data is not available download the missing data 144 | 145 | Parameters 146 | ---------- 147 | symbols_s: str or list of str 148 | start: datetime, with the initial date 149 | end: datetime, with the final date 150 | fields: str or list of str 151 | save: boolean, True if want to save the cache version 152 | useCache: boolean: True if want to load a cached version (if available) 153 | downloadMissing: boolean, True if want to download unavailable data 154 | ignoreMissing=True 155 | 156 | Returns 157 | ------- 158 | data: pandas.DataFrame 159 | ''' 160 | # 0. If ask for only one symbols or field convert it to a list of one item 161 | if type(symbols) == str: 162 | symbols = [symbols] 163 | if type(fields) == str: 164 | fields = [fields] 165 | 166 | # 1. Load the Data, if requested 167 | filename_id = "%s_%s_%s_%s" % ('_'.join(symbols), start.strftime('%m-%d-%Y'), 168 | end.strftime('%m-%d-%Y'), '-'.join(fields)) 169 | if useCache == True: 170 | data = self.load(filename_id) 171 | if data is not None: 172 | # 1.1 Data was cached before and loaded => return 173 | return data 174 | 175 | # 1. Data was not cached before need to load the data from csv files 176 | 177 | # 1.1 Get the list of filenames from the FileManager 178 | files = self.file_manager.get_filenames(symbols, start, end, downloadMissing, ignoreMissing) 179 | 180 | # 1.2 We are going to create a pd.DataFrame from a dictionary of pd.Series 181 | data_dic = {} 182 | 183 | for f, symbol in zip(files, symbols): 184 | # Create DataFrame from the csv 185 | new_data = pd.read_csv(os.path.join(self.dir, f)) 186 | # Change the index of the DataFrame to be the date 187 | new_data = pd.read_csv(os.path.join(self.dir, f), parse_dates=True, index_col='timestamp') 188 | 189 | for field in fields: 190 | # For each field in fields, creates a new column 191 | colname = '' 192 | if len(symbols) == 1 and len(fields) == 1: 193 | # Single symbol and Single field 194 | colname = field 195 | elif len(symbols) > 1 and len(fields) == 1: 196 | # Multiple symbols and single fields 197 | colname = symbol 198 | elif len(symbols) == 1 and len(fields) > 1: 199 | # Single symbol and Multiple fields 200 | colname = field 201 | else: 202 | # Multiple symbols and multiple fields 203 | colname = "%s %s" % (symbol, field) 204 | # Adds the pd.Series to the dictionary 205 | data_dic[colname] = new_data[field] 206 | 207 | # 1.4. Create, slice and sort the data 208 | data = pd.DataFrame(data_dic) 209 | data = data.sort_index() 210 | 211 | # Save a cache version if requested 212 | if save == True: 213 | self.save(data, filename_id) 214 | return data 215 | 216 | def download(self, symbols, start, end): 217 | self.get_data(symbols, start, end, useCache=False, save=False) 218 | -------------------------------------------------------------------------------- /utils/DateUtils.py: -------------------------------------------------------------------------------- 1 | import math 2 | import numpy as np 3 | import pandas as pd 4 | from datetime import datetime, timedelta 5 | from finance.utils import ListUtils 6 | 7 | def nyse_dates(start=datetime(2007,1,1), end=datetime.today(), 8 | insideSearch=True, lookbackDays=0, lookforwardDays=0, 9 | series=False): 10 | ''' 11 | Returns the NYSE open dates 12 | 13 | Parameters 14 | ---------- 15 | start: datetime, start date of the range (incluse) 16 | Default value: 17 | datetime(2007,1,1) 18 | datetime(1962,7,5) if end is lower than 2007-1-1 19 | end: datetime, end date of the range (incluse) 20 | Default value: datetime.today() 21 | insideSearch: boolean, TODO 22 | lookbackDays: int 23 | lookforwardDays: int 24 | series: boolean, if want to be returned a pandas.series 25 | 26 | Returns 27 | ------- 28 | dates: list of dates or pandas.Series 29 | ''' 30 | start = datetime(start.year, start.month, start.day) 31 | end = datetime(end.year, end.month, end.day) 32 | 33 | if start < datetime(2007, 1, 1) or end < datetime(2007, 1, 1): 34 | # If specify an start date or end date before 2007-1-1 35 | dates = ListUtils.NYSE(complete=True) 36 | 37 | if end < datetime(2007, 1, 1) and start == datetime(2007, 1, 1): 38 | # In case only specify an end date lower than 2007-1-1 39 | start = dates[0] 40 | else: 41 | # Get dates from 2007-1-1 42 | dates = ListUtils.NYSE() 43 | 44 | # Get the indexes to slice the array 45 | idx_start = 0 46 | idx_end = len(dates) 47 | # Get the indexes of the start and end dates 48 | if start is not datetime(2007,1,1): 49 | idx_start = search_closer_date(start, dates, searchBack=False) 50 | if end is not datetime.today(): 51 | idx_end = search_closer_date(end, dates, searchBack=True) 52 | 53 | # Modify the indexes with the lookback and lookforward days 54 | if lookbackDays is not 0: 55 | idx_start = idx_start - lookbackDays 56 | if lookforwardDays is not 0: 57 | idx_end = idx_end + lookforwardDays 58 | 59 | # Slice the dates using the indexes 60 | dates = dates[idx_start:idx_end+1] 61 | 62 | if series: 63 | return pd.Series(index=dates, data=dates) 64 | else: 65 | return dates 66 | 67 | def nyse_add(date, amount): 68 | ''' 69 | Add a number of date to a current date using the NYSE open dates 70 | 71 | Parameters 72 | ---------- 73 | date: datetime 74 | amount: int, how many days wants to add 75 | ''' 76 | dates = nyse_dates(start=date) 77 | idx = search_closer_date(date, dates) 78 | return dates[idx+amount] 79 | 80 | def nyse_substract(date, amount): 81 | ''' 82 | Substracts a number of date to a current date using the NYSE open dates 83 | 84 | Parameters 85 | ---------- 86 | date: datetime 87 | amount: int, how many days wants to substract 88 | 89 | Returns 90 | ------- 91 | date: datetime 92 | ''' 93 | dates = nyse_dates(end=date) 94 | idx = search_closer_date(date, dates) 95 | return dates[idx-amount] 96 | 97 | 98 | def search_closer_date(date, dates, exact=False, searchBack=True, maxDistance=10): 99 | ''' 100 | Get the index the closer date given as parameter 101 | 102 | Parameters 103 | ---------- 104 | date: datetime 105 | dates: list or np.array or pd.DatetimeIndex, list to look the date on 106 | searchBack: boolean, True to search for the date into the past 107 | maxDistance: int, maximum distance (on days) to look for the date 108 | ''' 109 | # 0. Diferent type of parameters 110 | if type(dates) == pd.DatetimeIndex: 111 | dates = dates.to_pydatetime() 112 | if type(dates) == np.ndarray: 113 | dates = dates.tolist() 114 | 115 | if exact == False: 116 | searchBack = -1 if searchBack else 1 117 | idx = 0 118 | for i in range(maxDistance): 119 | try: 120 | d = date + searchBack * timedelta(days=i) 121 | return dates.index(d) 122 | except ValueError: 123 | pass 124 | else: 125 | return dates.index(date) 126 | 127 | def nyse_dates_event(eventDate, lookbackDays, lookforwardDays, estimationPeriod, pastEvent=True): 128 | ''' 129 | Special Case of DateUtils.nyse_dates() returns the dates around an event 130 | 131 | Parameters 132 | ---------- 133 | eventDate: datetime 134 | lookbackDays: int 135 | lookforwardDays: int 136 | estimationPeriod: int 137 | 138 | Returns 139 | ------- 140 | dates: list of dates or pandas.Series 141 | ''' 142 | if pastEvent: 143 | return nyse_dates(start=eventDate, end=eventDate, 144 | lookbackDays=estimationPeriod+lookbackDays, 145 | lookforwardDays=lookforwardDays) 146 | else: 147 | return nyse_dates(start=eventDate, end=eventDate, 148 | lookbackDays=lookbackDays, 149 | lookforwardDays=estimationPeriod+lookforwardDays) 150 | -------------------------------------------------------------------------------- /utils/FileManager.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import urllib.parse 4 | import urllib.request 5 | from datetime import datetime 6 | import pandas as pd 7 | import time 8 | 9 | class FileManager(object): 10 | ''' 11 | Class to manage the files from: 12 | - Yahoo Finance 13 | - Alpha Vantage 14 | ''' 15 | def __init__(self, dir_path='./data/'): 16 | self.set_dir(dir_path) 17 | 18 | env_var_key = os.getenv("ALPHAVANTAGEKEY") 19 | if env_var_key is not None: 20 | self.alpha_vantage_key = env_var_key 21 | else: 22 | raise Exception('ALPHAVANTAGEKEY not defined') 23 | 24 | def set_dir(self, dir_path): 25 | ''' 26 | 1. Set global variables with absolute paths to the directories 27 | 2. Creates the directories 28 | 29 | Parameters 30 | ---------- 31 | dir_path: str 32 | ''' 33 | self.dir = os.path.realpath(dir_path) # Absolute Path 34 | 35 | #Create path if it doesn't exist 36 | if not (os.access(self.dir, os.F_OK)): 37 | os.makedirs(self.dir) 38 | 39 | def empty_dir(self, delete=True): 40 | ''' 41 | Empty the directory of files 42 | 43 | Parameters 44 | ---------- 45 | delete: boolean, True if want to delete the folder too 46 | ''' 47 | list_files = os.listdir(self.dir) # Get the list of files 48 | for f in list_files: 49 | try: 50 | os.remove(os.path.join(self.dir, f)) 51 | except: 52 | pass 53 | 54 | if delete: 55 | os.rmdir(self.dir) 56 | 57 | def get_filenames(self, symbol_s, start_date, end_date, downloadMissing=True, ignoreMissing=True): 58 | ''' 59 | Returns a list with the file paths of the symbols 60 | which contains the information between the specified dates. 61 | Optional: If data is not available download the missing data 62 | 63 | Parameters 64 | ---------- 65 | symbol_s: str for single - list of str for multiple 66 | start_date: datetime, with the initial date 67 | end_date: datetime, with the final date 68 | downloadMissing: boolean, True if want to download missing data 69 | 70 | Returns 71 | ------- 72 | if single - str with the relative path to the file with the information 73 | if multiple - list of str with relative paths 74 | ''' 75 | # 0. If only asks for one symbols convert it to a list 76 | if type(symbol_s) == str: 77 | symbols = [symbol_s] 78 | elif type(symbol_s) == list: 79 | symbols = symbol_s 80 | 81 | # 1. Get the list of files available 82 | list_files = [f for f in os.listdir(self.dir) if os.path.isfile(os.path.join(self.dir,f))] 83 | ans = [] 84 | 85 | # For symbol in symbols and for each file_name in files 86 | for symbol in symbols: 87 | f = None 88 | for file_name in list_files: 89 | # Check the name of the stock 90 | if file_name.startswith(symbol): 91 | # Check if the dates of the file are greater or equal than the requested 92 | # Note: split to get each date and file_name[:-4] to remove the .csv 93 | fi_start_date = datetime.strptime(file_name[:-4].split('_')[1], "%Y-%m-%d") 94 | fi_end_date = datetime.strptime(file_name[:-4].split('_')[2], "%Y-%m-%d") 95 | if fi_start_date <= start_date and fi_end_date >= end_date: 96 | f = file_name 97 | 98 | if f is None and downloadMissing: 99 | success = self.alphavantage_download(symbol, start_date, end_date) 100 | if success: 101 | # If download was susccesfull add the path to the new file 102 | f = "%s_%d-%d-%d_%d-%d-%d.csv" % (symbol, start_date.year, start_date.month, 103 | start_date.day, end_date.year, end_date.month, end_date.day) 104 | 105 | if ignoreMissing == False: 106 | ans.append(f) 107 | else: 108 | if f is not None: 109 | ans.append(f) 110 | 111 | 112 | if type(symbol_s) == str: 113 | if len(ans) == 1: 114 | return ans[0] 115 | else: 116 | return [] 117 | else: 118 | return ans 119 | 120 | def download(self, symbols, start_date, end_date): 121 | self.get_filenames(symbols, start_date, end_date, downloadMissing=True) 122 | 123 | def yahoo_download(self, symbol, start_date, end_date): 124 | ''' 125 | Downloads and saves the equitiy information from Yahoo! Finance between 126 | the specified dates. 127 | Saves the csv file with the name: SYMBOL_start_date_end_date.csv 128 | e.g: AAPL_2009-1-1_2010-1-1.csv 129 | 130 | Parameters 131 | ---------- 132 | symbol: str 133 | start_date: datetime 134 | end_date: datetime 135 | 136 | Returns 137 | ------- 138 | boolean: True if was able to download the symbol, False otherwise 139 | ''' 140 | try: 141 | params = urllib.parse.urlencode({ 142 | 's': str(symbol), 143 | 'a': start_date.month - 1, 'b': start_date.day, 'c': start_date.year, 144 | 'd': end_date.month - 1, 'e': end_date.day, 'f': end_date.year 145 | }) 146 | webFile = urllib.request.urlopen("http://ichart.finance.yahoo.com/table.csv?%s" % params) 147 | filename = "%s_%d-%d-%d_%d-%d-%d.csv" % (symbol, start_date.year, start_date.month, 148 | start_date.day, end_date.year, end_date.month, end_date.day) 149 | localFile = open( os.path.join(self.dir, filename), 'w') 150 | localFile.write(webFile.read().decode('utf-8')) 151 | webFile.close() 152 | localFile.close() 153 | return True 154 | except: 155 | # print(symbol, sys.exc_info()[1]) 156 | return False 157 | 158 | def alphavantage_download(self, symbol, start_date, end_date): 159 | """ 160 | Downloads and saves the equitiy information from Yahoo! Finance between 161 | the specified dates. 162 | Saves the csv file with the name: SYMBOL_start_date_end_date.csv 163 | e.g: AAPL_2009-1-1_2010-1-1.csv 164 | 165 | Parameters 166 | ---------- 167 | symbol: str 168 | start_date: datetime 169 | end_date: datetime 170 | 171 | Returns 172 | ------- 173 | boolean: True if was able to download the symbol, False otherwise 174 | """ 175 | try: 176 | params = urllib.parse.urlencode( 177 | { 178 | 'function': 'TIME_SERIES_DAILY_ADJUSTED', 179 | 'symbol': symbol, 180 | 'outputsize': 'full', 181 | 'datatype': 'csv', 182 | 'apikey': self.alpha_vantage_key 183 | }) 184 | sourceURL = "https://www.alphavantage.co/query?{0}".format(params) 185 | webFile = urllib.request.urlopen(sourceURL) 186 | # print(webFile.read().decode('utf-8')) 187 | #print("start_date: {0}".format(start_date)) 188 | #print("end_date: {0}".format(end_date)) 189 | 190 | # extract start date and end date from webfile 191 | csvData = pd.read_csv(webFile, parse_dates=True, index_col='timestamp') 192 | # Sort so earliest comes first 193 | csvData = csvData.sort_index() 194 | csvData = csvData.truncate(before=start_date) 195 | csvData = csvData.truncate(after=end_date) 196 | #print(csvData.head()) 197 | #print(csvData.tail()) 198 | data_start_date = csvData.index.tolist()[0] 199 | #print("data start_date: {0}".format(data_start_date)) 200 | 201 | data_end_date = csvData.index.tolist()[-1] 202 | #print("data end_date: {0}".format(data_end_date)) 203 | 204 | filename = "%s_%d-%d-%d_%d-%d-%d.csv" % (symbol, start_date.year, start_date.month, 205 | start_date.day, end_date.year, end_date.month, end_date.day) 206 | localFile = open(os.path.join(self.dir, filename), 'w') 207 | csvData.to_csv(localFile) 208 | webFile.close() 209 | localFile.close() 210 | return True 211 | except: 212 | print("FileManager::alphaVantageDownload: {0}, {1}".format(symbol, sys.exc_info()[1])) 213 | return False 214 | -------------------------------------------------------------------------------- /utils/ListUtils.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | def NYSE(complete=False): 4 | if complete: 5 | import os, inspect 6 | import numpy as np 7 | from datetime import datetime 8 | self_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) 9 | filename = os.path.join(self_dir, './lists/NYSE_dates.txt') 10 | return [datetime.strptime(x, "%m/%d/%Y") for x in np.loadtxt(filename, dtype=str)] 11 | else: 12 | from finance.utils.lists import NYSE_dates 13 | return NYSE_dates.all_dates 14 | 15 | def SP500(year=2012): 16 | if year == 2012: 17 | from finance.utils.lists import SP500_2012 18 | return SP500_2012.all_symbols 19 | elif year == 2008: 20 | from finance.utils.lists import SP500_2008 21 | return SP500_2008.all_symbols -------------------------------------------------------------------------------- /utils/__init__.py: -------------------------------------------------------------------------------- 1 | #from finance.utils.BasicUtils import BasicUtils 2 | #from finance.utils.DateUtils import DateUtils 3 | from finance.utils.DataAccess import DataAccess 4 | from finance.utils.FileManager import FileManager 5 | -------------------------------------------------------------------------------- /utils/lists/SP500_2008.py: -------------------------------------------------------------------------------- 1 | all_symbols = [ 2 | 'FMCC','FNMA','A','AA','AAPL','ABC','ABI','ABKFQ','ABT','ACAS','ACE','ACS','ADBE','ADI','ADM','ADP','ADSK','AEE','AEP','AES','AET','AFL','AGN','AIG','AIV','AIZ','AKAM','ALL','ALTR','AMAT','AMD','AMGN','AMP','AMT','AMZN','AN','ANF','AON','APA','APC','APD','APOL','ASH','ATI','AVB','AVP','AVY','AXP','AYE','AZO','BA','BAC','BAX','BBBY','BBT','BBY','BC','BCR','BDK','BDX','BEAM','BEN','BF.B','BHI','BIG','BIIB','BJS','BK','BLL','BMC','BMS','BMY','BRCM','BRK.B','BRLI','BSC','BSX','BTU','BUD','BXP','C','CA','CAG','CAH','CAT','CB','CBE','CBG','CBSH','CBS','CCE','CCL','CCMO','CCTYQ','CEG','CELG','CFC+A','CHK','CHRW','CI','CIEN','CINF','CIT','CL','CLX','CMA','CMCSA','CME','CMI','CMS','CNP','CNX','COF','COH','COL','COP','COST','COV','CPB','CPWR','CSC','CSCO','CSX','CTAS','CTL','CTSH','CTX','CTXS','CVG','CVH','CVS','CVX','D','DD','DDR','DDS','DE','DELL','DF','DFS','DGX','DHI','DHR','DIS','DOV','DOW','DRI','DTE','DTV','DUK','DVN','DYN','EBAY','ECL','ED','EDS','EFX','EIX','EK','EL','EMC','EMN','EMR','EOG','EP','EQ','EQR','ERTS','ESRX','ESV','ETFC','ETN','ETR','EXC','EXPD','EXPE','F','FCX','FDO','FDX','FE','FHN','FII','FIS','FISV','FITB','FLR','FRX','FTR','GAS','GCI','GD','GE','GENZ','GGP','GILD','GIS','GLW','GM','GME','GNW','GOOG','GPC','GPS','GR','GS','GT','GWW','HAL','HAR','HAS','HBAN','HCBK','HD','HES','HIG','HNZ','HOG','HON','HOT','HPC','HPQ','HRB','HSP','HST','HSY','HUM','IACI','IBM','ICE','IFF','IGT','INTC','INTU','IP','IPG','IR','ITT','ITW','JAVA','JBL','JCI','JCP','JDSU','JEC','JNJ','JNPR','JNS','JNY','JPM','JWN','K','KBH','KEY','KFT','KG','KIM','KLAC','KMB','KO','KR','KSS','L','LEG','LEHMQ','LEN','LH','LIZ','LLL','LLTC','LLY','LM','LMT','LNC','LOW','LSI','LTD','LUK','LUV','LXK','M','MAR','MAS','MAT','MBI','MCD','MCHP','MCK','MCO','MDP','MDT','MET','MHP','MHS','MI','MIL','MKC','MMC','MMM','MO','MOLX','MON','MRK','MRO','MS','MSFT','MSI','MTB','MTG','MTW','MU','MUR','MWV','MWW','MYL','NBL','NBR','NCC','NE','NEE','NEM','NI','NKE','NOC','NOV','NOVL','NSC','NSM','NTAP','NTRS','NUE','NVDA','NVLS','NWL','NWSA','NYT','NYX','ODP','OMC','OMX','ORCL','OXY','PAYX','PBG','PBI','PCAR','PCG','PCL','PCP','PDCO','PEG','PEP','PFE','PFG','PG','PGN','PGR','PH','PHM','PKI','PLD','PLL','PNC','PNW','POM','PPG','PPL','PRU','PSA','PTV','PX','Q','QCOM','QLGC','R','RAI','RDC','RF','RHI','RIG','RL','ROH','ROK','RRC','RRD','RSH','RTN','S','SAF','SBUX','SCHW','SE','SEE','SGP','SHLD','SHW','SIAL','SII','SLB','SLE','SLM','SNA','SNDK','SNV','SO','SPG','SPLS','SRE','SSP','STI','STJ','STR','STT','STZ','SUN','SVU','SWK','SWY','SYK','SYMC','SYY','T','TAP','TDC','TE','TEG','TEL','TER','TEX','TGT','THC','TIE','TIF','TJX','TLAB','TMK','TMO','TROW','TRV','TSN','TSO','TWX','TXN','TXT','TYC','UIS','UNH','UNM','UNP','UPS','USB','UST','UTX','VAR','VFC','VIA.B','VLO','VMC','VNO','VRSN','VZ','WAG','WAMUQ','WAT','WB','WEN','WFC','WFM','WFR','WFT','WHR','WIN','WLP','WM','WMB','WMT','WPI','WPO','WU','WWY','WY','WYE','WYN','X','XEL','XL','XLNX','XOM','XRX','XTO','YHOO','YUM','ZION','ZMH' 3 | ] -------------------------------------------------------------------------------- /utils/lists/SP500_2008.txt: -------------------------------------------------------------------------------- 1 | FMCC 2 | FNMA 3 | A 4 | AA 5 | AAPL 6 | ABC 7 | ABI 8 | ABKFQ 9 | ABT 10 | ACAS 11 | ACE 12 | ACS 13 | ADBE 14 | ADI 15 | ADM 16 | ADP 17 | ADSK 18 | AEE 19 | AEP 20 | AES 21 | AET 22 | AFL 23 | AGN 24 | AIG 25 | AIV 26 | AIZ 27 | AKAM 28 | ALL 29 | ALTR 30 | AMAT 31 | AMD 32 | AMGN 33 | AMP 34 | AMT 35 | AMZN 36 | AN 37 | ANF 38 | AON 39 | APA 40 | APC 41 | APD 42 | APOL 43 | ASH 44 | ATI 45 | AVB 46 | AVP 47 | AVY 48 | AXP 49 | AYE 50 | AZO 51 | BA 52 | BAC 53 | BAX 54 | BBBY 55 | BBT 56 | BBY 57 | BC 58 | BCR 59 | BDK 60 | BDX 61 | BEAM 62 | BEN 63 | BF.B 64 | BHI 65 | BIG 66 | BIIB 67 | BJS 68 | BK 69 | BLL 70 | BMC 71 | BMS 72 | BMY 73 | BRCM 74 | BRK.B 75 | BRLI 76 | BSC 77 | BSX 78 | BTU 79 | BUD 80 | BXP 81 | C 82 | CA 83 | CAG 84 | CAH 85 | CAT 86 | CB 87 | CBE 88 | CBG 89 | CBSH 90 | CBS 91 | CCE 92 | CCL 93 | CCMO 94 | CCTYQ 95 | CEG 96 | CELG 97 | CFC+A 98 | CHK 99 | CHRW 100 | CI 101 | CIEN 102 | CINF 103 | CIT 104 | CL 105 | CLX 106 | CMA 107 | CMCSA 108 | CME 109 | CMI 110 | CMS 111 | CNP 112 | CNX 113 | COF 114 | COH 115 | COL 116 | COP 117 | COST 118 | COV 119 | CPB 120 | CPWR 121 | CSC 122 | CSCO 123 | CSX 124 | CTAS 125 | CTL 126 | CTSH 127 | CTX 128 | CTXS 129 | CVG 130 | CVH 131 | CVS 132 | CVX 133 | D 134 | DD 135 | DDR 136 | DDS 137 | DE 138 | DELL 139 | DF 140 | DFS 141 | DGX 142 | DHI 143 | DHR 144 | DIS 145 | DOV 146 | DOW 147 | DRI 148 | DTE 149 | DTV 150 | DUK 151 | DVN 152 | DYN 153 | EBAY 154 | ECL 155 | ED 156 | EDS 157 | EFX 158 | EIX 159 | EK 160 | EL 161 | EMC 162 | EMN 163 | EMR 164 | EOG 165 | EP 166 | EQ 167 | EQR 168 | ERTS 169 | ESRX 170 | ESV 171 | ETFC 172 | ETN 173 | ETR 174 | EXC 175 | EXPD 176 | EXPE 177 | F 178 | FCX 179 | FDO 180 | FDX 181 | FE 182 | FHN 183 | FII 184 | FIS 185 | FISV 186 | FITB 187 | FLR 188 | FRX 189 | FTR 190 | GAS 191 | GCI 192 | GD 193 | GE 194 | GENZ 195 | GGP 196 | GILD 197 | GIS 198 | GLW 199 | GM 200 | GME 201 | GNW 202 | GOOG 203 | GPC 204 | GPS 205 | GR 206 | GS 207 | GT 208 | GWW 209 | HAL 210 | HAR 211 | HAS 212 | HBAN 213 | HCBK 214 | HD 215 | HES 216 | HIG 217 | HNZ 218 | HOG 219 | HON 220 | HOT 221 | HPC 222 | HPQ 223 | HRB 224 | HSP 225 | HST 226 | HSY 227 | HUM 228 | IACI 229 | IBM 230 | ICE 231 | IFF 232 | IGT 233 | INTC 234 | INTU 235 | IP 236 | IPG 237 | IR 238 | ITT 239 | ITW 240 | JAVA 241 | JBL 242 | JCI 243 | JCP 244 | JDSU 245 | JEC 246 | JNJ 247 | JNPR 248 | JNS 249 | JNY 250 | JPM 251 | JWN 252 | K 253 | KBH 254 | KEY 255 | KFT 256 | KG 257 | KIM 258 | KLAC 259 | KMB 260 | KO 261 | KR 262 | KSS 263 | L 264 | LEG 265 | LEHMQ 266 | LEN 267 | LH 268 | LIZ 269 | LLL 270 | LLTC 271 | LLY 272 | LM 273 | LMT 274 | LNC 275 | LOW 276 | LSI 277 | LTD 278 | LUK 279 | LUV 280 | LXK 281 | M 282 | MAR 283 | MAS 284 | MAT 285 | MBI 286 | MCD 287 | MCHP 288 | MCK 289 | MCO 290 | MDP 291 | MDT 292 | MET 293 | MHP 294 | MHS 295 | MI 296 | MIL 297 | MKC 298 | MMC 299 | MMM 300 | MO 301 | MOLX 302 | MON 303 | MRK 304 | MRO 305 | MS 306 | MSFT 307 | MSI 308 | MTB 309 | MTG 310 | MTW 311 | MU 312 | MUR 313 | MWV 314 | MWW 315 | MYL 316 | NBL 317 | NBR 318 | NCC 319 | NE 320 | NEE 321 | NEM 322 | NI 323 | NKE 324 | NOC 325 | NOV 326 | NOVL 327 | NSC 328 | NSM 329 | NTAP 330 | NTRS 331 | NUE 332 | NVDA 333 | NVLS 334 | NWL 335 | NWSA 336 | NYT 337 | NYX 338 | ODP 339 | OMC 340 | OMX 341 | ORCL 342 | OXY 343 | PAYX 344 | PBG 345 | PBI 346 | PCAR 347 | PCG 348 | PCL 349 | PCP 350 | PDCO 351 | PEG 352 | PEP 353 | PFE 354 | PFG 355 | PG 356 | PGN 357 | PGR 358 | PH 359 | PHM 360 | PKI 361 | PLD 362 | PLL 363 | PNC 364 | PNW 365 | POM 366 | PPG 367 | PPL 368 | PRU 369 | PSA 370 | PTV 371 | PX 372 | Q 373 | QCOM 374 | QLGC 375 | R 376 | RAI 377 | RDC 378 | RF 379 | RHI 380 | RIG 381 | RL 382 | ROH 383 | ROK 384 | RRC 385 | RRD 386 | RSH 387 | RTN 388 | S 389 | SAF 390 | SBUX 391 | SCHW 392 | SE 393 | SEE 394 | SGP 395 | SHLD 396 | SHW 397 | SIAL 398 | SII 399 | SLB 400 | SLE 401 | SLM 402 | SNA 403 | SNDK 404 | SNV 405 | SO 406 | SPG 407 | SPLS 408 | SRE 409 | SSP 410 | STI 411 | STJ 412 | STR 413 | STT 414 | STZ 415 | SUN 416 | SVU 417 | SWK 418 | SWY 419 | SYK 420 | SYMC 421 | SYY 422 | T 423 | TAP 424 | TDC 425 | TE 426 | TEG 427 | TEL 428 | TER 429 | TEX 430 | TGT 431 | THC 432 | TIE 433 | TIF 434 | TJX 435 | TLAB 436 | TMK 437 | TMO 438 | TROW 439 | TRV 440 | TSN 441 | TSO 442 | TWX 443 | TXN 444 | TXT 445 | TYC 446 | UIS 447 | UNH 448 | UNM 449 | UNP 450 | UPS 451 | USB 452 | UST 453 | UTX 454 | VAR 455 | VFC 456 | VIA.B 457 | VLO 458 | VMC 459 | VNO 460 | VRSN 461 | VZ 462 | WAG 463 | WAMUQ 464 | WAT 465 | WB 466 | WEN 467 | WFC 468 | WFM 469 | WFR 470 | WFT 471 | WHR 472 | WIN 473 | WLP 474 | WM 475 | WMB 476 | WMT 477 | WPI 478 | WPO 479 | WU 480 | WWY 481 | WY 482 | WYE 483 | WYN 484 | X 485 | XEL 486 | XL 487 | XLNX 488 | XOM 489 | XRX 490 | XTO 491 | YHOO 492 | YUM 493 | ZION 494 | ZMH 495 | -------------------------------------------------------------------------------- /utils/lists/SP500_2012.py: -------------------------------------------------------------------------------- 1 | all_symbols = [ 2 | 'A', 'AA', 'AAPL', 'ABC', 'ABT', 'ACE', 'ACN', 'ADBE', 'ADI', 'ADM', 'ADP', 'ADSK', 'AEE', 'AEP', 'AES', 'AET', 'AFL', 'AGN', 'AIG', 'AIV', 'AIZ', 'AKAM', 'ALL', 'ALTR', 'ALXN', 'AMAT', 'AMD', 'AMGN', 'AMP', 'AMT', 'AMZN', 'AN', 'ANF', 'ANR', 'AON', 'APA', 'APC', 'APD', 'APH', 'APOL', 'ARG', 'ATI', 'AVB', 'AVP', 'AVY', 'AXP', 'AZO', 'BA', 'BAC', 'BAX', 'BBBY', 'BBT', 'BBY', 'BCR', 'BDX', 'BEAM', 'BEN', 'BF.B', 'BHI', 'BIG', 'BIIB', 'BK', 'BLK', 'BLL', 'BMC', 'BMS', 'BMY', 'BRCM', 'BRK.B', 'BSX', 'BTU', 'BWA', 'BXP', 'C', 'CA', 'CAG', 'CAH', 'CAM', 'CAT', 'CB', 'CBE', 'CBG', 'CBS', 'CCE', 'CCI', 'CCL', 'CELG', 'CERN', 'CF', 'CFN', 'CHK', 'CHRW', 'CI', 'CINF', 'CL', 'CLF', 'CLX', 'CMA', 'CMCSA', 'CME', 'CMG', 'CMI', 'CMS', 'CNP', 'CNX', 'COF', 'COG', 'COH', 'COL', 'COP', 'COST', 'COV', 'CPB', 'CRM', 'CSC', 'CSCO', 'CSX', 'CTAS', 'CTL', 'CTSH', 'CTXS', 'CVC', 'CVH', 'CVS', 'CVX', 'D', 'DD', 'DE', 'DELL', 'DF', 'DFS', 'DGX', 'DHI', 'DHR', 'DIS', 'DISCA', 'DLTR', 'DNB', 'DNR', 'DO', 'DOV', 'DOW', 'DPS', 'DRI', 'DTE', 'DTV', 'DUK', 'DV', 'DVA', 'DVN', 'EA', 'EBAY', 'ECL', 'ED', 'EFX', 'EIX', 'EL', 'EMC', 'EMN', 'EMR', 'EOG', 'EQR', 'EQT', 'ESRX', 'ESV', 'ETFC', 'ETN', 'ETR', 'EW', 'EXC', 'EXPD', 'EXPE', 'F', 'FAST', 'FCX', 'FDO', 'FDX', 'FE', 'FFIV', 'FHN', 'FII', 'FIS', 'FISV', 'FITB', 'FLIR', 'FLR', 'FLS', 'FMC', 'FOSL', 'FRX', 'FSLR', 'FTI', 'FTR', 'GAS', 'GCI', 'GD', 'GE', 'GILD', 'GIS', 'GLW', 'GME', 'GNW', 'GOOG', 'GPC', 'GPS', 'GS', 'GT', 'GWW', 'HAL', 'HAR', 'HAS', 'HBAN', 'HCBK', 'HCN', 'HCP', 'HD', 'HES', 'HIG', 'HNZ', 'HOG', 'HON', 'HOT', 'HP', 'HPQ', 'HRB', 'HRL', 'HRS', 'HSP', 'HST', 'HSY', 'HUM', 'IBM', 'ICE', 'IFF', 'IGT', 'INTC', 'INTU', 'IP', 'IPG', 'IR', 'IRM', 'ISRG', 'ITW', 'IVZ', 'JBL', 'JCI', 'JCP', 'JDSU', 'JEC', 'JNJ', 'JNPR', 'JOY', 'JPM', 'JWN', 'K', 'KEY', 'KFT', 'KIM', 'KLAC', 'KMB', 'KMI', 'KMX', 'KO', 'KR', 'KSS', 'L', 'LEG', 'LEN', 'LH', 'LIFE', 'LLL', 'LLTC', 'LLY', 'LM', 'LMT', 'LNC', 'LO', 'LOW', 'LRCX', 'LSI', 'LTD', 'LUK', 'LUV', 'LXK', 'LYB', 'M', 'MA', 'MAR', 'MAS', 'MAT', 'MCD', 'MCHP', 'MCK', 'MCO', 'MDT', 'MET', 'MHP', 'MJN', 'MKC', 'MMC', 'MMM', 'MNST', 'MO', 'MOLX', 'MON', 'MOS', 'MPC', 'MRK', 'MRO', 'MS', 'MSFT', 'MSI', 'MTB', 'MU', 'MUR', 'MWV', 'MYL', 'NBL', 'NBR', 'NDAQ', 'NE', 'NEE', 'NEM', 'NFLX', 'NFX', 'NI', 'NKE', 'NOC', 'NOV', 'NRG', 'NSC', 'NTAP', 'NTRS', 'NU', 'NUE', 'NVDA', 'NWL', 'NWSA', 'NYX', 'OI', 'OKE', 'OMC', 'ORCL', 'ORLY', 'OXY', 'PAYX', 'PBCT', 'PBI', 'PCAR', 'PCG', 'PCL', 'PCLN', 'PCP', 'PCS', 'PDCO', 'PEG', 'PEP', 'PFE', 'PFG', 'PG', 'PGR', 'PH', 'PHM', 'PKI', 'PLD', 'PLL', 'PM', 'PNC', 'PNW', 'POM', 'PPG', 'PPL', 'PRGO', 'PRU', 'PSA', 'PWR', 'PX', 'PXD', 'QCOM', 'QEP', 'R', 'RAI', 'RDC', 'RF', 'RHI', 'RHT', 'RL', 'ROK', 'ROP', 'ROST', 'RRC', 'RRD', 'RSG', 'RTN', 'S', 'SAI', 'SBUX', 'SCG', 'SCHW', 'SE', 'SEE', 'SHLD', 'SHW', 'SIAL', 'SJM', 'SLB', 'SLM', 'SNA', 'SNDK', 'SNI', 'SO', 'SPG', 'SPLS', 'SRCL', 'SRE', 'STI', 'STJ', 'STT', 'STX', 'STZ', 'SWK', 'SWN', 'SWY', 'SYK', 'SYMC', 'SYY', 'T', 'TAP', 'TDC', 'TE', 'TEG', 'TEL', 'TER', 'TGT', 'THC', 'TIE', 'TIF', 'TJX', 'TMK', 'TMO', 'TRIP', 'TROW', 'TRV', 'TSN', 'TSO', 'TSS', 'TWC', 'TWX', 'TXN', 'TXT', 'TYC', 'UNH', 'UNM', 'UNP', 'UPS', 'URBN', 'USB', 'UTX', 'V', 'VAR', 'VFC', 'VIAB', 'VLO', 'VMC', 'VRSN', 'VTR', 'VZ', 'WAG', 'WAT', 'WDC', 'WEC', 'WFC', 'WFM', 'WHR', 'WIN', 'WLP', 'WM', 'WMB', 'WMT', 'WPI', 'WPO', 'WPX', 'WU', 'WY', 'WYN', 'WYNN', 'X', 'XEL', 'XL', 'XLNX', 'XOM', 'XRAY', 'XRX', 'XYL', 'YHOO', 'YUM', 'ZION', 'ZMH' 3 | ] -------------------------------------------------------------------------------- /utils/lists/SP500_2012.txt: -------------------------------------------------------------------------------- 1 | A 2 | AA 3 | AAPL 4 | ABC 5 | ABT 6 | ACE 7 | ACN 8 | ADBE 9 | ADI 10 | ADM 11 | ADP 12 | ADSK 13 | AEE 14 | AEP 15 | AES 16 | AET 17 | AFL 18 | AGN 19 | AIG 20 | AIV 21 | AIZ 22 | AKAM 23 | ALL 24 | ALTR 25 | ALXN 26 | AMAT 27 | AMD 28 | AMGN 29 | AMP 30 | AMT 31 | AMZN 32 | AN 33 | ANF 34 | ANR 35 | AON 36 | APA 37 | APC 38 | APD 39 | APH 40 | APOL 41 | ARG 42 | ATI 43 | AVB 44 | AVP 45 | AVY 46 | AXP 47 | AZO 48 | BA 49 | BAC 50 | BAX 51 | BBBY 52 | BBT 53 | BBY 54 | BCR 55 | BDX 56 | BEAM 57 | BEN 58 | BF.B 59 | BHI 60 | BIG 61 | BIIB 62 | BK 63 | BLK 64 | BLL 65 | BMC 66 | BMS 67 | BMY 68 | BRCM 69 | BRK.B 70 | BSX 71 | BTU 72 | BWA 73 | BXP 74 | C 75 | CA 76 | CAG 77 | CAH 78 | CAM 79 | CAT 80 | CB 81 | CBE 82 | CBG 83 | CBS 84 | CCE 85 | CCI 86 | CCL 87 | CELG 88 | CERN 89 | CF 90 | CFN 91 | CHK 92 | CHRW 93 | CI 94 | CINF 95 | CL 96 | CLF 97 | CLX 98 | CMA 99 | CMCSA 100 | CME 101 | CMG 102 | CMI 103 | CMS 104 | CNP 105 | CNX 106 | COF 107 | COG 108 | COH 109 | COL 110 | COP 111 | COST 112 | COV 113 | CPB 114 | CRM 115 | CSC 116 | CSCO 117 | CSX 118 | CTAS 119 | CTL 120 | CTSH 121 | CTXS 122 | CVC 123 | CVH 124 | CVS 125 | CVX 126 | D 127 | DD 128 | DE 129 | DELL 130 | DF 131 | DFS 132 | DGX 133 | DHI 134 | DHR 135 | DIS 136 | DISCA 137 | DLTR 138 | DNB 139 | DNR 140 | DO 141 | DOV 142 | DOW 143 | DPS 144 | DRI 145 | DTE 146 | DTV 147 | DUK 148 | DV 149 | DVA 150 | DVN 151 | EA 152 | EBAY 153 | ECL 154 | ED 155 | EFX 156 | EIX 157 | EL 158 | EMC 159 | EMN 160 | EMR 161 | EOG 162 | EQR 163 | EQT 164 | ESRX 165 | ESV 166 | ETFC 167 | ETN 168 | ETR 169 | EW 170 | EXC 171 | EXPD 172 | EXPE 173 | F 174 | FAST 175 | FCX 176 | FDO 177 | FDX 178 | FE 179 | FFIV 180 | FHN 181 | FII 182 | FIS 183 | FISV 184 | FITB 185 | FLIR 186 | FLR 187 | FLS 188 | FMC 189 | FOSL 190 | FRX 191 | FSLR 192 | FTI 193 | FTR 194 | GAS 195 | GCI 196 | GD 197 | GE 198 | GILD 199 | GIS 200 | GLW 201 | GME 202 | GNW 203 | GOOG 204 | GPC 205 | GPS 206 | GS 207 | GT 208 | GWW 209 | HAL 210 | HAR 211 | HAS 212 | HBAN 213 | HCBK 214 | HCN 215 | HCP 216 | HD 217 | HES 218 | HIG 219 | HNZ 220 | HOG 221 | HON 222 | HOT 223 | HP 224 | HPQ 225 | HRB 226 | HRL 227 | HRS 228 | HSP 229 | HST 230 | HSY 231 | HUM 232 | IBM 233 | ICE 234 | IFF 235 | IGT 236 | INTC 237 | INTU 238 | IP 239 | IPG 240 | IR 241 | IRM 242 | ISRG 243 | ITW 244 | IVZ 245 | JBL 246 | JCI 247 | JCP 248 | JDSU 249 | JEC 250 | JNJ 251 | JNPR 252 | JOY 253 | JPM 254 | JWN 255 | K 256 | KEY 257 | KFT 258 | KIM 259 | KLAC 260 | KMB 261 | KMI 262 | KMX 263 | KO 264 | KR 265 | KSS 266 | L 267 | LEG 268 | LEN 269 | LH 270 | LIFE 271 | LLL 272 | LLTC 273 | LLY 274 | LM 275 | LMT 276 | LNC 277 | LO 278 | LOW 279 | LRCX 280 | LSI 281 | LTD 282 | LUK 283 | LUV 284 | LXK 285 | LYB 286 | M 287 | MA 288 | MAR 289 | MAS 290 | MAT 291 | MCD 292 | MCHP 293 | MCK 294 | MCO 295 | MDT 296 | MET 297 | MHP 298 | MJN 299 | MKC 300 | MMC 301 | MMM 302 | MNST 303 | MO 304 | MOLX 305 | MON 306 | MOS 307 | MPC 308 | MRK 309 | MRO 310 | MS 311 | MSFT 312 | MSI 313 | MTB 314 | MU 315 | MUR 316 | MWV 317 | MYL 318 | NBL 319 | NBR 320 | NDAQ 321 | NE 322 | NEE 323 | NEM 324 | NFLX 325 | NFX 326 | NI 327 | NKE 328 | NOC 329 | NOV 330 | NRG 331 | NSC 332 | NTAP 333 | NTRS 334 | NU 335 | NUE 336 | NVDA 337 | NWL 338 | NWSA 339 | NYX 340 | OI 341 | OKE 342 | OMC 343 | ORCL 344 | ORLY 345 | OXY 346 | PAYX 347 | PBCT 348 | PBI 349 | PCAR 350 | PCG 351 | PCL 352 | PCLN 353 | PCP 354 | PCS 355 | PDCO 356 | PEG 357 | PEP 358 | PFE 359 | PFG 360 | PG 361 | PGR 362 | PH 363 | PHM 364 | PKI 365 | PLD 366 | PLL 367 | PM 368 | PNC 369 | PNW 370 | POM 371 | PPG 372 | PPL 373 | PRGO 374 | PRU 375 | PSA 376 | PSX 377 | PWR 378 | PX 379 | PXD 380 | QCOM 381 | QEP 382 | R 383 | RAI 384 | RDC 385 | RF 386 | RHI 387 | RHT 388 | RL 389 | ROK 390 | ROP 391 | ROST 392 | RRC 393 | RRD 394 | RSG 395 | RTN 396 | S 397 | SAI 398 | SBUX 399 | SCG 400 | SCHW 401 | SE 402 | SEE 403 | SHLD 404 | SHW 405 | SIAL 406 | SJM 407 | SLB 408 | SLM 409 | SNA 410 | SNDK 411 | SNI 412 | SO 413 | SPG 414 | SPLS 415 | SRCL 416 | SRE 417 | STI 418 | STJ 419 | STT 420 | STX 421 | STZ 422 | SUN 423 | SWK 424 | SWN 425 | SWY 426 | SYK 427 | SYMC 428 | SYY 429 | T 430 | TAP 431 | TDC 432 | TE 433 | TEG 434 | TEL 435 | TER 436 | TGT 437 | THC 438 | TIE 439 | TIF 440 | TJX 441 | TMK 442 | TMO 443 | TRIP 444 | TROW 445 | TRV 446 | TSN 447 | TSO 448 | TSS 449 | TWC 450 | TWX 451 | TXN 452 | TXT 453 | TYC 454 | UNH 455 | UNM 456 | UNP 457 | UPS 458 | URBN 459 | USB 460 | UTX 461 | V 462 | VAR 463 | VFC 464 | VIAB 465 | VLO 466 | VMC 467 | VNO 468 | VRSN 469 | VTR 470 | VZ 471 | WAG 472 | WAT 473 | WDC 474 | WEC 475 | WFC 476 | WFM 477 | WHR 478 | WIN 479 | WLP 480 | WM 481 | WMB 482 | WMT 483 | WPI 484 | WPO 485 | WPX 486 | WU 487 | WY 488 | WYN 489 | WYNN 490 | X 491 | XEL 492 | XL 493 | XLNX 494 | XOM 495 | XRAY 496 | XRX 497 | XYL 498 | YHOO 499 | YUM 500 | ZION 501 | ZMH 502 | -------------------------------------------------------------------------------- /utils/lists/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielfrg/PythonFinance/98f5b090d9180c4cbb9a7e7f14132f3424d68e35/utils/lists/__init__.py --------------------------------------------------------------------------------