Exemple #1
0
def production_classic_futures_system(
    data,
    config_filename,
    log=logtoscreen("futures_system"),
    notional_trading_capital=None,
    base_currency=None,
):

    log_level = "on"

    sim_data = dataSimData(data)
    config = Config(config_filename)

    # Overwrite capital
    if notional_trading_capital is not None:
        config.notional_trading_capital = notional_trading_capital

    if base_currency is not None:
        config.base_currency = base_currency

    system = futures_system(data=sim_data, config=config)
    system._log = log

    system.set_logging_level(log_level)

    return system
    def test_simple_system_config_import(self, data):

        my_config = Config("systems.provided.example.simplesystemconfig.yaml")
        my_config.risk_overlay = arg_not_supplied
        my_config.exclude_instrument_lists = dict(
            ignore_instruments=["MILK"],
            trading_restrictions=["BUTTER"],
            bad_markets=["CHEESE"],
        )
        print(my_config)
        my_system = System(
            [
                Account(),
                Portfolios(),
                PositionSizing(),
                ForecastCombine(),
                ForecastScaleCap(),
                Rules(),
                RawData(),
            ],
            data,
            my_config,
        )
        print(my_system.rules.get_raw_forecast("EDOLLAR", "ewmac32").tail(5))
        print(my_system.rules.get_raw_forecast("EDOLLAR", "ewmac8").tail(5))
        print(
            my_system.forecastScaleCap.get_capped_forecast("EDOLLAR", "ewmac32").tail(5)
        )
        print(my_system.forecastScaleCap.get_forecast_scalar("EDOLLAR", "ewmac32"))
        print(my_system.combForecast.get_combined_forecast("EDOLLAR").tail(5))
        print(my_system.combForecast.get_forecast_weights("EDOLLAR").tail(5))

        print(my_system.positionSize.get_subsystem_position("EDOLLAR").tail(5))

        print(my_system.portfolio.get_notional_position("EDOLLAR").tail(5))
Exemple #3
0
def production_classic_futures_system(
    data: dataBlob,
    config_filename: str,
    log=logtoscreen("futures_system"),
    notional_trading_capital: float = arg_not_supplied,
    base_currency: str = arg_not_supplied,
) -> System:

    log_level = "on"

    sim_data = get_sim_data_object_for_production(data)
    config = Config(config_filename)

    # Overwrite capital and base currency
    if notional_trading_capital is not arg_not_supplied:
        config.notional_trading_capital = notional_trading_capital

    if base_currency is not arg_not_supplied:
        config.base_currency = base_currency

    system = futures_system(data=sim_data, config=config)
    system._log = log

    system.set_logging_level(log_level)

    return system
