def test_bet_size_budget_default(self): """ Tests for the successful execution of the 'bet_size_budget' function. """ # Setup the test DataFrame. dates_test = np.array([ dt.datetime(2000, 1, 1) + i * dt.timedelta(days=1) for i in range(5) ]) shift_dt = np.array([dt.timedelta(days=0.5 * i + 1) for i in range(5)]) dates_shifted_test = dates_test + shift_dt events_test = pd.DataFrame(data=[[0.55, 1], [0.7, 1], [0.95, 1], [0.65, -1], [0.85, 1]], columns=['prob', 'side'], index=dates_test) events_test['t1'] = dates_shifted_test # Calculate correct result. events_result = get_concurrent_sides(events_test['t1'], events_test['side']) avg_long = events_result['active_long'] / events_result[ 'active_long'].max() avg_short = events_result['active_short'] / events_result[ 'active_short'].max() events_result['bet_size'] = avg_long - avg_short # Evaluate. self.assertTrue( events_result.equals( bet_size_budget(events_test['t1'], events_test['side'])))
def test_bet_size_budget_div_zero(self): """ Tests for successful handling of events DataFrames that result in a maximum number of concurrent bet sides of zero. """ # Setup the test DataFrame. dates_test = np.array([ dt.datetime(2000, 1, 1) + i * dt.timedelta(days=1) for i in range(5) ]) shift_dt = np.array([dt.timedelta(days=0.5 * i + 1) for i in range(5)]) dates_shifted_test = dates_test + shift_dt events_test = pd.DataFrame(data=[[0.55, 1], [0.7, 1], [0.95, 1], [0.65, 1], [0.85, 1]], columns=['prob', 'side'], index=dates_test) events_test['t1'] = dates_shifted_test # Calculate correct results. events_result = get_concurrent_sides(events_test['t1'], events_test['side']) max_active_long, max_active_short = events_result['active_long'].max( ), events_result['active_short'].max() avg_long = events_result[ 'active_long'] / max_active_long if max_active_long > 0 else 0 avg_short = events_result[ 'active_short'] / max_active_short if max_active_short > 0 else 0 events_result['bet_size'] = avg_long - avg_short # Evaluate. self.assertTrue( events_result.equals( bet_size_budget(events_test['t1'], events_test['side'])))
def test_bet_size_reserve_return_params(self, mock_likely_parameters): """ Tests for successful execution of 'bet_size_reserve' using return_parameters=True. Function 'most_likely_parameters' needs to be patched because the 'M2N.mp_fit' method makes use of random numbers. """ # Setup the test DataFrame. np.random.seed(0) sample_size = 500 start_date = dt.datetime(2000, 1, 1) date_step = dt.timedelta(days=1) dates = np.array( [start_date + i * date_step for i in range(sample_size)]) shift_dt = np.array([ dt.timedelta(days=d) for d in np.random.uniform(1., 20., sample_size) ]) dates_shifted = dates + shift_dt time_1 = pd.Series(data=dates_shifted, index=dates) df_events = time_1.to_frame() df_events = df_events.rename(columns={0: 't1'}) df_events['p'] = np.random.uniform(0.0, 1.0, sample_size) df_events = df_events[['t1', 'p']] df_events['side'] = df_events['p'].apply(lambda x: 1 if x >= 0.5 else -1) # Calculate the correct results. events_active = get_concurrent_sides(df_events['t1'], df_events['side']) events_active['c_t'] = events_active['active_long'] - events_active[ 'active_short'] central_moments = [ moment(events_active['c_t'].to_numpy(), moment=i) for i in range(1, 6) ] raw_moments = raw_moment(central_moments=central_moments, dist_mean=events_active['c_t'].mean()) m2n_test = M2N(raw_moments, epsilon=1e-5, factor=5, n_runs=25, variant=2, max_iter=10_000, num_workers=1) test_results = m2n_test.mp_fit() test_params = most_likely_parameters(test_results) mock_likely_parameters.return_value = test_params test_fit = [ test_params[key] for key in ['mu_1', 'mu_2', 'sigma_1', 'sigma_2', 'p_1'] ] events_active['bet_size'] = events_active['c_t'].apply( lambda c: single_bet_size_mixed(c, test_fit)) # Evaluate. eval_events, eval_params = bet_size_reserve(df_events['t1'], df_events['side'], fit_runs=25, return_parameters=True) self.assertEqual(test_params, eval_params) self.assertTrue(events_active.equals(eval_events))
def test_get_concurrent_sides_default(self): """ Tests for the successful execution of 'get_concurrent_sides'. Since there are no options or branches, there are no additional test cases beyond default. """ # Setup the test DataFrame. np.random.seed(0) sample_size = 100 start_date = dt.datetime(2000, 1, 1) date_step = dt.timedelta(days=1) dates = np.array( [start_date + i * date_step for i in range(sample_size)]) shift_dt = np.array([ dt.timedelta(days=d) for d in np.random.uniform(1., 20., sample_size) ]) dates_shifted = dates + shift_dt time_1 = pd.Series(data=dates_shifted, index=dates) df_events = time_1.to_frame() df_events = df_events.rename(columns={0: 't1'}) df_events['p'] = np.random.uniform(0.0, 1.0, sample_size) df_events = df_events[['t1', 'p']] df_events['side'] = df_events['p'].apply(lambda x: 1 if x >= 0.5 else -1) # Calculate correct result. events_test = df_events.copy() events_test['active_long'] = 0 events_test['active_short'] = 0 for idx in events_test.index: df_long_active_idx = set(events_test[(events_test.index <= idx) & (events_test['t1'] > idx) \ & (events_test['side'] > 0)].index) events_test.loc[idx, 'active_long'] = len(df_long_active_idx) df_short_active_idx = set(events_test[(events_test.index <= idx) & (events_test['t1'] > idx) \ & (events_test['side'] < 0)].index) events_test.loc[idx, 'active_short'] = len(df_short_active_idx) events_test = events_test[['active_long', 'active_short']] # Evaluate. df_results = get_concurrent_sides(df_events['t1'], df_events['side']) self.assertTrue( np.allclose(events_test.to_numpy(), df_results[['active_long', 'active_short']].to_numpy(), 1e-9))