예제 #1
0
    def test_get_raw_fixed_forecast_weights(self):

        # fixed weights:
        #    nested dict (in config)
        ans1a = self.system.combForecast.get_forecast_weights("EDOLLAR")
        self.assertAlmostEqual(ans1a.ewmac16.values[-1], 0.5)

        ans1b = self.system.combForecast.get_raw_forecast_weights("BUND")
        self.assertEqual(ans1b.ewmac8.values[-1], 1.0)

        #    missing; equal weights
        config = copy.copy(self.config)
        del (config.forecast_weights)
        system2 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans2 = system2.combForecast.get_forecast_weights("BUND")
        self.assertAlmostEqual(ans2.ewmac8.values[-1], 0.49917057)  # smoothing

        #    non nested dict
        config.forecast_weights = dict(ewmac8=0.1, ewmac16=0.9)
        system3 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans3 = system3.combForecast.get_forecast_weights("BUND")
        self.assertEqual(ans3.ewmac8.values[-1], 0.099834114877206212)
예제 #2
0
    def test_get_capped_forecast(self):

        # fixed, normal cap
        self.assertAlmostEqual(
            self.system.forecastScaleCap.get_capped_forecast(
                "EDOLLAR", "ewmac8").tail(1).values[0], 0.871230635)

        # estimated, normal cap
        config = copy.copy(self.config)
        config.use_forecast_scale_estimates = True

        system2 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        self.assertAlmostEqual(system2.forecastScaleCap.get_forecast_scalar(
            "EDOLLAR", "ewmac8").tail(1).values[0],
                               5.8,
                               places=1)

        # binding cap
        config.use_forecast_scale_estimates = False
        config.forecast_cap = 0.2
        system3 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        self.assertAlmostEqual(
            system3.forecastScaleCap.get_capped_forecast(
                "EDOLLAR", "ewmac8").tail(1).values[0], 0.2)
예제 #3
0
    def testRules(self):

        # config=Config(dict(trading_rules=dict(ewmac=dict(function="pysystemtrade.systems.provided.example.rules.ewmac_forecast_with_defaults"))))
        data = csvFuturesData("sysdata.tests")

        rules = Rules(
            dict(
                function=
                "pysystemtrade.systems.provided.example.rules.ewmac_forecast_with_defaults"
            ))
        system = System([rules], data)

        ans = system.rules.get_raw_forecast("EDOLLAR", "rule0")
        self.assertAlmostEqual(ans.tail(1).values[0], 2.1384223788141838, 5)

        config = Config(
            dict(trading_rules=dict(ewmac=dict(
                function=
                "pysystemtrade.systems.provided.example.rules.ewmac_forecast_with_defaults"
            ))))
        rules = Rules()
        system = System([rules], data, config)
        ans = system.rules.get_raw_forecast("EDOLLAR", "ewmac")
        self.assertAlmostEqual(ans.tail(1).values[0], 2.1384223788141838, 5)

        config = Config(
            "pysystemtrade.systems.provided.example.exampleconfig.yaml")
        rawdata = RawData()

        rules = Rules()
        system = System([rules, rawdata], data, config)
        ans = system.rules.get_raw_forecast("EDOLLAR", "ewmac8")
        self.assertAlmostEqual(ans.tail(1).values[0], 0.16438313875, 5)
