def test_get_moments(self): """ Tests the 'get_moments' method of the M2N class. """ u_1, u_2, s_1, s_2, p_1 = [2.1, 4.3, 1.1, 0.7, 0.3] p_2 = 1 - p_1 m_1 = p_1 * u_1 + p_2 * u_2 m_2 = p_1 * (s_1**2 + u_1**2) + p_2 * (s_2**2 + u_2**2) m_3 = p_1 * (3 * s_1**2 * u_1 + u_1**3) + p_2 * (3 * s_2**2 * u_2 + u_2**3) m_4 = p_1 * (3 * s_1**4 + 6 * s_1**2 * u_1**2 + u_1**4) + p_2 * ( 3 * s_2**4 + 6 * s_2**2 * u_2**2 + u_2**4) m_5 = p_1 * (15 * s_1**4 * u_1 + 10 * s_1**2 * u_1**3 + u_1**5) + p_2 * (15 * s_2**4 * u_2 + 10 * s_2**2 * u_2**3 + u_2**5) test_params = [u_1, u_2, s_1, s_2, p_1] test_mmnts = [m_1, m_2, m_3, m_4, m_5] # Create M2N object. m2n_test = M2N(test_mmnts) # Check self-return method. m2n_test.get_moments(test_params, return_result=False) self.assertEqual(test_mmnts, m2n_test.new_moments) # Check the function when 'return_value' is True. result_mmnts = m2n_test.get_moments(test_params, return_result=True) self.assertEqual(test_mmnts, result_mmnts)
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_iter_4_validity_check_5(self): """ Tests 'iter_4' method's 'Validity check 5' breakpoint condition. """ moments_test = [0.0, 0.1, 0.0, 0.0, 5] m2n_test = M2N(moments_test) param_results = m2n_test.iter_4(0.1, 0.5) self.assertTrue(not param_results)
def test_iter_4_validity_check_3(self): """ Tests 'iter_4' method's 'Validity check 3' breakpoint condition. """ moments_test = [1.5, 2, 3, 4, 5] m2n_test = M2N(moments_test) param_results = m2n_test.iter_4(2, 0.7) self.assertTrue(not param_results)
def test_iter_4_success(self): """ Tests 'iter_4' method for successful execution. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] m2n_test = M2N(moments_test) param_results = m2n_test.iter_4(1, 0.2) self.assertTrue(len(param_results) == 5)
def test_iter_5_success(self): """ Tests 'iter_5' method for successful execution. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] mu_2_test, p_1_test = 0.8642146104188053, 0.03296760034110158 m2n_test = M2N(moments_test) param_results = m2n_test.iter_5(mu_2_test, p_1_test) self.assertTrue(len(param_results) == 5)
def test_iter_5_validity_check_7(self): """ Tests 'iter_5' method's 'Validity check 7' breakpoint condition. """ moments_test = [0.0, 0.1, 0.1, 0.0, 0.2] mu_2_test, p_1_test = 0.4, 0.95 m2n_test = M2N(moments_test) param_results = m2n_test.iter_5(mu_2_test, p_1_test) self.assertTrue(not param_results)
def test_iter_5_validity_check_9(self): """ Tests 'iter_5' method's 'Validity check 9' breakpoint condition. """ moments_test = [ 1.7465392043495434, 12.32010406019726, 44.3090981635415, 302.3152423573811, 1403.0640473698527 ] mu_2_test, p_1_test = 1.8733475857864539, 0.019291066689915537 m2n_test = M2N(moments_test) param_results = m2n_test.iter_5(mu_2_test, p_1_test) self.assertTrue(not param_results)
def test_iter_5_validity_check_8(self): """ Tests 'iter_5' method's 'Validity check 8' breakpoint condition. """ moments_test = [ 1.7486117351052706, 12.30094642908807, 44.14804719610457, 301.66990880582324, 1389.7073066865096 ] mu_2_test, p_1_test = 8.927498436080297, -1910484717784700.2 m2n_test = M2N(moments_test) param_results = m2n_test.iter_5(mu_2_test, p_1_test) self.assertTrue(not param_results)
def test_m2n_constructor(self): """ Tests that the constructor of the M2N class executes properly. """ moments_test = [1, 2, 3, 4, 5] m2n_test = M2N(moments_test) # Confirm that the initial attributes get set properly. self.assertEqual(m2n_test.moments, moments_test) self.assertEqual(m2n_test.new_moments, [0, 0, 0, 0, 0]) self.assertEqual(m2n_test.parameters, [0, 0, 0, 0, 0]) self.assertEqual( m2n_test.error, sum([moments_test[i]**2 for i in range(len(moments_test))]))
def test_fit_variant_value_error(self): """ Tests that the 'fit' method throws a ValueError if an invalid value is passed to argument 'variant'. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] mu_2_test = 1 epsilon_test = 1e-5 factor_test = 5 n_runs_test = 5 variant_test = 3 max_iter_test = 10_000 m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test) self.assertRaises(ValueError, m2n_test.fit, mu_2_test)
def test_fit_variant_2(self): """ Tests the 'fit' method of the M2N class, using variant 2. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] mu_2_test = 1 epsilon_test = 1e-5 factor_test = 5 n_runs_test = 5 variant_test = 2 max_iter_test = 10_000 m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test) m2n_test.fit(mu_2_test) self.assertTrue(len(m2n_test.parameters) == 5)
def test_mp_fit_return_type(self): """ Tests that the 'mp_fit' method executes successfully. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] epsilon_test = 1e-5 factor_test = 5 n_runs_test = 10 variant_test = 2 max_iter_test = 10_000 num_workers_test = 1 epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test, num_workers_test = 1e-5, 5, 10, 2, 10_000, 1 m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test, num_workers_test) df_results = m2n_test.mp_fit() self.assertTrue(isinstance(df_results, pd.DataFrame))
def test_single_fit_loop_return_type(self): """ Tests that the 'single_fit_loop' method executes successfully. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] epsilon_test = 1e-5 factor_test = 5 n_runs_test = 10 variant_test = 2 max_iter_test = 10_000 epsilon_test, factor_test, variant_test, max_iter_test = 1e-5, 5, 2, 10_000 np.random.seed(12) m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test) df_results = m2n_test.single_fit_loop() self.assertTrue(isinstance(df_results, pd.DataFrame))
def test_fit_success_via_max_iter(self): """ Tests that the 'fit' method successfully exits due to the maximum number of iterations being reached. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] np.random.seed(12) mu_2_test = 1 epsilon_test = 1e-12 factor_test = 5 n_runs_test = 5 variant_test = 1 max_iter_test = 1 mu_2_test, epsilon_test, variant_test, max_iter_test = 1, 1e-12, 1, 1 m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test) m2n_test.fit(mu_2=mu_2_test) self.assertTrue(len(m2n_test.parameters) == 5)
def test_fit_success_via_error(self): """ Tests that the 'fit' method successfully exits due to a low error being reached. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] mu_2_test = 1 epsilon_test = 1e-5 factor_test = 5 n_runs_test = 5 variant_test = 1 max_iter_test = 10_000 mu_2_test, epsilon_test, variant_test, max_iter_test = 1, 1e-5, 1, 10_000 m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test) m2n_test.error = 1e6 m2n_test.fit(mu_2_test) self.assertTrue(len(m2n_test.parameters) == 5)
def test_fit_success_via_epsilon(self): """ Tests that the 'fit' method successfully exits due to p_1 converging. """ moments_test = [0.7, 2.6, 0.4, 25, -59.8] mu_2_test = 1 epsilon_test = 1e12 factor_test = 5 n_runs_test = 5 variant_test = 1 max_iter_test = 10_000 mu_2_test, epsilon_test, variant_test, max_iter_test = 1, 1e12, 1, 10_000 np.random.seed(12) m2n_test = M2N(moments_test, epsilon_test, factor_test, n_runs_test, variant_test, max_iter_test) m2n_test.fit(mu_2_test) self.assertTrue(len(m2n_test.parameters) == 5)
""" events_active = get_concurrent_sides(events_t1, sides) # Calculate the concurrent difference in active bets: c_t = <current active long> - <current active short> events_active[ 'c_t'] = events_active['active_long'] - events_active['active_short'] # Calculate the first 5 centered and raw moments from the c_t distribution. central_mmnts = [ moment(events_active['c_t'].to_numpy(), moment=i) for i in range(1, 6) ] raw_mmnts = raw_moment(central_moments=central_mmnts, dist_mean=events_active['c_t'].mean()) # Fit the mixture of distributions. m2n = M2N(raw_mmnts, epsilon=epsilon, factor=factor, n_runs=fit_runs, variant=variant, max_iter=max_iter, num_workers=num_workers) df_fit_results = m2n.mp_fit() fit_params = most_likely_parameters(df_fit_results) params_list = [ fit_params[key] for key in ['mu_1', 'mu_2', 'sigma_1', 'sigma_2', 'p_1'] ] # Calculate the bet size. events_active['bet_size'] = events_active['c_t'].apply( lambda c: single_bet_size_mixed(c, params_list)) if return_parameters: return events_active, fit_params