def __init__(self, symbol, start_date, end_date, key): """ Initialises equity class Parameters ---------- symbol : str Symbol for equity as found on exchange start_date : str or datetime or datetime.date First date of interest in YYYY-MM-DD form end_date : str of datetime or datetime.date Last date of interest in YYYY-MM-DD form key : str Alpha-vantage API key Raises ------ ValueError API Key is invalid Equity symbol does not exist End date is same as or before start date RuntimeError API Call limit reached """ # Convert dates from strings to date objects start_date = _convert_date(start_date) end_date = _convert_date(end_date) # Raises error if date range invalid if end_date <= start_date: raise ValueError("end_date is the same as or before start_date") # Raises error if key is empty string if len(key) == 0: raise ValueError("Invalid API Key") self.symbol = symbol self.start_date = start_date self.end_date = end_date self.key = key # Fetch all data df = self._daily() # Get dates of interest only mask = (df.index >= start_date) & (df.index <= end_date) df = df.loc[mask] # Sort date earliest first df.sort_index(inplace=True) # Set data attribute self.data = df # Set each possible price type self.high = df["2. high"] self.low = df["3. low"] self.open = df["1. open"] self.closed = df["5. adjusted close"]
def test_bad_type(self): """ Tests function with a incorrect type as date """ with self.assertRaises(TypeError): _convert_date(34) with self.assertRaises(TypeError): _convert_date([self.date])
def test_bad_str(self): """ Tests function with a incorrect string input """ with self.assertRaises(ValueError): _convert_date("sdkifsd") with self.assertRaises(ValueError): _convert_date("")
def plot(self, start_date=None, end_date=None): """ Plots closed prices of equity between two dates as a line graph Parameters ---------- start_date : (optional) str or datetime or datetime.date First date to plot in YYYY-MM-DD form, defaults to equity start date end_date : (optional) str of datetime or datetime.date Last date to plot in YYYY-MM-DD form, defaults to equity end date Raises ------ ValueError End date is same as or before start date """ # If no start/end date specified use default if start_date is None: start_date = self.start_date else: start_date = _convert_date(start_date) if end_date is None: end_date = self.end_date else: end_date = _convert_date(end_date) # Raises error if date range invalid if end_date <= start_date: raise ValueError("end_date is the same as or before start_date") # Gets required range only closed = self.closed mask = (closed.index >= start_date) & (closed.index <= end_date) closed = closed.loc[mask] fig, ax = plt.subplots() ax.plot(closed) plt.title(f"{self.symbol} from {start_date} to {end_date}") plt.xlabel("Date") plt.ylabel("Adjusted closed prices ($)") # Put dollar marks infront of y axis formatter = ticker.FormatStrFormatter('$%1.2f') ax.yaxis.set_major_formatter(formatter) plt.grid() plt.show()
def test_str(self): """ Tests function with a string input """ self.assertEqual(self.date, _convert_date(self.date_str))
def plot_closed(self, start_date=None, end_date=None): """ Plots closed prices of both equities between two dates as a line graph Parameters ---------- start_date : (optional) str or datetime or datetime.date First date to plot in YYYY-MM-DD form, defaults to equity start date end_date : (optional) str of datetime or datetime.date Last date to plot in YYYY-MM-DD form, defaults to equity end date Raises ------ ValueError End date is same as or before start date """ # If no start/end date specified use default if start_date is None: start_date = self.start_date else: start_date = _convert_date(start_date) if end_date is None: end_date = self.end_date else: end_date = _convert_date(end_date) # Raises error if date range invalid if end_date <= start_date: raise ValueError('end_date is the same as or before start_date') elif start_date < self.start_date: raise ValueError('start_date can\'t be before pair.start_date') elif end_date > self.end_date: raise ValueError('end_date can\'t be after pair.end_date') # Gets required range only for both equities equity1_closed = self.equity1.closed mask = (equity1_closed.index >= start_date) \ & (equity1_closed.index <= end_date) equity1_closed = equity1_closed.loc[mask] equity2_closed = self.equity2.closed mask = (equity2_closed.index >= start_date) \ & (equity2_closed.index <= end_date) equity2_closed = equity2_closed.loc[mask] fig, ax = plt.subplots() plt.plot(equity1_closed, label=self.equity1.symbol) plt.plot(equity2_closed, label=self.equity2.symbol) title = (f'{self.equity1.symbol} and {self.equity2.symbol} ' f'from {start_date} to {end_date}') plt.title(title) plt.xlabel("Date") plt.ylabel("Adjusted closed prices ($)") # Put dollar marks infront of y axis formatter = ticker.FormatStrFormatter('$%1.2f') ax.yaxis.set_major_formatter(formatter) plt.legend() plt.grid() plt.show()
def test_date(self): """ Tests function with a date input """ self.assertEqual(self.date, _convert_date(self.date))