def test_historical_price__margin_adjustment__daily(self): # In case if we want only 1 historical bar and the last full bar was more than ~12 days ago, the adjustment of # the margin for the "number of days to go back" need to be performed self.current_time = str_to_date("2021-05-18 00:00:00.000000", DateFormat.FULL_ISO) actual_bars = self.data_provider.historical_price( self.ticker_1, PriceField.ohlcv(), 1, frequency=Frequency.DAILY) expected_bars = PricesDataFrame(data=[[25.0, 25.1, 25.2, None, 25.3]], index=[str_to_date('2021-05-05')], columns=PriceField.ohlcv()) assert_dataframes_equal(actual_bars, expected_bars, check_names=False) self.current_time = str_to_date("2021-05-27 00:00:00.000000", DateFormat.FULL_ISO) actual_bars = self.data_provider.historical_price( self.ticker_1, PriceField.ohlcv(), 1, frequency=Frequency.DAILY) assert_dataframes_equal(actual_bars, expected_bars, check_names=False) with self.assertRaises(ValueError): self.current_time = str_to_date("2021-06-06 00:00:00.000000", DateFormat.FULL_ISO) self.data_provider.historical_price(self.ticker_1, PriceField.ohlcv(), 1, frequency=Frequency.DAILY)
def test_drifting_weights_alloc_not_fully_invested(self): expected_df = self.alloc_for_not_fully_invested_drift_weights _, actual_df = Portfolio.drifting_weights(self.assets_df, self.weights_not_full_invest) assert_dataframes_equal(expected_df, actual_df, absolute_tolerance=1e-06)
def test_asof_multiple_dates_gaps_at_the_end(self): actual_result = self.qf_data_array.asof(str_to_date('2018-02-06')) expected_result = QFDataFrame( index=self.qf_data_array.tickers.to_index(), columns=self.qf_data_array.fields.to_index(), data=[[16, 17, 18, 19], [12, 13, 14, 15]]) assert_dataframes_equal(expected_result, actual_result)
def test_concat(self): full_df = QFDataFrame(data=self.prices_values, index=self.dates, columns=self.column_names) # Concatenate along index (axis = 0) number_of_rows = len(full_df) half_df = full_df.iloc[:number_of_rows // 2] second_half_df = full_df.iloc[number_of_rows // 2:] concatenated_df = pd.concat([half_df, second_half_df]) self.assertEqual(type(concatenated_df), QFDataFrame) self.assertEqual({dtype("float64")}, set(concatenated_df.dtypes)) assert_dataframes_equal(concatenated_df, full_df) # Concatenate along columns (axis = 1) number_of_columns = full_df.num_of_columns half_df = full_df.loc[:, full_df.columns[:number_of_columns // 2]] second_half_df = full_df.loc[:, full_df.columns[number_of_columns // 2:]] concatenated_df = pd.concat([half_df, second_half_df], axis=1) self.assertEqual(type(concatenated_df), QFDataFrame) self.assertEqual({dtype("float64")}, set(concatenated_df.dtypes)) assert_dataframes_equal(concatenated_df, full_df)
def test_futures_chain_without_adjustment(self): timer = SettableTimer(self.end_date) self.future_ticker_1.initialize_data_provider(timer, self.data_provider) futures_chain = FuturesChain(self.future_ticker_1, self.data_provider, FuturesAdjustmentMethod.NTH_NEAREST) # AB2021M is the current specific ticker till 2021-06-14 inclusive, afterwards the AB2021U start_date = str_to_date("2021-06-13") end_date = str_to_date("2021-06-17") fields = PriceField.ohlcv() prices = futures_chain.get_price(fields, start_date, end_date, Frequency.DAILY) prices_m_contract = self.data_provider.get_price( PortaraTicker("AB2021M", SecurityType.FUTURE, 1), fields, start_date, str_to_date("2021-06-14"), Frequency.DAILY) prices_u_contract = self.data_provider.get_price( PortaraTicker("AB2021U", SecurityType.FUTURE, 1), fields, str_to_date("2021-06-15"), end_date, Frequency.DAILY) assert_dataframes_equal(prices, concat([prices_m_contract, prices_u_contract]), check_names=False)
def test_asof_nans_when_no_data_available(self): actual_result = self.qf_data_array.asof(str_to_date('2018-02-02')) expected_result = QFDataFrame( index=self.qf_data_array.tickers.to_index(), columns=self.qf_data_array.fields.to_index()) assert_dataframes_equal(expected_result, actual_result)
def test_import_dataframe(self): template_file_path = self.template_file_path(SINGLE_SHEET_ONE_DATA_FRAME) imported_dataframe = self.xl_importer.import_container(file_path=template_file_path, container_type=QFDataFrame, starting_cell='A1', ending_cell='C10') assert_dataframes_equal(self.test_data_frame, imported_dataframe)
def test_stepwise_factors_identification(self): stepwise_factors_identifier = StepwiseFactorsIdentifier( is_intercept=False, epsilon=0.01) actual_df = stepwise_factors_identifier.select_best_factors( self.regressors_df, self.analysed_tms) expected_df = self.regressors_df.loc[:, ['a', 'b']] assert_dataframes_equal(expected_df, actual_df)
def test_enet_factors_identification(self): enet_factors_identifier = ElasticNetFactorsIdentifier( max_number_of_regressors=10) actual_df = enet_factors_identifier.select_best_factors( self.regressors_df, self.analysed_tms) expected_df = self.regressors_df.loc[:, ['a', 'b']] assert_dataframes_equal(expected_df, actual_df)
def test_enet_factors_identification_simplified(self): enet_factors_identifier = ElasticNetFactorsIdentifierSimplified( epsilon=0.05) actual_df = enet_factors_identifier.select_best_factors( self.regressors_df, self.analysed_tms) expected_df = self.regressors_df.loc[:, ['a', 'b']] assert_dataframes_equal(expected_df, actual_df)
def test_asof_multiple_dates(self): actual_result = self.qf_data_array.asof( [str_to_date('2018-02-05'), str_to_date('2018-02-04')]) expected_result = QFDataFrame( index=self.qf_data_array.tickers.to_index(), columns=self.qf_data_array.fields.to_index(), data=[[8, 9, 10, 11], [np.nan, np.nan, np.nan, np.nan]]) assert_dataframes_equal(expected_result, actual_result)
def test_import_custom_dataframe(self): template_file_path = self.template_file_path(SINGLE_SHEET_CUSTOM_INDEX_DATA_FRAME) df = QFDataFrame({"Test": [1, 2, 3, 4, 5], "Test2": [10, 20, 30, 40, 50]}, ["A", "B", "C", "D", "E"]) imported_dataframe = self.xl_importer.import_container(file_path=template_file_path, container_type=QFDataFrame, starting_cell='A10', ending_cell='C15', include_index=True, include_column_names=True) assert_dataframes_equal(df, imported_dataframe)
def test_min_max_normalized(self): normalized_prices = [[0.00, 0.00, 0.00, 0.00, 0.00], [0.25, 0.25, 0.25, 0.25, 0.25], [0.50, 0.50, 0.50, 0.50, 0.50], [0.75, 0.75, 0.75, 0.75, 0.75], [1.00, 1.00, 1.00, 1.00, 1.00]] expected_dataframe = PricesDataFrame(data=normalized_prices, index=self.dates, columns=self.column_names) actual_dataframe = self.test_prices_df.min_max_normalized() assert_dataframes_equal(expected_dataframe, actual_dataframe)
def _assert_bars_for_today_is_correct(self, curr_time_str, expected_values): current_time = str_to_date(curr_time_str, DateFormat.FULL_ISO) self.timer.set_current_time(current_time) expected_dataframe = QFDataFrame(data=expected_values, index=self.tickers_index, columns=self.fields_index) actual_dataframe = self.data_handler.get_current_bar(self.tickers) assert_dataframes_equal(expected_dataframe, actual_dataframe, check_names=False)
def test_exponential_average(self): smoothed_values = [[1.000000, 1.000000, 1.000000, 1.000000, 1.000000], [1.940000, 1.940000, 1.940000, 1.940000, 1.940000], [2.936400, 2.936400, 2.936400, 2.936400, 2.936400], [3.936184, 3.936184, 3.936184, 3.936184, 3.936184], [4.936171, 4.936171, 4.936171, 4.936171, 4.936171]] expected_dataframe = PricesDataFrame(data=smoothed_values, index=self.dates, columns=self.column_names) actual_dataframe = self.test_prices_df.exponential_average() assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_aggregate_by_year(self): dates = pd.DatetimeIndex(['2015-06-01', '2015-12-30', '2016-01-01', '2016-05-01']) test_dataframe = SimpleReturnsDataFrame(data=self.simple_returns_values, index=dates) expected_aggregated_rets = [[2.000000, 2.000000, 2.000000, 2.000000, 2.000000], [0.666666, 0.666666, 0.666666, 0.666666, 0.666666]] expected_dataframe = SimpleReturnsDataFrame(data=expected_aggregated_rets, index=pd.DatetimeIndex(['2015-12-31', '2016-12-31'])) actual_dataframe = test_dataframe.aggregate_by_year() assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_get_price_with_single_field(self): actual_frame = self.prefetching_data_provider.get_price( self.cached_tickers, PriceField.Volume, self.start_date, self.end_date, self.frequency) expected_frame = PricesDataFrame(data=np.full( (len(self.cached_dates_idx), len(self.cached_tickers_idx)), 0), index=self.cached_dates_idx, columns=self.cached_tickers_idx) tt.assert_dataframes_equal(expected_frame, actual_frame, check_index_type=True, check_column_type=True)
def test_proxy_using_values(self): expected_values = [[0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0], [2.0, 0.0, 2.0, 2.0], [3.0, 3.0, 0.0, 3.0], [4.0, 4.0, 4.0, 4.0], [5.0, 5.0, 5.0, 5.0]] expected_columns = ['a', 'c', 'd', 'e'] expected_dates = self.test_dataframe.index.copy() expected_dataframe = SimpleReturnsDataFrame(data=expected_values, columns=expected_columns, index=expected_dates) self.data_cleaner.threshold = 0.2 actual_dataframe = self.data_cleaner.proxy_using_value(proxy_value=0.0) assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_import_custom_dataframe_shifted(self): # This tests issue #79. template_file_path = self.template_file_path(SINGLE_SHEET_CUSTOM_INDEX_DATA_FRAME_SHIFTED) # With index and column names. df = QFDataFrame({"Test": [1, 2, 3, 4, 5], "Test2": [10, 20, 30, 40, 50]}, ["A", "B", "C", "D", "E"]) imported_dataframe = self.xl_importer.import_container(file_path=template_file_path, container_type=QFDataFrame, starting_cell='C10', ending_cell='E15', include_index=True, include_column_names=True) assert_dataframes_equal(df, imported_dataframe) # With index and no column names. df = QFDataFrame({0: [1, 2, 3, 4, 5], 1: [10, 20, 30, 40, 50]}, ["A", "B", "C", "D", "E"]) imported_dataframe = self.xl_importer.import_container(file_path=template_file_path, container_type=QFDataFrame, starting_cell='C11', ending_cell='E15', include_index=True, include_column_names=False) assert_dataframes_equal(df, imported_dataframe) # With column names and no index. df = QFDataFrame({"Test": [1, 2, 3, 4, 5], "Test2": [10, 20, 30, 40, 50]}) imported_dataframe = self.xl_importer.import_container(file_path=template_file_path, container_type=QFDataFrame, starting_cell='D10', ending_cell='E15', include_index=False, include_column_names=True) assert_dataframes_equal(df, imported_dataframe) # With no column names and no index. df = QFDataFrame({0: [1, 2, 3, 4, 5], 1: [10, 20, 30, 40, 50]}) imported_dataframe = self.xl_importer.import_container(file_path=template_file_path, container_type=QFDataFrame, starting_cell='D11', ending_cell='E15', include_index=False, include_column_names=False) assert_dataframes_equal(df, imported_dataframe)
def test_rolling_time_window(self): actual_result = self.test_prices_df.rolling_time_window(window_length=2, step=1, func=lambda x: x.mean()) expected_values = [[1.5, 1.5, 1.5, 1.5, 1.5], [2.5, 2.5, 2.5, 2.5, 2.5], [3.5, 3.5, 3.5, 3.5, 3.5], [4.5, 4.5, 4.5, 4.5, 4.5]] expected_index = self.test_prices_df.index[-4:].copy(deep=True) expected_columns = ['a', 'b', 'c', 'd', 'e'] expected_result = QFDataFrame(expected_values, expected_index, expected_columns) assert_dataframes_equal(expected_result, actual_result, absolute_tolerance=1e-20) actual_result = self.test_prices_df.rolling_time_window(window_length=2, step=1, func=lambda x: x.mean().mean()) expected_values = [1.5, 2.5, 3.5, 4.5] expected_index = self.test_prices_df.index[-4:].copy(deep=True) expected_result = QFSeries(expected_values, expected_index) assert_series_equal(expected_result, actual_result, absolute_tolerance=1e-20)
def test_proxy_using_regression(self): expected_values = [[np.nan, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0], [2.0, 2.0, 2.0, 2.0], [3.0, 3.0, 3.0, 3.0], [4.0, 4.0, 4.0, 4.0], [5.0, 5.0, 5.0, 5.0]] expected_columns = ['a', 'c', 'd', 'e'] expected_dates = self.test_dataframe.index.copy() expected_dataframe = SimpleReturnsDataFrame(data=expected_values, columns=expected_columns, index=expected_dates) self.data_cleaner.threshold = 0.2 actual_dataframe = self.data_cleaner.proxy_using_regression( benchmark_tms=self.test_benchmark, columns_type=SimpleReturnsSeries) assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_make_scenarios(self): initial_risks = [0.01, 0.02, 0.03] scenarios = [ self.sample_trades_df * 1.0, self.sample_trades_df * -1.0, self.sample_trades_df * 2.0 ] # type: Sequence[QFDataFrame] actual_stats = self.initial_risk_stats_factory.make_stats( initial_risks, scenarios) expected_stats = QFDataFrame(index=[0.01, 0.02, 0.03], columns=[ InitialRiskStatsFactory.FAILED, InitialRiskStatsFactory.SUCCEEDED ], data=[[1 / 3, 2 / 3], [0.0, 1 / 3], [2 / 3, 1 / 3]]) assert_dataframes_equal(expected_stats, actual_stats)
def test_get_values_for_common_dates(self): data = range(6) dates1 = DatetimeIndex([ '2014-12-31', '2015-01-02', '2015-01-04', '2015-01-05', '2015-01-09', '2015-01-10' ]) dates2 = DatetimeIndex([ '2015-02-01', '2015-01-02', '2015-01-03', '2015-01-04', '2015-01-05', '2015-01-10' ]) series1 = QFSeries(data=data, index=dates1, name='Series 1') series2 = QFSeries(data=data, index=dates2, name='Series 2') data_2d = array([data, data]).transpose() dataframe1 = QFDataFrame( data=data_2d, index=dates2, columns=['DataFrame Col. A', 'DataFrame Col. B']) expected_index = DatetimeIndex( ['2015-01-02', '2015-01-04', '2015-01-05', '2015-01-10']) expected_data1 = [1, 2, 3, 5] expected_series1 = QFSeries(data=expected_data1, index=expected_index, name='Series 1') expected_data2 = [1, 3, 4, 5] expected_series2 = QFSeries(data=expected_data2, index=expected_index, name='Series 2') expected_dataframe = QFDataFrame( data=array([expected_data2, expected_data2]).transpose(), index=expected_index, columns=['DataFrame Col. A', 'DataFrame Col. B']) actual_series1, actual_series2, actual_dataframe = get_values_for_common_dates( series1, series2, dataframe1) assert_series_equal(expected_series1, actual_series1) assert_series_equal(expected_series2, actual_series2) assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_historical_price__single_ticker__multiple_fields__daily(self): self.current_time = str_to_date("2021-05-06 00:00:00.000000", DateFormat.FULL_ISO) # Test when the current day does not have the open price actual_bars = self.data_provider.historical_price( self.ticker_2, PriceField.ohlcv(), 2, frequency=Frequency.DAILY) expected_bars = PricesDataFrame( data=[[29.0, 29.1, 29.2, 30.0, 29.3], [27.0, 27.1, 27.2, None, 27.3]], index=[str_to_date('2021-05-02'), str_to_date('2021-05-05')], columns=PriceField.ohlcv()) assert_dataframes_equal(expected_bars, actual_bars, check_names=False) self.current_time = str_to_date("2021-05-06 00:00:00.000000", DateFormat.FULL_ISO) actual_bars = self.data_provider.historical_price( self.ticker_2, PriceField.ohlcv(), 3, frequency=Frequency.DAILY) expected_bars = PricesDataFrame(data=[[27.0, 27.1, 27.2, 28.0, 27.3], [29.0, 29.1, 29.2, 30.0, 29.3], [27.0, 27.1, 27.2, None, 27.3]], index=[ str_to_date('2021-05-01'), str_to_date('2021-05-02'), str_to_date('2021-05-05') ], columns=PriceField.ohlcv()) assert_dataframes_equal(expected_bars, actual_bars, check_names=False) # More than 3 bars are not available with self.assertRaises(ValueError): self.data_provider.historical_price(self.ticker_2, PriceField.ohlcv(), 4, frequency=Frequency.DAILY)
def test_prices_to_prices(self): expected_dataframe = self.test_prices_df actual_dataframe = self.test_prices_df.to_prices() assert_dataframes_equal(expected_dataframe, actual_dataframe) self.assertEqual({dtype("float64")}, set(actual_dataframe.dtypes))
def test_simple_to_simple_returns(self): expected_dataframe = self.test_simple_returns_df actual_dataframe = self.test_simple_returns_df.to_simple_returns() assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_prices_to_log_returns(self): expected_dataframe = self.test_log_returns_df actual_dataframe = self.test_prices_df.to_log_returns() assert_dataframes_equal(expected_dataframe, actual_dataframe)
def test_log_to_simple_returns(self): expected_dataframe = self.test_simple_returns_df actual_dataframe = self.test_log_returns_df.to_simple_returns() assert_dataframes_equal(expected_dataframe, actual_dataframe) self.assertEqual({dtype("float64")}, set(actual_dataframe.dtypes))