예제 #1
0
 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)
예제 #2
0
 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))
예제 #3
0
 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)
예제 #4
0
 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)
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
 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)
예제 #8
0
 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)
예제 #9
0
 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)
예제 #10
0
 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))]))
예제 #11
0
 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)
예제 #12
0
 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)
예제 #13
0
 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))
예제 #14
0
 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))
예제 #15
0
 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)
예제 #16
0
 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)
예제 #17
0
 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)
예제 #18
0
    """
    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