예제 #4
0
    def test_get_trading_rule_list(self):

        # fixed weights
        ans = self.system.combForecast.get_trading_rule_list("EDOLLAR")
        self.assertEqual(ans, ['ewmac16', 'ewmac8'])

        ans2 = self.system.combForecast.get_trading_rule_list("BUND")
        self.assertEqual(ans2, ['ewmac8'])

        # fixed weights - non nested dict
        config = copy.copy(self.config)
        config.forecast_weights = dict(ewmac8=.5, ewmac16=.5)
        system2 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans3 = system2.combForecast.get_trading_rule_list("EDOLLAR")
        self.assertEqual(ans3, ['ewmac16', 'ewmac8'])
        ans4 = system2.combForecast.get_trading_rule_list("BUND")
        self.assertEqual(ans4, ans3)

        # fixed weights - missing
        del (config.forecast_weights)
        system3 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans5 = system3.combForecast.get_trading_rule_list("EDOLLAR")
        self.assertEqual(ans5, ['ewmac16', 'ewmac8'])

        # estimated weights - missing
        config.use_forecast_weight_estimates = True
        system4 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans6 = system4.combForecast.get_trading_rule_list("EDOLLAR")
        self.assertEqual(ans6, ['ewmac16', 'ewmac8'])

        # estimated weights - non nested
        setattr(config, "rule_variations", ["ewmac8"])
        system5 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans6 = system5.combForecast.get_trading_rule_list("EDOLLAR")
        self.assertEqual(ans6, ['ewmac8'])

        #estimated weights - nested dict
        setattr(
            config, "rule_variations",
            dict(EDOLLAR=["ewmac8"],
                 BUND=["ewmac16"],
                 US10=["ewmac8", "ewmac16"]))
        system6 = System(
            [self.rawdata, self.rules, self.fcs,
             self.forecast_combine()], self.data, config)
        ans7 = system6.combForecast.get_trading_rule_list("EDOLLAR")
        self.assertEqual(ans7, ['ewmac8'])
        ans8 = system6.combForecast.get_trading_rule_list("BUND")
        self.assertEqual(ans8, ['ewmac16'])
        ans8 = system6.combForecast.get_trading_rule_list("US10")
        self.assertEqual(ans8, ['ewmac16', 'ewmac8'])  # missing
예제 #5
0
def futures_system(data=None, config=None, trading_rules=None, log_level="on"):
    """

    :param data: data object (defaults to reading from csv files)
    :type data: sysdata.data.Data, or anything that inherits from it

    :param config: Configuration object (defaults to futuresconfig.yaml in this directory)
    :type config: sysdata.configdata.Config

    :param trading_rules: Set of trading rules to use (defaults to set specified in config object)
    :type trading_rules: list or dict of TradingRules, or something that can be parsed to that

    :param log_level: How much logging to do
    :type log_level: str


    >>> system=futures_system(log_level="off")
    >>> system
    System with stages: accounts, portfolio, positionSize, rawdata, combForecast, forecastScaleCap, rules
    >>> system.rules.get_raw_forecast("EDOLLAR", "ewmac2_8").dropna().head(2)
                ewmac2_8
    1983-10-10  0.695929
    1983-10-11 -0.604704

                ewmac2_8
    2015-04-21  0.172416
    2015-04-22 -0.477559
    >>> system.rules.get_raw_forecast("EDOLLAR", "carry").dropna().head(2)
                   carry
    1983-10-10  0.952297
    1983-10-11  0.854075

                   carry
    2015-04-21  0.350892
    2015-04-22  0.350892
    """

    if data is None:
        data = csvFuturesData()

    if config is None:
        config = Config(
            "pysystemtrade.systems.provided.futures_chapter15.futuresconfig.yaml")

    rules = Rules(trading_rules)

    system = System([
        Account(), Portfolios(), PositionSizing(), FuturesRawData(),
        ForecastCombine(), ForecastScaleCap(), rules
    ], data, config)

    system.set_logging_level(log_level)

    return system