Exemple #4
0
    def testRules(self):

        # config=Config(dict(trading_rules=dict(ewmac=dict(function="systems.provided.rules.ewmac.ewmac_forecast_with_defaults"))))
        NOTUSEDrawdata, data, NOTUSEDconfig = get_test_object()

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

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

        config = Config(
            dict(
                trading_rules=dict(
                    ewmac=dict(
                        function="systems.provided.rules.ewmac.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], -3.28002839, 5)

        config = Config("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], -2.158634, 5)
 def test_prebaked_from_confg(self):
     """
     This is the config system from 'examples.introduction.prebakedsimplesystems'
     """
     my_config = Config("systems.provided.example.simplesystemconfig.yaml")
     my_config.risk_overlay = arg_not_supplied
     my_data = csvFuturesSimData()
     my_system = simplesystem(config=my_config, data=my_data)
     print(my_system.portfolio.get_notional_position("EDOLLAR").tail(5))
Exemple #6
0
def get_control_config() -> Config:
    try:
        control_config = Config(PRIVATE_CONTROL_CONFIG_FILE,
                                default_filename=DEFAULT_CONTROL_CONFIG_FILE)
        control_config.fill_with_defaults()
    except:
        raise Exception("Need to have either %s or %s or both present:" %
                        (str(DEFAULT_CONTROL_CONFIG_FILE),
                         str(PRIVATE_CONTROL_CONFIG_FILE)))

    return control_config
def set_up_config(data: dataBlob, config_filename: str) -> Config:
    production_config = data.config
    backtest_file_config = Config(config_filename)

    # 'later elements overwrite earlier ones'
    config = Config([production_config, backtest_file_config])

    ## this is also done by the system, but more transparent to do it here
    config.fill_with_defaults()

    return config
Exemple #8
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 = csvFuturesSimData()

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

    my_system.set_logging_level(log_level)

    return my_system
Exemple #9
0
def futures_system(sim_data=arg_not_supplied,
                   config_filename="systems.provided.rob_system.config.yaml"):

    if sim_data is arg_not_supplied:
        sim_data = dbFuturesSimData()

    config = Config(config_filename)

    system = System(
        [
            Risk(),
            accountForOptimisedStage(),
            optimisedPositions(),
            Portfolios(),
            PositionSizing(),
            myFuturesRawData(),
            ForecastCombine(),
            volAttenForecastScaleCap(),
            Rules(),
        ],
        sim_data,
        config,
    )
    system.set_logging_level("on")

    return system
Exemple #10
0
    def test_mp_optimisation(self):
        config = Config()

        weighting_params = config.default_config_dict[
            'forecast_weight_estimate']

        n_threads = 8
        weighting_params[
            'n_threads'] = n_threads  # running from a Pool of threads

        start_time1 = time()
        weights1 = optimiseWeightsOverTime(self.net_returns,
                                           **weighting_params).weights()
        stop_time1 = time()

        del weighting_params[
            'n_threads']  # running in main process, not separate process

        start_time2 = time()
        weights2 = optimiseWeightsOverTime(self.net_returns,
                                           **weighting_params).weights()
        stop_time2 = time()

        print(
            f"Takes {stop_time1-start_time1} seconds with {n_threads} processes"
        )
        print(
            f"Takes {stop_time2-start_time2} seconds running in main process")

        self.assertTrue(weights1.equals(weights2))
Exemple #11
0
def generate_matching_duplicate_dict(config: Config):
    """
    Returns a dict, each element is a named set of duplicated instruments
    Within each dict we have two elements: included, excluded
    Each of these is a list

    For example:
    dict(copper = dict(included = ["COPPER"], excluded = ["COPPER_mini"]
    """

    duplicate_instruments_config = config.get_element_or_missing_data(
        "duplicate_instruments")

    if duplicate_instruments_config is missing_data:
        raise Exception("Need 'duplicate_instruments' in config")
    exclude_dict = duplicate_instruments_config.get("exclude", missing_data)
    include_dict = duplicate_instruments_config.get("include", missing_data)
    if exclude_dict is missing_data or include_dict is missing_data:
        raise Exception(
            "Need 'duplicate_instruments': exclude_dict and include_dict in config"
        )

    joint_keys = list(
        set(list(exclude_dict.keys()) + list(include_dict.keys())))

    results_dict = dict([(key,
                          get_duplicate_dict_entry(key, include_dict,
                                                   exclude_dict))
                         for key in joint_keys])

    return results_dict
Exemple #12
0
def get_config_of_excluded_instruments(config: Config) -> dict:
    exclude_instrument_lists = config.get_element_or_missing_data(
        "exclude_instrument_lists")
    if exclude_instrument_lists is missing_data:
        return {}

    return exclude_instrument_lists
def get_control_config() -> Config:
    try:
        control_config = Config(
            PRIVATE_CONTROL_CONFIG_FILE, default_filename=DEFAULT_CONTROL_CONFIG_FILE
        )
        control_config.fill_with_defaults()
    except ParserError as pe:
        raise Exception("YAML syntax problem: %s" % str(pe))
    except FileNotFoundError:
        raise Exception(
            "Need to have either %s or %s or both present:"
            % (str(DEFAULT_CONTROL_CONFIG_FILE), str(PRIVATE_CONTROL_CONFIG_FILE))
        )
    except BaseException as be:
        raise Exception("Problem reading control config: %s" % str(be))

    return control_config
Exemple #14
0
def get_test_object_futures():
    """
    Returns some standard test data
    """
    data = csvFuturesSimData()
    rawdata = FuturesRawData()
    config = Config("systems.provided.example.exampleconfig.yaml")
    return (rawdata, data, config)
Exemple #15
0
    def setUp(self):

        system = System(
            [testStage1(), testStage2()],
            simData(),
            Config(dict(instruments=["code", "another_code"])),
        )
        self.system = system
Exemple #16
0
def get_test_object_futures_with_rules_and_capping():
    """
    Returns some standard test data
    """
    data = csvFuturesSimData()
    rawdata = FuturesRawData()
    rules = Rules()
    config = Config("systems.provided.example.exampleconfig.yaml")
    capobject = ForecastScaleCap()
    return (capobject, rules, rawdata, data, config)
    def setUp(self):
        class testStage(SystemStage):
            @property
            def name(self):
                return "test"

        stage = testStage()
        data = simData()
        config = Config(dict(instruments=["another_code", "code"]))
        system = System([stage], data=data, config=config)
        self.system = system
Exemple #18
0
def get_test_object_futures_with_pos_sizing():
    """
    Returns some standard test data
    """
    data = csvFuturesSimData()
    rawdata = FuturesRawData()
    rules = Rules()
    config = Config("systems.provided.example.exampleconfig.yaml")
    capobject = ForecastScaleCap()
    combobject = ForecastCombine()
    posobject = PositionSizing()
    return (posobject, combobject, capobject, rules, rawdata, data, config)
Exemple #19
0
def get_test_object_futures():
    """
    Returns some standard test data
    """
    data = csvFuturesSimData(datapath_dict=dict(
        config_data="sysdata.tests.configtestdata",
        adjusted_prices="sysdata.tests.adjtestdata",
        spot_fx_data="sysdata.tests.fxtestdata",
        multiple_price_data="sysdata.tests.multiplepricestestdata",
    ))
    rawdata = FuturesRawData()
    config = Config("systems.provided.example.exampleconfig.yaml")
    return (rawdata, data, config)
Exemple #20
0
def generate_matching_duplicate_dict(config: Config = arg_not_supplied):
    """
    Returns a dict, each element is a named set of duplicated instruments
    Within each dict we have two elements: included, excluded
    Each of these is a list

    For example:
    dict(copper = dict(included = ["COPPER"], excluded = ["COPPER_mini"]
    """

    if config is arg_not_supplied:
        print(
            "Using defaults.yaml config - won't include any elements from private_config or backtest configs"
        )
        config = Config()
        config.fill_with_defaults()

    duplicate_instruments_config = config.get_element_or_missing_data(
        "duplicate_instruments")

    if duplicate_instruments_config is missing_data:
        raise Exception("Need 'duplicate_instruments' in config")
    exclude_dict = duplicate_instruments_config.get("exclude", missing_data)
    include_dict = duplicate_instruments_config.get("include", missing_data)
    if exclude_dict is missing_data or include_dict is missing_data:
        raise Exception(
            "Need 'duplicate_instruments': exclude_dict and include_dict in config"
        )

    joint_keys = list(
        set(list(exclude_dict.keys()) + list(include_dict.keys())))

    results_dict = dict([(key,
                          get_duplicate_dict_entry(key, include_dict,
                                                   exclude_dict))
                         for key in joint_keys])

    return results_dict
Exemple #21
0
def system():
    """test fixture creates a system with start and end dates"""
    system = futures_system(
        data=CsvFuturesSimTestData(),
        config=Config("systems.provided.futures_chapter15.futuresconfig.yaml"),
    )

    # speed things up
    system.config.forecast_weight_estimate["method"] = "shrinkage"
    system.config.forecast_weight_estimate["date_method"] = "in_sample"
    system.config.instrument_weight_estimate["date_method"] = "in_sample"
    system.config.instrument_weight_estimate["method"] = "shrinkage"

    return system
Exemple #22
0
def get_test_object_futures_with_rules_and_capping():
    """
    Returns some standard test data
    """
    data = csvFuturesSimData(datapath_dict=dict(
        config_data="sysdata.tests.configtestdata",
        adjusted_prices="sysdata.tests.adjtestdata",
        spot_fx_data="sysdata.tests.fxtestdata",
        multiple_price_data="sysdata.tests.multiplepricestestdata",
    ))
    rawdata = FuturesRawData()
    rules = Rules()
    config = Config("systems.provided.example.exampleconfig.yaml")
    capobject = ForecastScaleCap()
    return (capobject, rules, rawdata, data, config)
def get_production_config() -> Config:
    if private_config_file_exists():
        config = Config(PRIVATE_CONFIG_FILE)
    else:
        print("Private configuration %s does not exist; no problem if running in sim mode")
        config = Config({})

    config.fill_with_defaults()

    return config
def futures_system(data=None,
                   config=None,
                   trading_rules=arg_not_supplied,
                   log_level="on"):
    """

    :param data: data object (defaults to reading from csv files)
    :type data: sysdata.data.simData, 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 = csvFuturesSimData()

    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
def my_config(ewmac_8, ewmac_32):
    my_config = Config()
    my_config.trading_rules = dict(ewmac8=ewmac_8, ewmac32=ewmac_32)
    my_config.instruments = ["US10", "EDOLLAR", "CORN", "SP500"]
    my_config.risk_overlay = arg_not_supplied
    my_config.exclude_instrument_lists = dict(
        ignore_instruments=["MILK"],
        trading_restrictions=["BUTTER"],
        bad_markets=["CHEESE"],
    )

    return my_config
    def test_simple_system_trading_rules_fixed(self, data, my_rules, fcs):

        # or we can use the values from the book
        my_config = Config()
        my_config.trading_rules = dict(ewmac8=ewmac_8, ewmac32=ewmac_32)
        my_config.instruments = ["US10", "EDOLLAR", "CORN", "SP500"]
        my_config.forecast_scalars = dict(ewmac8=5.3, ewmac32=2.65)
        my_config.use_forecast_scale_estimates = False

        my_system = System([fcs, my_rules], data, my_config)
        print(
            my_system.forecastScaleCap.get_capped_forecast("EDOLLAR", "ewmac32").tail(5)
        )
Exemple #27
0
def get_test_object_futures_with_pos_sizing_estimates():
    """
    Returns some standard test data
    """
    data = csvFuturesSimData(datapath_dict=dict(
        config_data="sysdata.tests.configtestdata",
        adjusted_prices="sysdata.tests.adjtestdata",
        spot_fx_data="sysdata.tests.fxtestdata",
        multiple_price_data="sysdata.tests.multiplepricestestdata",
    ))
    rawdata = FuturesRawData()
    rules = Rules()
    config = Config("systems.provided.example.estimateexampleconfig.yaml")
    capobject = ForecastScaleCap()
    combobject = ForecastCombine()
    posobject = PositionSizing()
    account = Account()
    return (account, posobject, combobject, capobject, rules, rawdata, data,
            config)
Exemple #28
0
    def __init__(
            self,
            stage_list: list,
            data: simData,
            config: Config = arg_not_supplied,
            log: logger = logtoscreen("base_system"),
    ):
        """
        Create a system object for doing simulations or live trading

        :param stage_list: A list of stages
        :type stage_list: list of systems.stage.SystemStage (or anything that inherits from it)

        :param data: data for doing simulations
        :type data: sysdata.data.simData (or anything that inherits from that)

        :param config: Optional configuration
        :type config: sysdata.configdata.Config

        :returns: new system object

        >>> from systems.stage import SystemStage
        >>> stage=SystemStage()
        >>> from sysdata.sim.csv_futures_sim_data import csvFuturesSimData
        >>> data=csvFuturesSimData()
        >>> System([stage], data)
        System base_system with .config, .data, and .stages: Need to replace method when inheriting

        """

        if config is arg_not_supplied:
            # Default - for very dull systems this is sufficient
            config = Config()

        self._data = data
        self._config = config
        self._log = log

        self.config.system_init(self)
        self.data.system_init(self)
        self._setup_stages(stage_list)
        self._cache = systemCache(self)
    def test_simple_system_risk_overlay(self, data, ewmac_8, ewmac_32):

        my_config = Config(
            dict(
                trading_rules=dict(ewmac8=ewmac_8, ewmac32=ewmac_32),
                instrument_weights=dict(US10=0.1, EDOLLAR=0.4, CORN=0.3, SP500=0.2),
                instrument_div_multiplier=1.5,
                forecast_scalars=dict(ewmac8=5.3, ewmac32=2.65),
                forecast_weights=dict(ewmac8=0.5, ewmac32=0.5),
                forecast_div_multiplier=1.1,
                percentage_vol_target=25.00,
                notional_trading_capital=500000,
                base_currency="GBP",
                risk_overlay=dict(
                    max_risk_fraction_normal_risk=1.4,
                    max_risk_fraction_stdev_risk=3.6,
                    max_risk_limit_sum_abs_risk=3.4,
                    max_risk_leverage=13.0,
                ),
                exclude_instrument_lists=dict(
                    ignore_instruments=["MILK"],
                    trading_restrictions=["BUTTER"],
                    bad_markets=["CHEESE"],
                ),
            )
        )
        print(my_config)
        my_system = System(
            [
                Account(),
                Portfolios(),
                PositionSizing(),
                ForecastCombine(),
                ForecastScaleCap(),
                Rules(),
                RawData(),
            ],
            data,
            my_config,
        )
        print(my_system.portfolio.get_notional_position("EDOLLAR").tail(5))
Exemple #30
0
def get_duplicate_list_of_instruments_to_remove_from_config(
        config: Config) -> list:
    duplicate_instruments_config = config.get_element_or_missing_data(
        "duplicate_instruments")

    if duplicate_instruments_config is missing_data:
        return []
    exclude_dict = duplicate_instruments_config.get("exclude", missing_data)
    if exclude_dict is missing_data:
        return []
    list_of_duplicates = list(exclude_dict.values())

    ## do this because can have multiple duplicates
    duplicate_list_flattened = []
    for item in list_of_duplicates:
        if type(item) is list:
            duplicate_list_flattened = duplicate_list_flattened + item
        else:
            duplicate_list_flattened.append(item)

    return duplicate_list_flattened