diff --git a/docs/client.rst b/docs/client.rst index 244a054..cbc2058 100644 --- a/docs/client.rst +++ b/docs/client.rst @@ -106,3 +106,41 @@ See the official documentation for each method for a complete response schema. .. autoclass:: schwab.client.Client.Account :members: :undoc-members: + + ++++++++++++++ +Price History ++++++++++++++ + +Schwab provides price history for equities and ETFs. It does not provide price +history for options, futures, or any other instruments. + +In the raw API, fetching price history is somewhat complicated: the API offers a +single endpoint :meth:`Client.get_price_history` that accepts a complex variety +of inputs, but fails to document them in any meaningful way. + +Thankfully, we've reverse engineered this endpoint and built some helpful +utilities for fetching prices by minute, day, week, etc. Each method can be +called with or without date bounds. When called without date bounds, it returns +all data available. Each method offers a different lookback period, so make sure +to read the documentation below to learn how much data is available. + + +.. automethod:: schwab.client.Client.get_price_history_every_minute +.. automethod:: schwab.client.Client.get_price_history_every_five_minutes +.. automethod:: schwab.client.Client.get_price_history_every_ten_minutes +.. automethod:: schwab.client.Client.get_price_history_every_fifteen_minutes +.. automethod:: schwab.client.Client.get_price_history_every_thirty_minutes +.. automethod:: schwab.client.Client.get_price_history_every_day +.. automethod:: schwab.client.Client.get_price_history_every_week + +For the sake of completeness, here is the documentation for the raw price +history endpoint, in all its complexity. + +.. automethod:: schwab.client.Client.get_price_history +.. autoclass:: schwab.client.Client.PriceHistory + :members: + :undoc-members: + :member-order: bysource + + diff --git a/schwab/client/base.py b/schwab/client/base.py index 4ad8b9c..0d4d104 100644 --- a/schwab/client/base.py +++ b/schwab/client/base.py @@ -182,3 +182,307 @@ def get_accounts(self, *, fields=None): return self._get_request(path, params) + ########################################################################## + # Price History + + class PriceHistory: + class PeriodType(Enum): + DAY = 'day' + MONTH = 'month' + YEAR = 'year' + YEAR_TO_DATE = 'ytd' + + class Period(Enum): + # Daily + ONE_DAY = 1 + TWO_DAYS = 2 + THREE_DAYS = 3 + FOUR_DAYS = 4 + FIVE_DAYS = 5 + TEN_DAYS = 10 + + # Monthly + ONE_MONTH = 1 + TWO_MONTHS = 2 + THREE_MONTHS = 3 + SIX_MONTHS = 6 + + # Year + ONE_YEAR = 1 + TWO_YEARS = 2 + THREE_YEARS = 3 + FIVE_YEARS = 5 + TEN_YEARS = 10 + FIFTEEN_YEARS = 15 + TWENTY_YEARS = 20 + + # Year to date + YEAR_TO_DATE = 1 + + class FrequencyType(Enum): + MINUTE = 'minute' + DAILY = 'daily' + WEEKLY = 'weekly' + MONTHLY = 'monthly' + + class Frequency(Enum): + # Minute + EVERY_MINUTE = 1 + EVERY_FIVE_MINUTES = 5 + EVERY_TEN_MINUTES = 10 + EVERY_FIFTEEN_MINUTES = 15 + EVERY_THIRTY_MINUTES = 30 + + # Other frequencies + DAILY = 1 + WEEKLY = 1 + MONTHLY = 1 + + def get_price_history( + self, + symbol, + *, + period_type=None, + period=None, + frequency_type=None, + frequency=None, + start_datetime=None, + end_datetime=None, + need_extended_hours_data=None, + need_previous_close=None): + '''Get price history for a symbol. + + :param period_type: The type of period to show. + :param period: The number of periods to show. Should not be provided if + ``start_datetime`` and ``end_datetime``. + :param frequency_type: The type of frequency with which a new candle + is formed. + :param frequency: The number of the frequencyType to be included in each + candle. + :param start_datetime: Start date. + :param end_datetime: End date. Default is previous trading day. + :param need_extended_hours_data: If true, return extended hours data. + Default is true. + :param need_previous_close: If true, return the previous close price and + date. + ''' + period_type = self.convert_enum( + period_type, self.PriceHistory.PeriodType) + period = self.convert_enum(period, self.PriceHistory.Period) + frequency_type = self.convert_enum( + frequency_type, self.PriceHistory.FrequencyType) + frequency = self.convert_enum( + frequency, self.PriceHistory.Frequency) + + params = { + 'symbol': symbol, + } + + if period_type is not None: + params['periodType'] = period_type + if period is not None: + params['period'] = period + if frequency_type is not None: + params['frequencyType'] = frequency_type + if frequency is not None: + params['frequency'] = frequency + if start_datetime is not None: + params['startDate'] = self._datetime_as_millis( + 'start_datetime', start_datetime) + if end_datetime is not None: + params['endDate'] = self._datetime_as_millis( + 'end_datetime', end_datetime) + if need_extended_hours_data is not None: + params['needExtendedHoursData'] = need_extended_hours_data + if need_previous_close is not None: + params['needPreviousClose'] = need_previous_close + + path = '/marketdata/v1/pricehistory'.format(symbol) + return self._get_request(path, params) + + + ########################################################################## + # Price history utilities + + + def __normalize_start_and_end_datetimes(self, start_datetime, end_datetime): + if start_datetime is None: + start_datetime = datetime.datetime(year=1971, month=1, day=1) + if end_datetime is None: + end_datetime = (datetime.datetime.utcnow() + + datetime.timedelta(days=7)) + + return start_datetime, end_datetime + + + def get_price_history_every_minute( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a per-minute + granularity. This endpoint currently appears to return up to 48 days of + data. + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.DAY, + period=self.PriceHistory.Period.ONE_DAY, + frequency_type=self.PriceHistory.FrequencyType.MINUTE, + frequency=self.PriceHistory.Frequency.EVERY_MINUTE, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + def get_price_history_every_five_minutes( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a per-five-minutes + granularity. This endpoint currently appears to return approximately + nine months of data. + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.DAY, + period=self.PriceHistory.Period.ONE_DAY, + frequency_type=self.PriceHistory.FrequencyType.MINUTE, + frequency=self.PriceHistory.Frequency.EVERY_FIVE_MINUTES, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + def get_price_history_every_ten_minutes( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a per-ten-minutes + granularity. This endpoint currently appears to return approximately + nine months of data. + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.DAY, + period=self.PriceHistory.Period.ONE_DAY, + frequency_type=self.PriceHistory.FrequencyType.MINUTE, + frequency=self.PriceHistory.Frequency.EVERY_TEN_MINUTES, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + def get_price_history_every_fifteen_minutes( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a per-fifteen-minutes + granularity. This endpoint currently appears to return approximately + nine months of data. + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.DAY, + period=self.PriceHistory.Period.ONE_DAY, + frequency_type=self.PriceHistory.FrequencyType.MINUTE, + frequency=self.PriceHistory.Frequency.EVERY_FIFTEEN_MINUTES, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + def get_price_history_every_thirty_minutes( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a per-thirty-minutes + granularity. This endpoint currently appears to return approximately + nine months of data. + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.DAY, + period=self.PriceHistory.Period.ONE_DAY, + frequency_type=self.PriceHistory.FrequencyType.MINUTE, + frequency=self.PriceHistory.Frequency.EVERY_THIRTY_MINUTES, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + def get_price_history_every_day( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a daily granularity. + The exact period of time over which this endpoint returns data is + unclear, although it has been observed returning data as far back as + 1985 (for ``AAPL``). + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.YEAR, + period=self.PriceHistory.Period.TWENTY_YEARS, + frequency_type=self.PriceHistory.FrequencyType.DAILY, + frequency=self.PriceHistory.Frequency.EVERY_MINUTE, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + def get_price_history_every_week( + self, symbol, *, start_datetime=None, end_datetime=None, + need_extended_hours_data=None, need_previous_close=None): + ''' + Fetch price history for a stock or ETF symbol at a weekly granularity. + The exact period of time over which this endpoint returns data is + unclear, although it has been observed returning data as far back as + 1985 (for ``AAPL``). + ''' + + start_datetime, end_datetime = self.__normalize_start_and_end_datetimes( + start_datetime, end_datetime) + + return self.get_price_history( + symbol, + period_type=self.PriceHistory.PeriodType.YEAR, + period=self.PriceHistory.Period.TWENTY_YEARS, + frequency_type=self.PriceHistory.FrequencyType.WEEKLY, + frequency=self.PriceHistory.Frequency.EVERY_MINUTE, + start_datetime=start_datetime, + end_datetime=end_datetime, + need_extended_hours_data=need_extended_hours_data, + need_previous_close=need_previous_close) + + + diff --git a/tests/client_test.py b/tests/client_test.py index 0196b48..4f205d5 100644 --- a/tests/client_test.py +++ b/tests/client_test.py @@ -999,6 +999,7 @@ def test_get_option_chain_option_type_unchecked(self): 'apikey': API_KEY, 'symbol': 'AAPL', 'optionType': 'S'}) + ''' # get_price_history @@ -1006,16 +1007,16 @@ def test_get_option_chain_option_type_unchecked(self): def test_get_price_history_vanilla(self): self.client.get_price_history(SYMBOL) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY}) + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL}) def test_get_price_history_period_type(self): self.client.get_price_history( SYMBOL, period_type=self.client_class.PriceHistory.PeriodType.MONTH) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'periodType': 'month'}) @@ -1023,8 +1024,8 @@ def test_get_price_history_period_type_unchecked(self): self.client.set_enforce_enums(False) self.client.get_price_history(SYMBOL, period_type='month') self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'periodType': 'month'}) @@ -1032,8 +1033,8 @@ def test_get_price_history_num_periods(self): self.client.get_price_history( SYMBOL, period=self.client_class.PriceHistory.Period.TEN_DAYS) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'period': 10}) @@ -1041,8 +1042,8 @@ def test_get_price_history_num_periods_unchecked(self): self.client.set_enforce_enums(False) self.client.get_price_history(SYMBOL, period=10) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'period': 10}) @@ -1051,8 +1052,8 @@ def test_get_price_history_frequency_type(self): SYMBOL, frequency_type=self.client_class.PriceHistory.FrequencyType.DAILY) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'frequencyType': 'daily'}) @@ -1060,8 +1061,8 @@ def test_get_price_history_frequency_type_unchecked(self): self.client.set_enforce_enums(False) self.client.get_price_history(SYMBOL, frequency_type='daily') self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'frequencyType': 'daily'}) @@ -1070,8 +1071,8 @@ def test_get_price_history_frequency(self): SYMBOL, frequency=self.client_class.PriceHistory.Frequency.EVERY_FIVE_MINUTES) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'frequency': 5}) @@ -1079,8 +1080,8 @@ def test_get_price_history_frequency_unchecked(self): self.client.set_enforce_enums(False) self.client.get_price_history(SYMBOL, frequency=5) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'frequency': 5}) @@ -1088,8 +1089,8 @@ def test_get_price_history_start_datetime(self): self.client.get_price_history( SYMBOL, start_datetime=EARLIER_DATETIME) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'startDate': EARLIER_MILLIS}) @@ -1104,8 +1105,8 @@ def test_get_price_history_start_datetime_str(self): def test_get_price_history_end_datetime(self): self.client.get_price_history(SYMBOL, end_datetime=EARLIER_DATETIME) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'endDate': EARLIER_MILLIS}) @@ -1120,19 +1121,27 @@ def test_get_price_history_end_datetime_str(self): def test_get_price_history_need_extended_hours_data(self): self.client.get_price_history(SYMBOL, need_extended_hours_data=True) self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/{symbol}/pricehistory'), params={ - 'apikey': API_KEY, + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, 'needExtendedHoursData': True}) + def test_get_price_history_need_previous_close(self): + self.client.get_price_history(SYMBOL, need_previous_close=True) + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params={ + 'symbol': SYMBOL, + 'needPreviousClose': True}) + + # get_price_history_every_minute - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_minute_vanilla(self): self.client.get_price_history_every_minute('AAPL') params = { - 'apikey': API_KEY, + 'symbol': 'AAPL', 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1143,16 +1152,16 @@ def test_get_price_history_every_minute_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_minute_start_datetime(self): self.client.get_price_history_every_minute( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1163,16 +1172,16 @@ def test_get_price_history_every_minute_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_minute_end_datetime(self): self.client.get_price_history_every_minute( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1183,16 +1192,16 @@ def test_get_price_history_every_minute_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_minute_empty_extendedhours(self): self.client.get_price_history_every_minute( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1203,16 +1212,16 @@ def test_get_price_history_every_minute_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_minute_extendedhours(self): self.client.get_price_history_every_minute( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1224,18 +1233,59 @@ def test_get_price_history_every_minute_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_minute_empty_previous_close(self): + self.client.get_price_history_every_minute( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_MINUTE + 'frequency': 1, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_minute_previous_close(self): + self.client.get_price_history_every_minute( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_MINUTE + 'frequency': 1, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) + # get_price_history_every_five_minutes - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_five_minutes_vanilla(self): self.client.get_price_history_every_five_minutes('AAPL') params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1246,16 +1296,16 @@ def test_get_price_history_every_five_minutes_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_five_minutes_start_datetime(self): self.client.get_price_history_every_five_minutes( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1266,16 +1316,16 @@ def test_get_price_history_every_five_minutes_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_five_minutes_end_datetime(self): self.client.get_price_history_every_five_minutes( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1286,16 +1336,16 @@ def test_get_price_history_every_five_minutes_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_five_minutes_empty_extendedhours(self): self.client.get_price_history_every_five_minutes( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1306,16 +1356,16 @@ def test_get_price_history_every_five_minutes_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_five_minutes_extendedhours(self): self.client.get_price_history_every_five_minutes( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1327,18 +1377,58 @@ def test_get_price_history_every_five_minutes_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_five_minutes_empty_previous_close(self): + self.client.get_price_history_every_five_minutes( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_FIVE_MINUTES + 'frequency': 5, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_five_minutes_previous_close(self): + self.client.get_price_history_every_five_minutes( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_FIVE_MINUTES + 'frequency': 5, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) # get_price_history_every_ten_minutes - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_ten_minutes_vanilla(self): self.client.get_price_history_every_ten_minutes('AAPL') params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1349,16 +1439,16 @@ def test_get_price_history_every_ten_minutes_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_ten_minutes_start_datetime(self): self.client.get_price_history_every_ten_minutes( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1369,16 +1459,16 @@ def test_get_price_history_every_ten_minutes_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_ten_minutes_end_datetime(self): self.client.get_price_history_every_ten_minutes( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1389,16 +1479,16 @@ def test_get_price_history_every_ten_minutes_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_ten_minutes_empty_extendedhours(self): self.client.get_price_history_every_ten_minutes( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1409,16 +1499,16 @@ def test_get_price_history_every_ten_minutes_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_ten_minutes_extendedhours(self): self.client.get_price_history_every_ten_minutes( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1430,18 +1520,58 @@ def test_get_price_history_every_ten_minutes_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_ten_minutes_empty_previous_close(self): + self.client.get_price_history_every_ten_minutes( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_TEN_MINUTES + 'frequency': 10, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_ten_minutes_previous_close(self): + self.client.get_price_history_every_ten_minutes( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_TEN_MINUTES + 'frequency': 10, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) # get_price_history_every_fifteen_minutes - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_fifteen_minutes_vanilla(self): self.client.get_price_history_every_fifteen_minutes('AAPL') params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1452,16 +1582,16 @@ def test_get_price_history_every_fifteen_minutes_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_fifteen_minutes_start_datetime(self): self.client.get_price_history_every_fifteen_minutes( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1472,16 +1602,16 @@ def test_get_price_history_every_fifteen_minutes_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_fifteen_minutes_end_datetime(self): self.client.get_price_history_every_fifteen_minutes( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1492,16 +1622,16 @@ def test_get_price_history_every_fifteen_minutes_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_fifteen_minutes_empty_extendedhours(self): self.client.get_price_history_every_fifteen_minutes( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1512,16 +1642,16 @@ def test_get_price_history_every_fifteen_minutes_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_fifteen_minutes_extendedhours(self): self.client.get_price_history_every_fifteen_minutes( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1533,18 +1663,58 @@ def test_get_price_history_every_fifteen_minutes_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_fifteen_minutes_empty_previous_close(self): + self.client.get_price_history_every_fifteen_minutes( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_FIFTEEN_MINUTES + 'frequency': 15, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_fifteen_minutes_previous_close(self): + self.client.get_price_history_every_fifteen_minutes( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_FIFTEEN_MINUTES + 'frequency': 15, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) # get_price_history_every_thirty_minutes - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_thirty_minutes_vanilla(self): self.client.get_price_history_every_thirty_minutes('AAPL') params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1555,16 +1725,16 @@ def test_get_price_history_every_thirty_minutes_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_thirty_minutes_start_datetime(self): self.client.get_price_history_every_thirty_minutes( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1575,16 +1745,16 @@ def test_get_price_history_every_thirty_minutes_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_thirty_minutes_end_datetime(self): self.client.get_price_history_every_thirty_minutes( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1595,16 +1765,16 @@ def test_get_price_history_every_thirty_minutes_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_thirty_minutes_empty_extendedhours(self): self.client.get_price_history_every_thirty_minutes( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1615,16 +1785,16 @@ def test_get_price_history_every_thirty_minutes_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_thirty_minutes_extendedhours(self): self.client.get_price_history_every_thirty_minutes( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'day', # ONE_DAY 'period': 1, @@ -1636,18 +1806,58 @@ def test_get_price_history_every_thirty_minutes_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_thirty_minutes_empty_previous_close(self): + self.client.get_price_history_every_thirty_minutes( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_THIRTY_MINUTES + 'frequency': 30, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_thirty_minutes_previous_close(self): + self.client.get_price_history_every_thirty_minutes( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'day', + # ONE_DAY + 'period': 1, + 'frequencyType': 'minute', + # EVERY_THIRTY_MINUTES + 'frequency': 30, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) # get_price_history_every_day - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_day_vanilla(self): self.client.get_price_history_every_day('AAPL') params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1658,16 +1868,16 @@ def test_get_price_history_every_day_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_day_start_datetime(self): self.client.get_price_history_every_day( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1678,16 +1888,16 @@ def test_get_price_history_every_day_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_day_end_datetime(self): self.client.get_price_history_every_day( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1698,16 +1908,16 @@ def test_get_price_history_every_day_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_day_empty_extendedhours(self): self.client.get_price_history_every_day( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1718,16 +1928,16 @@ def test_get_price_history_every_day_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_day_extendedhours(self): self.client.get_price_history_every_day( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1739,18 +1949,58 @@ def test_get_price_history_every_day_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_day_empty_previous_close(self): + self.client.get_price_history_every_day( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'year', + # TWENTY_YEARS + 'period': 20, + 'frequencyType': 'daily', + # DAILY + 'frequency': 1, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_day_previous_close(self): + self.client.get_price_history_every_day( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'year', + # TWENTY_YEARS + 'period': 20, + 'frequencyType': 'daily', + # DAILY + 'frequency': 1, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) # get_price_history_every_week - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_week_vanilla(self): self.client.get_price_history_every_week('AAPL') params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1761,16 +2011,16 @@ def test_get_price_history_every_week_vanilla(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_week_start_datetime(self): self.client.get_price_history_every_week( 'AAPL', start_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1781,16 +2031,16 @@ def test_get_price_history_every_week_start_datetime(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_week_end_datetime(self): self.client.get_price_history_every_week( 'AAPL', end_datetime=EARLIER_DATETIME) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1801,16 +2051,16 @@ def test_get_price_history_every_week_end_datetime(self): 'endDate': EARLIER_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_week_empty_extendedhours(self): self.client.get_price_history_every_week( 'AAPL', need_extended_hours_data=None) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1821,16 +2071,16 @@ def test_get_price_history_every_week_empty_extendedhours(self): 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), params=params) - @patch('tda.client.base.datetime.datetime', mockdatetime) + @patch('schwab.client.base.datetime.datetime', mockdatetime) def test_get_price_history_every_week_extendedhours(self): self.client.get_price_history_every_week( 'AAPL', need_extended_hours_data=True) params = { - 'apikey': API_KEY, + 'symbol': SYMBOL, 'periodType': 'year', # TWENTY_YEARS 'period': 20, @@ -1842,10 +2092,51 @@ def test_get_price_history_every_week_extendedhours(self): 'needExtendedHoursData': True, } self.mock_session.get.assert_called_once_with( - self.make_url('/v1/marketdata/AAPL/pricehistory'), + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_week_empty_previous_close(self): + self.client.get_price_history_every_week( + 'AAPL', need_previous_close=None) + params = { + 'symbol': SYMBOL, + 'periodType': 'year', + # TWENTY_YEARS + 'period': 20, + 'frequencyType': 'weekly', + # DAILY + 'frequency': 1, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), + params=params) + + + @patch('schwab.client.base.datetime.datetime', mockdatetime) + def test_get_price_history_every_week_previous_close(self): + self.client.get_price_history_every_week( + 'AAPL', need_previous_close=True) + params = { + 'symbol': SYMBOL, + 'periodType': 'year', + # TWENTY_YEARS + 'period': 20, + 'frequencyType': 'weekly', + # DAILY + 'frequency': 1, + 'startDate': MIN_TIMESTAMP_MILLIS, + 'endDate': NOW_DATETIME_PLUS_SEVEN_DAYS_TIMESTAMP_MILLIS, + 'needPreviousClose': True, + } + self.mock_session.get.assert_called_once_with( + self.make_url('/marketdata/v1/pricehistory'), params=params) + ''' # get_quote