예제 #6
0
    def testCallingTradingRule(self):

        # config=Config(dict(trading_rules=dict(ewmac=dict(function="pysystemtrade.systems.provided.example.rules.ewmac_forecast_with_defaults"))))
        data = csvFuturesData("sysdata.tests")

        rawdata = RawData()
        rules = Rules()
        system = System([rawdata, rules], data)

        # Call with default data and config
        rule = TradingRule(ewmac_forecast_with_defaults)
        ans = rule.call(system, "EDOLLAR")
        self.assertAlmostEqual(ans.tail(1).values[0], 2.1384223788141838, 5)

        # Change the data source
        rule = TradingRule((
            "pysystemtrade.systems.provided.example.rules.ewmac_forecast_with_defaults_no_vol",
            ["rawdata.get_daily_prices",
             "rawdata.daily_returns_volatility"], dict()))

        ans = rule.call(system, "EDOLLAR")
        self.assertAlmostEqual(ans.tail(1).values[0], 0.029376, 5)

        rule = TradingRule(
            dict(
                function=
                "pysystemtrade.systems.provided.example.rules.ewmac_forecast_with_defaults_no_vol",
                data=[
                    "rawdata.get_daily_prices",
                    "rawdata.daily_returns_volatility"
                ],
                other_args=dict(Lfast=50, Lslow=200)))
        ans = rule.call(system, "EDOLLAR")
        self.assertAlmostEqual(ans.tail(1).values[0], 3.84426755)
예제 #7
0
 def setUp(self):
     stage = SystemStage()
     stage.name = "test"
     data = Data()
     config = Config(dict(instruments=["another_code", "code"]))
     system = System([stage], data=data, config=config)
     self.system = system
예제 #8
0
 def setUp(self):
     (accounts, fcs, rules, rawdata, data,
      config) = get_test_object_futures_with_rules_and_capping_estimate()
     system = System(
         [accounts, rawdata, rules, fcs,
          ForecastCombineEstimated()], data, config)
     setattr(self, "system", system)
예제 #9
0
 def setUp(self):
     (rules, rawdata, data, config) = get_test_object_futures_with_rules()
     system = System([rawdata, rules, ForecastScaleCap()], data, config)
     self.system = system
     self.config = config
     self.rules = rules
     self.rawdata = rawdata
     self.forecast_scale_cap = ForecastScaleCap
     self.data = data
예제 #10
0
    def test_get_forecast_scalar(self):
        # fixed
        ## From config
        self.assertEqual(
            self.system.forecastScaleCap.get_forecast_scalar(
                "EDOLLAR", "ewmac8"), 5.3)

        ## default
        config = copy.copy(self.config)
        unused = config.trading_rules['ewmac8'].pop('forecast_scalar')
        system2 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        self.assertEqual(
            system2.forecastScaleCap.get_forecast_scalar("EDOLLAR", "ewmac8"),
            1.0)

        ## other config location
        setattr(config, 'forecast_scalars', dict(ewmac8=11.0))
        system3 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        self.assertEqual(
            system3.forecastScaleCap.get_forecast_scalar("EDOLLAR", "ewmac8"),
            11.0)

        # estimated
        config = copy.copy(self.config)
        config.use_forecast_scale_estimates = True

        system2 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        ## From default
        self.assertAlmostEqual(system2.forecastScaleCap.get_forecast_scalar(
            "EDOLLAR", "ewmac8").tail(1).values[0],
                               5.8,
                               places=1)

        ## From config
        scale_config = dict(pool_instruments=False)
        config.forecast_scalar_estimate = scale_config
        system2 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        self.assertAlmostEqual(
            system2.forecastScaleCap.get_forecast_scalar(
                "EDOLLAR", "ewmac8").tail(1).values[0], 5.653444301)
예제 #11
0
    def setUpWithEstimatedReturns(self):
        config = copy.copy(self.config)
        config.use_forecast_weight_estimates = True
        config.use_forecast_div_mult_estimates = True
        new_system = System([
            self.rawdata, self.rules, self.fcs,
            self.forecast_combine(),
            Account()
        ], self.data, config)

        return new_system
예제 #12
0
    def testCarryRule(self):
        data = csvFuturesData("sysdata.tests")

        rawdata = FuturesRawData()
        rules = Rules()
        system = System([rawdata, rules], data)
        rule = TradingRule(carry, [
            "rawdata.daily_annualised_roll", "rawdata.daily_returns_volatility"
        ], dict(smooth_days=90))
        ans = rule.call(system, "EDOLLAR")
        self.assertAlmostEqual(ans.tail(1).values[0], 0.411686026, 5)
