def load(self, datadir="../data/", start=None, end=None): """ Tries to load from csv first, then pulls from Yahoo! """ filepath = "{0}{1}.csv".format(datadir, self.ticker) print("Checking {}".format(filepath)) if start is None: start = self.start else: start = standard_date_format(last_trading_day(start)) if end is None: end = self.end else: end = standard_date_format(last_trading_day(end)) if path.isfile(filepath): self.data = read_yahoo_csv(path=filepath) csv_start = standard_date_format(self.data.index.min()) csv_end = standard_date_format(self.data.index.max()) if (pd.to_datetime(csv_end) < pd.to_datetime(end)) | ( pd.to_datetime(csv_start) > pd.to_datetime(start) ): _refresh_success = self.refresh( datadir=datadir, start=min(start, csv_start), end=max(end, csv_end) ) else: _refresh_success = 1 if _refresh_success: self.data = read_yahoo_csv(path=filepath, startdate=start, enddate=end) else: self.data = retrieve_yahoo_data( ticker=self.ticker, startdate=start, enddate=end ) self.save(filename="{}.csv".format(self.ticker), datadir=datadir)
def __init__(self, name, start=None, end=None): super().__init__(name) if start is None: self.start = standard_date_format(last_trading_day("2000-01-01")) else: self.start = standard_date_format(last_trading_day(start)) if end is None: self.end = standard_date_format(last_trading_day(todays_date())) else: self.end = standard_date_format(last_trading_day(end)) self.ticker = name self.set_name(name) self.load(start=self.start, end=self.end) self.get_last_price() self.get_max_price() self.get_min_price() self.get_median_price() self.get_mean_price() self.get_std_price() self.dividends = 0.0 self.benchmark_ticker = "sp500" self.benchmark = None
def refresh(self, datadir="../data/", start=None, end=None): """ Tries to load from csv first, then pulls from Yahoo! """ if start is None: start = self.start else: start = standard_date_format(last_trading_day(start)) if end is None: end = self.end else: end = standard_date_format(last_trading_day(end)) try: self.data = retrieve_yahoo_data( ticker=self.ticker, startdate=start, enddate=end ) self.save(filename="{}.csv".format(self.ticker), datadir=datadir) return 1 except: print("Refresh failed") return 0
def modify_quantity(self, date, quantity): date = last_trading_day(date) try: return quantity * self.data.loc[self.data.index == date, "Modifier"].values[0] except: return quantity
def get_price_at(self, date, column="Close"): date = last_trading_day(date) return self.data.loc[self.data.index == date, column].values[0]
def parse_portfolio(df=None, p=None): """ Takes a dataframe with transactions and performs those on a given portfolio Parameters ========== df : input dataframe p : portfolio (Portfolio class object) Returns ======= p : modified portfolio (Portfolio class object) """ # use a lower bound on the minimum number of days pulled minimum_date_for_data = last_trading_day() - timedelta(weeks=1) # put input dataframe(s) in list dfs = [] if type(df) == pd.core.frame.DataFrame: dfs.append(df) else: dfs.extend(df) # loop through list of dataframes Tickers_all = [] for df in dfs: Tickers_all = Tickers_all + list(df.Ticker.values) # load data for all securities for ticker in list(set(Tickers_all)): if ticker: if ticker not in p.securities_archive: if str(ticker).isalnum() & (str(ticker) != "nan"): print("Adding ", ticker) min_date = minimum_date_for_data for df in dfs: if ticker in list(set(df.Ticker)): first_date = min(df.loc[df.Ticker == ticker, "Date"].values) min_date = min(first_date, min_date) p.add_security_archive(ticker, min_date) for df in dfs: # define a priority for transaction types so ordering makes sense df.loc[df.Transaction == "deposit", "Priority"] = 1 df.loc[df.Transaction == "Contribution", "Priority"] = 1 df.loc[df.Transaction == "Funds Received", "Priority"] = 1 df.loc[df.Transaction == "Conversion (incoming)", "Priority"] = 1 df.loc[df.Transaction == "buy", "Priority"] = 2 df.loc[df.Transaction == "Buy", "Priority"] = 2 df.loc[df.Transaction == "Reinvestment", "Priority"] = 2 df.loc[df.Transaction == "dividend", "Priority"] = 3 df.loc[df.Transaction == "Dividend", "Priority"] = 3 df.loc[df.Transaction == "sell", "Priority"] = 4 df.loc[df.Transaction == "Sell", "Priority"] = 4 df.loc[df.Transaction == "withdraw", "Priority"] = 5 df.loc[df.Transaction == "Distribution", "Priority"] = 5 df.sort_values(by=["Date", "Priority"], inplace=True) for index, row in df.iterrows(): if row.notnull()["Date"]: # print(row['Date'], row['Transaction'], row['Ticker'], row['Currency'], row['Price'], row['Quantity']) if str.lower(row["Transaction"]) == "buy": p.buy_security( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=row["Price"], quantity=row["Quantity"], ) elif str.lower(row["Transaction"]) == "sell": p.sell_security( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=row["Price"], quantity=row["Quantity"], ) # FINRA fee of $.000119 per share up to $5.95 #_FINRAfee = min( # max(ceil(0.0119 * row["Quantity"]), 1.0) / 100.0, 5.95 #) # SEC fee of $.000013 per trade of up to $1M #if not np.isnan(row["Price"]): # _SECfee = max(ceil(row["Quantity"] * row["Price"] / 800.0), 1.0) / 100.0 #else: # _SECfee = 0.000013 # need to find a better place to put this fee where price is known #p.wallet = p.wallet.append( # {"Date": row["Date"], "Change": -_FINRAfee - _SECfee}, # ignore_index=True, #) elif str.lower(row["Transaction"]) == "deposit": p.deposit_cash( date=row["Date"], currency=row["Currency"], price=row["Price"], quantity=row["Quantity"], ) elif str.lower(row["Transaction"]) == "withdraw": p.withdraw_cash( date=row["Date"], currency=row["Currency"], price=row["Price"], quantity=row["Quantity"], ) elif row["Transaction"] == "Dividend": p.dividend( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=1.0, quantity=row["Dollars"], ) elif row["Transaction"] == "dividend": p.dividend( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=1.0, quantity=row["Quantity"], ) else: pass else: pass return p
def parse_portfolio_vanguard(df=None, p=None): """ Takes a dataframe with transactions in Vanguard format and performs those on a given portfolio Parameters ========== df : input dataframe p : portfolio (Portfolio class object) Returns ======= p : modified portfolio (Portfolio class object) """ # use a lower bound on the minimum number of days pulled minimum_date_for_data = last_trading_day() - timedelta(weeks=1) # put input dataframe(s) in list dfs = [] if type(df) == pd.core.frame.DataFrame: dfs.append(df) else: dfs.extend(df) # loop through list of dataframes Tickers_all = [] for df in dfs: Tickers_all = Tickers_all + list(df.Ticker.values) # load data for all securities for ticker in list(set(Tickers_all)): if ticker: if ticker not in p.securities_archive: if str(ticker).isalnum() & (str(ticker) != "nan"): print("Adding ", ticker) min_date = minimum_date_for_data for df in dfs: if ticker in list(set(df.Ticker)): first_date = min(df.loc[df.Ticker == ticker, "Date"].values) min_date = min(first_date, min_date) p.add_security_archive(ticker, min_date) for df in dfs: # define a priority for transaction types so ordering makes sense df.loc[df.Transaction == "deposit", "Priority"] = 1 df.loc[df.Transaction == "Contribution", "Priority"] = 1 df.loc[df.Transaction == "Funds Received", "Priority"] = 1 df.loc[df.Transaction == "Conversion (incoming)", "Priority"] = 1 df.loc[df.Transaction == "buy", "Priority"] = 2 df.loc[df.Transaction == "Buy", "Priority"] = 2 df.loc[df.Transaction == "Reinvestment", "Priority"] = 2 df.loc[df.Transaction == "Reinvestment (LT)", "Priority"] = 2 df.loc[df.Transaction == "Reinvestment (ST)", "Priority"] = 2 df.loc[df.Transaction == "dividend", "Priority"] = 3 df.loc[df.Transaction == "Dividend", "Priority"] = 3 df.loc[df.Transaction == "Capital gain (LT)", "Priority"] = 3 df.loc[df.Transaction == "Capital gain (ST)", "Priority"] = 3 df.loc[df.Transaction == "sell", "Priority"] = 4 df.loc[df.Transaction == "Sell", "Priority"] = 4 df.loc[df.Transaction == "Withdrawal", "Priority"] = 5 df.loc[df.Transaction == "withdraw", "Priority"] = 5 df.loc[df.Transaction == "Distribution", "Priority"] = 5 df.sort_values(by=["Date", "Priority"], inplace=True) for index, row in df.iterrows(): if row.notnull()["Date"]: # print(row['Date'], row['Transaction'], row['Ticker'], row['Currency'], row['Price'], row['Quantity'], row['Dollars']) if (row["Transaction"] == "Buy" or row["Transaction"] == "buy"): p.buy_security( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=row["Price"], quantity=row["Quantity"], ) elif (row["Transaction"] == "Sell" or row["Transaction"] == "sell"): p.sell_security( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=row["Price"], quantity=-row["Quantity"], ) # note the minus sign elif (row["Transaction"] == "Contribution" or row["Transaction"] == "Funds Received" or row["Transaction"] == "Conversion (incoming)" or row["Transaction"] == "deposit"): p.deposit_cash( date=row["Date"], currency=row["Currency"], price=1.0, quantity=row["Dollars"], ) elif (row["Transaction"] == "Distribution" or row["Transaction"] == "Withdrawal" or row["Transaction"] == "withdraw"): p.withdraw_cash( date=row["Date"], currency=row["Currency"], price=1.0, quantity=-1.0 * row["Dollars"], ) elif (row["Transaction"] == "Dividend" or row["Transaction"] == "Capital gain (LT)" or row["Transaction"] == "Capital gain (ST)"): p.dividend( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=1.0, quantity=row["Dollars"], ) elif (row["Transaction"] == "Reinvestment" or row["Transaction"] == "Reinvestment (LT)" or row["Transaction"] == "Reinvestment (ST)") and row["Quantity"] != 0: p.buy_security( date=row["Date"], ticker=row["Ticker"], currency=row["Currency"], price=row["Price"], quantity=row["Quantity"], ) else: pass else: pass return p