def retrieve_yahoo_data(ticker=None, startdate="20000101", enddate=None): """ Downloads quote, dividend, and split data from Yahoo! Finance for a security. """ if enddate == None: enddate = todays_date() # convert input to yahoo standard startdate = yahoo_date_format(startdate) enddate = yahoo_date_format(enddate) df = retrieve_yahoo_quote(ticker=ticker, startdate=startdate, enddate=enddate) df_dividend = retrieve_yahoo_dividends(ticker=ticker, startdate=startdate, enddate=enddate) df_splits = retrieve_yahoo_splits(ticker=ticker, startdate=startdate, enddate=enddate) df = df.join(df_dividend, how="left").fillna(0.0) df = df.join(df_splits["Modifier"], how="left").fillna(method="bfill").fillna(1.0) return df
def buy_security(self, date, ticker, currency="USD", price=None, quantity=0): # potentially add ticker to list if ticker not in self.tickers: self.add_security(ticker) # print('adding', ticker) # and to archive if ticker not in self.tickers_archive: self.add_security_archive(ticker) # get closing price of security for transaction date if price not provided try: if np.isnan(price): price = self.securities[ticker].get_price_at(date) except: if price is None: price = self.securities[ticker].get_price_at(date) # modify quantity for subsequent stock splits quantity = self.securities[ticker].modify_quantity(date, quantity) for i in range(np.int(quantity)): self.prices[ticker].append(price) self.prices_lifo[ticker].append(price) self.prices_fifo[ticker].append(price) # store point in time value in wallet self.wallet = self.wallet.append( { "Date": date, "Change": -1.0 * price * quantity }, ignore_index=True).sort_values("Date") # store transaction in df self.transactions = self.transactions.append( { "Date": date, "Transaction": "buy", "Ticker": ticker, "Currency": currency, "Price": 1.0 * price, "Quantity": 1.0 * quantity, "TradeValue": 1.0 * price * quantity, }, ignore_index=True, sort=False, ).sort_values("Date") self.cash = self.get_cash(date=todays_date()) print("buying {0:.2f} {1} (new balance: {2:.2f} {3})".format( quantity, ticker, self.cash, currency))
def read_treasury_csv(path=None, startdate="2000-01-01", enddate=None): """ Read locally stored csv with data from US Deparment of the Treasury. """ if enddate == None: enddate = todays_date() # convert dates to pandas format startdate = standard_date_format(startdate) enddate = standard_date_format(enddate) _df = pd.read_csv(path, index_col="Date", parse_dates=True) return _df.loc[(_df.index >= startdate) & (_df.index <= enddate)]
def read_yahoo_csv(path=None, startdate="2000-01-01", enddate=None): """ Read locally stored csv with data from Yahoo! Finance for a security. """ if enddate == None: enddate = todays_date() # convert dates to pandas format startdate = standard_date_format(startdate) enddate = standard_date_format(enddate) df = pd.read_csv(path, index_col="Date", parse_dates=True) return df.loc[(df.index >= startdate) & (df.index <= enddate)]
def dividend(self, date, ticker="", currency="USD", price=1.0, quantity=0): """ """ self.wallet = self.wallet.append( { "Date": date, "Change": 1.0 * price * quantity }, ignore_index=True).sort_values("Date") # store transaction in df self.transactions = self.transactions.append( { "Date": date, "Transaction": "dividend", "Ticker": ticker, "Currency": currency, "Price": 1.0 * price, "Quantity": 1.0 * quantity, "TradeValue": 1.0 * price * quantity, }, ignore_index=True, sort=False, ).sort_values("Date") # store dividends in df self.dividends = self.dividends.append( { "Date": date, "Ticker": ticker, "Amount": 1.0 * price * quantity }, ignore_index=True, ).sort_values("Date") self.cash = self.get_cash(date=todays_date()) if ticker == "" or ticker != ticker: print("interest {0:.2f} {2} (new balance: {1:.2f} {2})".format( quantity * price, self.cash, currency)) else: print("dividend {0} {1:.2f} {3} (new balance: {2:.2f} {3})".format( ticker, quantity * price, self.cash, currency))
def withdraw_cash(self, date, currency="USD", price=1.0, quantity=0): """ Takes amount of quantity*price out of wallet """ self.wallet = self.wallet.append( { "Date": date, "Change": -1.0 * price * quantity }, ignore_index=True).sort_values("Date") # store transaction in df self.transactions = self.transactions.append( { "Date": date, "Transaction": "withdraw", "Ticker": np.nan, "Currency": currency, "Price": 1.0 * price, "Quantity": 1.0 * quantity, "TradeValue": 1.0 * price * quantity, }, ignore_index=True, sort=False, ).sort_values("Date") # store payments in df self.payments = self.payments.append( { "Date": date, "In": 0.0, "Out": 1.0 * price * quantity }, ignore_index=True).sort_values("Date") self.cash = self.get_cash(date=todays_date()) if self.cash < 0.0: print("Warning, cash balance negative: {0:.2f} {1}".format( self.cash, currency)) else: print("withdrawing {0:.2f} {2} (new balance: {1:.2f} {2})".format( quantity * price, self.cash, currency)) #
def deposit_cash(self, date, currency="USD", price=1.0, quantity=0): """ Adds an amount of quantity*price to the wallet Price acts as exchange rate if currency is not USD """ self.wallet = self.wallet.append( { "Date": date, "Change": 1.0 * price * quantity }, ignore_index=True).sort_values("Date") # store transaction in df self.transactions = self.transactions.append( { "Date": date, "Transaction": "deposit", "Ticker": np.nan, "Currency": currency, "Price": 1.0 * price, "Quantity": 1.0 * quantity, "TradeValue": 1.0 * price * quantity, }, ignore_index=True, sort=False, ).sort_values("Date") # store payment in df self.payments = self.payments.append( { "Date": date, "In": 1.0 * price * quantity, "Out": 0.0 }, ignore_index=True).sort_values("Date") self.cash = self.get_cash(date=todays_date()) print("depositing {0:.2f} {2} (new balance: {1:.2f} {2})".format( quantity * price, self.cash, currency))
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 __init__(self, name): super().__init__(name) self.securities = {} self.securities_archive = {} self.tickers = [] self.tickers_archive = [] self.dividends = pd.DataFrame(columns=["Date", "Ticker", "Amount"]) self.payments = pd.DataFrame(columns=["Date", "In", "Out"]) self.wallet = pd.DataFrame(columns=["Date", "Change"]) self.total_portfolio_value = 0.0 self.total_security_value = 0.0 self.cash = 0.0 self.return_value = 0.0 self.return_rate = 0.0 self.prices = {} self.prices_fifo = {} self.prices_lifo = {} self.index = 0 self.benchmark_ticker = "sp500" self.benchmark = None self.transactions = pd.DataFrame(columns=[ "Date", "Transaction", "Ticker", "Currency", "Price", "Quantity" ]) self.date = standard_date_format(todays_date())
def retrieve_treasury_yield_curve_rates( url="https://www.treasury.gov/resource-center/data-chart-center/interest-rates/Pages/TextView.aspx?data=yieldAll", startdate="20000101", enddate=None, ): """ Download yield curve rates data from US Deparment of the Treasury. """ if enddate == None: enddate = todays_date() # convert dates to pandas format startdate = standard_date_format(startdate) enddate = standard_date_format(enddate) _headers = { "User-Agent": "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11" } # use request to retrieve data req = urllib.request.Request(url, headers=_headers) f = urllib.request.urlopen(req) html_data = f.read().decode("utf-8") soup = BeautifulSoup(html_data, "lxml") table = soup.find("table", {"class": "t-chart"}) _df = pd.read_html(str(table), header=0, index_col="Date", parse_dates=True)[0] return _df.loc[(_df.index >= startdate) & (_df.index <= enddate)]
def sell_security(self, date, ticker, currency="USD", price=None, quantity=0): # get closing price of security for transaction date if price not provided try: if np.isnan(price): price = self.securities[ticker].get_price_at(date) except: if price is None: price = self.securities[ticker].get_price_at(date) # modify quantity for subsequent stock splits quantity = self.securities[ticker].modify_quantity(date, quantity) # remove number of securities from prices deque for i in range(np.int(quantity)): _ = self.prices_fifo[ticker].popleft() _ = self.prices_lifo[ticker].pop() # make sure security is fully removed, correct for rounding errors _df = self.transactions.loc[self.transactions.Transaction.isin( ("buy", "sell")), :].copy() _df.loc[_df.Transaction == "sell", "Quantity"] = _df.loc[_df.Transaction == "sell", "Quantity"].apply(lambda x: -x) # set quantity to exactly match remaining quantity in portfolio if _df.groupby( by=["Ticker"])["Quantity"].sum()[ticker] <= quantity * 1.0001: quantity = _df.groupby(by=["Ticker"])["Quantity"].sum()[ticker] # store point in time value in wallet self.wallet = self.wallet.append( { "Date": date, "Change": 1.0 * price * quantity }, ignore_index=True).sort_values("Date") # store transaction in df self.transactions = self.transactions.append( { "Date": date, "Transaction": "sell", "Ticker": ticker, "Currency": currency, "Price": 1.0 * price, "Quantity": 1.0 * quantity, "TradeValue": 1.0 * price * quantity, }, ignore_index=True, sort=False, ).sort_values("Date") self.cash = self.get_cash(date=todays_date()) print("selling {0:.2f} {1} (new balance: {2:.2f} {3})".format( quantity, ticker, self.cash, currency)) # potentially remove ticker from list _df = self.transactions.loc[self.transactions.Transaction.isin( ("buy", "sell")), :].copy() _df.loc[_df.Transaction == "sell", "Quantity"] = _df.loc[_df.Transaction == "sell", "Quantity"].apply(lambda x: -x) if _df.groupby(by=["Ticker"])["Quantity"].sum()[ticker] <= 0.0001: self.remove_security(ticker)