예제 #13
0
def futures_system(data=None,
                   config=None,
                   trading_rules=None,
                   log_level="terse"):
    """

    :param data: data object (defaults to reading from csv files)
    :type data: sysdata.data.Data, or anything that inherits from it

    :param config: Configuration object (defaults to futuresconfig.yaml in this directory)
    :type config: sysdata.configdata.Config

    :param trading_rules: Set of trading rules to use (defaults to set specified in config object)
    :param trading_rules: list or dict of TradingRules, or something that can be parsed to that

    :param log_level: Set of trading rules to use (defaults to set specified in config object)
    :type log_level: str

    """

    if data is None:
        data = csvFuturesData()

    if config is None:
        config = Config(
            "systems.provided.futures_chapter15.futuresestimateconfig.yaml")

    rules = Rules(trading_rules)

    system = System([
        Account(),
        Portfolios(),
        PositionSizing(),
        FuturesRawData(),
        ForecastCombine(),
        ForecastScaleCap(), rules
    ], data, config)

    system.set_logging_level(log_level)

    return system
예제 #14
0
    def test_get_forecast_cap(self):

        ans = self.system.forecastScaleCap.get_forecast_cap()
        self.assertEqual(ans, 21.0)

        ## test defaults
        config = self.config
        del (config.forecast_cap)
        system3 = System([self.rawdata, self.rules,
                          self.forecast_scale_cap()], self.data, config)
        ans = system3.forecastScaleCap.get_forecast_cap()
        self.assertEqual(ans, 20.0)
예제 #15
0
def simplesystem(data=None, config=None, log_level="on"):
    """
    Example of how to 'wrap' a complete system
    """
    if config is None:
        config = Config("systems.provided.example.simplesystemconfig.yaml")
    if data is None:
        data = csvFuturesData()

    my_system = System([
        Account(),
        Portfolios(),
        PositionSizing(),
        ForecastCombine(),
        ForecastScaleCap(),
        Rules()
    ], data, config)

    my_system.set_logging_level(log_level)

    return my_system
예제 #16
0
    def test_get_price_volatility(self):
        self.assertAlmostEqual(
            self.system.positionSize.get_price_volatility("EDOLLAR").values[
                -1], 0.059789159138)

        ## now without rawdata, should default to calculate on adj price
        system2 = System([
            self.rules, self.fcs, self.forecast_combine,
            self.position_sizing()
        ], self.data, self.config)
        self.assertAlmostEqual(
            system2.positionSize.get_price_volatility("EDOLLAR").values[-1],
            0.059723565)
예제 #17
0
    def setUp(self):

        (fcs, rules, rawdata, data,
         config) = get_test_object_futures_with_rules_and_capping()
        system = System([rawdata, rules, fcs, ForecastCombine()], data, config)

        self.system = system
        self.config = config
        self.rules = rules
        self.rawdata = rawdata
        self.fcs = fcs
        self.forecast_combine = ForecastCombine
        self.data = data
예제 #18
0
 def test_estimated_instrument_weights(self):
     config = copy.copy(self.config)
     config.use_instrument_weight_estimates = True
     system2 = System([
         self.rawdata, self.rules, self.possizing, self.forecast_combine,
         self.fcs,
         Account(),
         self.portfolios()
     ], self.data, config)
     ans = system2.portfolio.get_instrument_weights()
     self.assertAlmostEqual(ans.BUND.values[-1], 0.541, places=2)
     self.assertAlmostEqual(ans.EDOLLAR.values[-1], 0.346, places=2)
     self.assertAlmostEqual(ans.US10.values[-1], 0.1121, places=2)
예제 #19
0
    def setUp(self):

        (comb, fcs, rules, rawdata, data,
         config) = get_test_object_futures_with_comb_forecasts()
        system = System([rawdata, rules, fcs, comb, PositionSizing()], data,
                        config)

        self.system = system
        self.config = config
        self.rules = rules
        self.rawdata = rawdata
        self.fcs = fcs
        self.forecast_combine = comb
        self.data = data
        self.position_sizing = PositionSizing
예제 #20
0
    def test_actual_positions(self):
        config = copy.copy(self.config)
        config.use_instrument_weight_estimates = True
        system2 = System([
            self.rawdata, self.rules, self.possizing, self.forecast_combine,
            self.fcs,
            Account(),
            self.portfolios()
        ], self.data, config)

        ans = system2.portfolio.get_actual_position("EDOLLAR")
        self.assertAlmostEqual(ans.values[-1], 1.058623, places=4)

        ans = system2.portfolio.get_actual_buffers_for_position("EDOLLAR")
        self.assertAlmostEqual(ans.values[-1][0], 1.164485, places=4)
        self.assertAlmostEqual(ans.values[-1][1], 0.952761, places=4)
예제 #21
0
    def setUp(self):

        (posobject, combobject, capobject, rules, rawdata, data,
         config) = get_test_object_futures_with_pos_sizing()
        system = System(
            [rawdata, rules, posobject, combobject, capobject,
             Portfolios()], data, config)

        self.system = system
        self.config = config
        self.rules = rules
        self.rawdata = rawdata
        self.fcs = capobject
        self.forecast_combine = combobject
        self.data = data
        self.possizing = posobject
        self.portfolios = Portfolios
예제 #22
0
    def test_estimated_dm(self):
        config = copy.copy(self.config)
        config.use_instrument_weight_estimates = True
        system2 = System([
            self.rawdata, self.rules, self.possizing, self.forecast_combine,
            self.fcs,
            Account(),
            self.portfolios()
        ], self.data, config)
        ans = system2.portfolio.get_instrument_correlation_matrix(
        ).corr_list[-1]

        self.assertAlmostEqual(ans[0][1], 0.3889, places=3)
        self.assertAlmostEqual(ans[0][2], 0.5014, places=3)
        self.assertAlmostEqual(ans[1][2], 0.8771, places=3)

        ans = system2.portfolio.get_estimated_instrument_diversification_multiplier(
        )
        self.assertAlmostEqual(ans.values[-1], 1.1855, places=3)
예제 #23
0
    def test_get_daily_cash_vol_target(self):
        ans_dict = self.system.positionSize.get_daily_cash_vol_target()
        self.assertEqual(ans_dict['base_currency'], "GBP")
        self.assertEqual(ans_dict['annual_cash_vol_target'], 16000.0)
        self.assertEqual(ans_dict['daily_cash_vol_target'], 1000.0)
        self.assertEqual(ans_dict['notional_trading_capital'], 100000.0)
        self.assertEqual(ans_dict['percentage_vol_target'], 16.0)

        # test for missing config defaults
        system2 = System([
            self.rawdata, self.rules, self.fcs, self.forecast_combine,
            self.position_sizing()
        ], self.data)
        ans_dict2 = system2.positionSize.get_daily_cash_vol_target()
        self.assertEqual(ans_dict2['base_currency'], "USD")
        self.assertEqual(ans_dict2['annual_cash_vol_target'], 160000.0)
        self.assertEqual(ans_dict2['daily_cash_vol_target'], 10000.0)
        self.assertEqual(ans_dict2['notional_trading_capital'], 1000000.0)
        self.assertEqual(ans_dict2['percentage_vol_target'], 16.0)
예제 #24
0
    def update(self, message):
        """
        Subscriber pattern main method. Will be called each time a registered
        event occurs.
        
        :param message: dict with instrument names as keys and pd.Dataframe
                        as values.
        """
        data = self.get_data(message)
        # Ib data Object. This is the Object that manage the data from ibAPI.
        my_data = ib_Data(data)

        # create a list with the instruments for the config object
        my_config = Config("private.config.yaml")  # create a config object.
        my_config.instruments = my_data.get_instruments_list()

        # Setting the rules.
        my_rules = Rules(dict(ewmac=ewmac))
        my_rules.trading_rules()

        # Initializing the system with all the stages.
        my_stages = [
            Account(),
            Portfolios(),
            PositionSizing(),
            ForecastCombine(),
            ForecastScaleCap(), my_rules
        ]
        my_system = System(stage_list=my_stages,
                           data=my_data,
                           config=my_config)

        # Forecast for each instrument.
        for i in message.keys():
            print("\n{} forecast:\n".format(i))
            position = my_system.portfolio.get_notional_position(i)

            # Publishing forecast.
            message = dict(ticker=i, forecast=int(position.iloc[-1]))
            print(position.tail(5))
            self.pub.dispatch(i, message)
예제 #25
0
    def setUp(self):

        system = System([testStage1(), testStage2()], Data(),
                        Config(dict(instruments=["code", "another_code"])))
        self.system = system
예제 #26
0
    def test_get_returns_for_optimisation(self):
        # Note: More thorough tests will be run inside optimisation module (FIXME next refactoring)
        # At this point we don't run proper tests but just check all the plumbing works with new caching code
        # FIXME rewrite proper tests once refactored optimisation generally

        system = self.setUpWithEstimatedReturns()

        print(
            system.combForecast.get_SR_cost_for_instrument_forecast(
                "EDOLLAR", "ewmac8"))
        print(
            system.combForecast.get_SR_cost_for_instrument_forecast(
                "BUND", "ewmac8"))
        print(
            system.combForecast.get_SR_cost_for_instrument_forecast(
                "US10", "ewmac8"))

        print(system.combForecast.has_same_cheap_rules_as_code("EDOLLAR"))
        print(system.combForecast.has_same_cheap_rules_as_code("BUND"))
        print(system.combForecast.has_same_cheap_rules_as_code("US10"))

        print(
            system.combForecast.get_returns_for_optimisation(
                "EDOLLAR").to_frame())
        print(
            system.combForecast.get_returns_for_optimisation(
                "BUND").to_frame())
        print(
            system.combForecast.get_returns_for_optimisation(
                "US10").to_frame())

        print(system.combForecast.has_same_cheap_rules_as_code("EDOLLAR"))
        print(system.combForecast.has_same_cheap_rules_as_code("BUND"))
        print(system.combForecast.has_same_cheap_rules_as_code("US10"))

        # default - don't pool costs, pool gross
        print(system.combForecast.get_raw_forecast_weights("BUND"))

        # pool neithier gross or costs
        config = copy.copy(system.config)
        config.forecast_weight_estimate['pool_gross_returns'] = False
        config.forecast_weight_estimate['forecast_cost_estimates'] = False

        system2 = System([
            self.rawdata, self.rules, self.fcs,
            self.forecast_combine(),
            Account()
        ], self.data, config)
        print(system2.combForecast.get_raw_forecast_weights("BUND"))

        # pool gross, not costs
        config = copy.copy(system.config)
        config.forecast_weight_estimate['pool_gross_returns'] = True
        config.forecast_weight_estimate['forecast_cost_estimates'] = False

        system2 = System([
            self.rawdata, self.rules, self.fcs,
            self.forecast_combine(),
            Account()
        ], self.data, config)
        print(system2.combForecast.get_raw_forecast_weights("BUND"))

        # pool both (special function)
        config = copy.copy(system.config)
        config.forecast_weight_estimate['pool_gross_returns'] = True
        config.forecast_weight_estimate['forecast_cost_estimates'] = True

        system2 = System([
            self.rawdata, self.rules, self.fcs,
            self.forecast_combine(),
            Account()
        ], self.data, config)
        print(system2.combForecast.get_raw_forecast_weights("BUND"))
예제 #27
0
    def setUp(self):

        (rawdata, data, config) = get_test_object()

        system = System([rawdata], data)
        self.system = system