Exemplo n.º 1
0
    def pandl_for_instrument_forecast_weighted(self,
                                               instrument_code,
                                               rule_variation_name,
                                               delayfill=True):
        """
        Get the p&l for one instrument and forecast; as % of total capital


        :param instrument_code: instrument to get values for
        :type instrument_code: str

        :param rule_variation_name: rule to get values for
        :type rule_variation_name: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :returns: accountCurve


        """

        self.log.msg(
            "Calculating pandl for instrument forecast weighted for %s %s" %
            (instrument_code, rule_variation_name),
            instrument_code=instrument_code,
            rule_variation_name=rule_variation_name)

        pandl = self.pandl_for_instrument_forecast(
            instrument_code, rule_variation_name, delayfill=delayfill)
        weight = self.get_instrument_forecast_scaling_factor(
            instrument_code, rule_variation_name)
        pandl = weighted(pandl, weight)

        return pandl
Exemplo n.º 2
0
    def pandl_for_instrument_forecast_weighted(self,
                                               instrument_code,
                                               rule_variation_name,
                                               delayfill=True):
        """
        Get the p&l for one instrument and forecast; as % of total capital


        :param instrument_code: instrument to get values for
        :type instrument_code: str

        :param rule_variation_name: rule to get values for
        :type rule_variation_name: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :returns: accountCurve


        """

        self.log.msg(
            "Calculating pandl for instrument forecast weighted for %s %s" %
            (instrument_code, rule_variation_name),
            instrument_code=instrument_code,
            rule_variation_name=rule_variation_name)

        pandl = self.pandl_for_instrument_forecast(
            instrument_code, rule_variation_name, delayfill=delayfill)
        weight = self.get_instrument_forecast_scaling_factor(
            instrument_code, rule_variation_name)
        pandl = weighted(pandl, weight)

        return pandl
Exemplo n.º 3
0
    def pandl_for_instrument_rules(self, instrument_code, delayfill=True):
        """
        Get the p&l for one instrument over multiple forecasts; as % of arbitrary capital

        P&L are weighted by forecast weights and FDM

        KEY OUTPUT

        :param instrument_code: instrument to get values for
        :type instrument_code: str


        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :returns: accountCurve

        >>> from systems.basesystem import System
        >>> from systems.tests.testdata import get_test_object_futures_with_portfolios
        >>> (portfolio, posobject, combobject, capobject, rules, rawdata, data, config)=get_test_object_futures_with_portfolios()
        >>> system=System([portfolio, posobject, combobject, capobject, rules, rawdata, Account()], data, config)
        >>>
        >>> system.accounts.pandl_for_instrument_rules_weighted("EDOLLAR").get_stats("sharpe")
        {'ewmac16': 0.6799720823590352, 'ewmac8': 0.69594671177102}
        """

        self.log.terse(
            "Calculating pandl for instrument rules for %s" % instrument_code,
            instrument_code=instrument_code,
        )

        forecast_rules = self.get_trading_rule_list(instrument_code)
        pandl_rules_unweighted = [
            self.pandl_for_instrument_forecast(
                instrument_code, rule_variation_name, delayfill=delayfill
            )
            for rule_variation_name in forecast_rules
        ]

        pandl_rules = [
            weighted(
                pandl_this_rule,
                weighting=self.get_forecast_scaling_factor(
                    instrument_code, rule_variation_name
                ),
            )
            for (pandl_this_rule, rule_variation_name) in zip(
                pandl_rules_unweighted, forecast_rules
            )
        ]

        pandl_rules = accountCurveGroup(
            pandl_rules,
            forecast_rules,
            capital=ARBITRARY_FORECAST_CAPITAL,
            weighted_flag=True,
        )

        return pandl_rules
Exemplo n.º 4
0
    def pandl_for_instrument_rules(self, instrument_code, delayfill=True):
        """
        Get the p&l for one instrument over multiple forecasts; as % of arbitrary capital

        P&L are weighted by forecast weights and FDM

        KEY OUTPUT

        :param instrument_code: instrument to get values for
        :type instrument_code: str


        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :returns: accountCurve

        >>> from systems.basesystem import System
        >>> from systems.tests.testdata import get_test_object_futures_with_portfolios
        >>> (portfolio, posobject, combobject, capobject, rules, rawdata, data, config)=get_test_object_futures_with_portfolios()
        >>> system=System([portfolio, posobject, combobject, capobject, rules, rawdata, Account()], data, config)
        >>>
        >>> system.accounts.pandl_for_instrument_rules_weighted("EDOLLAR").get_stats("sharpe")
        {'ewmac16': 0.6799720823590352, 'ewmac8': 0.69594671177102}
        """

        self.log.terse(
            "Calculating pandl for instrument rules for %s" % instrument_code,
            instrument_code=instrument_code)

        forecast_rules = self.get_trading_rule_list(instrument_code)
        pandl_rules_unweighted = [
            self.pandl_for_instrument_forecast(
                instrument_code, rule_variation_name, delayfill=delayfill)
            for rule_variation_name in forecast_rules
        ]

        pandl_rules = [
            weighted(
                pandl_this_rule,
                weighting=self.get_forecast_scaling_factor(
                    instrument_code, rule_variation_name))
            for (pandl_this_rule, rule_variation_name
                 ) in zip(pandl_rules_unweighted, forecast_rules)
        ]

        pandl_rules = accountCurveGroup(
            pandl_rules,
            forecast_rules,
            capital=ARBITRARY_FORECAST_CAPITAL,
            weighted_flag=True)

        return pandl_rules
Exemplo n.º 5
0
    def pandl_for_trading_rule(self, rule_variation_name, delayfill=True):
        """
        Get the p&l for one trading rule over multiple instruments; as % of its risk contribution

        Within the trading rule the instrument returns are weighted by instrument weight

        :param rule_variation_name: rule to get values for
        :type rule_variation_name: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :returns: accountCurve

        """

        self.log.terse("Calculating pandl for trading rule %s" %
                       rule_variation_name)

        instrument_list = self.parent.get_instrument_list()
        instrument_list = [
            instr_code for instr_code in instrument_list
            if rule_variation_name in self.get_trading_rule_list(instr_code)
        ]

        # already weighted
        # capital on these will be the default
        pandl_by_instrument_weighted = [
            self.pandl_for_instrument_forecast_weighted(
                instr_code, rule_variation_name, delayfill)
            for instr_code in instrument_list
        ]

        # now we weight so total capital is correct
        capital_this_rule = self.get_capital_in_rule(rule_variation_name)

        def _cleanweightelement(capelement):
            if np.isnan(capelement):
                return 0.0
            if capelement == 0.0:
                return 0.0
            else:
                return 1.0 / capelement

        weight = [
            _cleanweightelement(capelement)
            for capelement in list(capital_this_rule.values)
        ]
        weight = pd.Series(weight, index=capital_this_rule.index)

        pandl_by_instrument_reweighted = [
            weighted(pandl_for_instrument, weight, allow_reweighting=True)
            for pandl_for_instrument in pandl_by_instrument_weighted
        ]

        pandl_rule = accountCurveGroup(
            pandl_by_instrument_reweighted,
            instrument_list,
            capital=ARBITRARY_FORECAST_CAPITAL,
            weighted_flag=True,
        )

        return pandl_rule
Exemplo n.º 6
0
    def pandl_for_instrument(self,
                             instrument_code,
                             delayfill=True,
                             roundpositions=True):
        """
        Get the p&l for one instrument

        :param instrument_code: instrument to get values for
        :type instrument_code: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :param roundpositions: Round positions to whole contracts
        :type roundpositions: bool

        :returns: accountCurve

        >>> from systems.basesystem import System
        >>> from systems.tests.testdata import get_test_object_futures_with_portfolios
        >>> (portfolio, posobject, combobject, capobject, rules, rawdata, data, config)=get_test_object_futures_with_portfolios()
        >>> system=System([portfolio, posobject, combobject, capobject, rules, rawdata, Account()], data, config)
        >>> system.accounts.pandl_for_instrument("US10").ann_std()
        0.13908407620762306
        """

        self.log.msg(
            "Calculating pandl for instrument for %s" % instrument_code,
            instrument_code=instrument_code,
        )

        price = self.get_daily_price(instrument_code)
        positions = self.get_buffered_position(instrument_code,
                                               roundpositions=roundpositions)
        fx = self.get_fx_rate(instrument_code)
        value_of_price_point = self.get_value_of_price_move(instrument_code)
        get_daily_returns_volatility = self.get_daily_returns_volatility(
            instrument_code)

        capital = self.get_notional_capital()
        ann_risk_target = self.get_ann_risk_target()

        (SR_cost, cash_costs) = self.get_costs(instrument_code)

        instr_pandl = accountCurve(
            price,
            positions=positions,
            delayfill=delayfill,
            roundpositions=roundpositions,
            fx=fx,
            value_of_price_point=value_of_price_point,
            capital=capital,
            ann_risk_target=ann_risk_target,
            SR_cost=SR_cost,
            cash_costs=cash_costs,
            get_daily_returns_volatility=get_daily_returns_volatility,
        )

        if SR_cost is not None:
            # Note that SR cost is done as a proportion of capital
            # Since we're only using part of the capital we need to correct
            # for this
            turnover_for_SR = self.instrument_turnover(
                instrument_code, roundpositions=roundpositions)
            SR_cost = SR_cost * turnover_for_SR
            weighting = self.get_instrument_scaling_factor(instrument_code)
            apply_weight_to_costs_only = True

            instr_pandl = weighted(
                instr_pandl,
                weighting=weighting,
                apply_weight_to_costs_only=apply_weight_to_costs_only,
            )

        else:
            # Costs wil be correct
            # We don't need to do anything
            pass

        return instr_pandl
Exemplo n.º 7
0
    def pandl_for_instrument_with_multiplier(self,
                                             instrument_code,
                                             delayfill=True,
                                             roundpositions=True):
        """
        Get the p&l for one instrument, using variable capital

        :param instrument_code: instrument to get values for
        :type instrument_code: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :param roundpositions: Round positions to whole contracts
        :type roundpositions: bool

        :returns: accountCurve

        """

        self.log.msg(
            "Calculating pandl for instrument for %s with capital multiplier" %
            instrument_code,
            instrument_code=instrument_code,
        )

        price = self.get_daily_price(instrument_code)
        positions = self.get_buffered_position_with_multiplier(
            instrument_code, roundpositions=roundpositions)
        fx = self.get_fx_rate(instrument_code)
        value_of_price_point = self.get_value_of_price_move(instrument_code)
        get_daily_returns_volatility = self.get_daily_returns_volatility(
            instrument_code)

        capital = self.get_actual_capital(delayfill=delayfill,
                                          roundpositions=roundpositions)

        ann_risk_target = self.get_ann_risk_target()

        (SR_cost, cash_costs) = self.get_costs(instrument_code)

        instr_pandl = accountCurve(
            price,
            positions=positions,
            delayfill=delayfill,
            roundpositions=roundpositions,
            fx=fx,
            value_of_price_point=value_of_price_point,
            capital=capital,
            ann_risk_target=ann_risk_target,
            SR_cost=SR_cost,
            cash_costs=cash_costs,
            get_daily_returns_volatility=get_daily_returns_volatility,
        )

        if SR_cost is not None:
            # Note that SR cost is done as a proportion of capital
            # Since we're only using part of the capital we need to correct
            # for this
            turnover_for_SR = self.instrument_turnover(
                instrument_code, roundpositions=roundpositions)
            SR_cost = SR_cost * turnover_for_SR
            weighting = self.get_instrument_scaling_factor(instrument_code)
            apply_weight_to_costs_only = True

            instr_pandl = weighted(
                instr_pandl,
                weighting=weighting,
                apply_weight_to_costs_only=apply_weight_to_costs_only,
            )

        else:
            # Costs wil be correct
            # We don't need to do anything
            pass

        return instr_pandl
Exemplo n.º 8
0
    def pandl_for_trading_rule(self, rule_variation_name, delayfill=True):
        """
        Get the p&l for one trading rule over multiple instruments; as % of its risk contribution

        Within the trading rule the instrument returns are weighted by instrument weight

        :param rule_variation_name: rule to get values for
        :type rule_variation_name: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :returns: accountCurve

        """

        self.log.terse(
            "Calculating pandl for trading rule %s" % rule_variation_name)

        instrument_list = self.parent.get_instrument_list()
        instrument_list = [
            instr_code for instr_code in instrument_list
            if rule_variation_name in self.get_trading_rule_list(instr_code)
        ]

        # already weighted
        # capital on these will be the default
        pandl_by_instrument_weighted = [
            self.pandl_for_instrument_forecast_weighted(
                instr_code, rule_variation_name, delayfill)
            for instr_code in instrument_list
        ]

        # now we weight so total capital is correct
        capital_this_rule = self.get_capital_in_rule(rule_variation_name)

        def _cleanweightelement(capelement):
            if np.isnan(capelement):
                return 0.0
            if capelement == 0.0:
                return 0.0
            else:
                return 1.0 / capelement

        weight = [
            _cleanweightelement(capelement)
            for capelement in list(capital_this_rule.values)
        ]
        weight = pd.Series(weight, index=capital_this_rule.index)

        pandl_by_instrument_reweighted = [
            weighted(pandl_for_instrument, weight, allow_reweighting=True)
            for pandl_for_instrument in pandl_by_instrument_weighted
        ]

        pandl_rule = accountCurveGroup(
            pandl_by_instrument_reweighted,
            instrument_list,
            capital=ARBITRARY_FORECAST_CAPITAL,
            weighted_flag=True)

        return pandl_rule
Exemplo n.º 9
0
    def pandl_for_instrument(self,
                             instrument_code,
                             delayfill=True,
                             roundpositions=True):
        """
        Get the p&l for one instrument

        :param instrument_code: instrument to get values for
        :type instrument_code: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :param roundpositions: Round positions to whole contracts
        :type roundpositions: bool

        :returns: accountCurve

        >>> from systems.basesystem import System
        >>> from systems.tests.testdata import get_test_object_futures_with_portfolios
        >>> (portfolio, posobject, combobject, capobject, rules, rawdata, data, config)=get_test_object_futures_with_portfolios()
        >>> system=System([portfolio, posobject, combobject, capobject, rules, rawdata, Account()], data, config)
        >>> system.accounts.pandl_for_instrument("US10").ann_std()
        0.13908407620762306
        """

        self.log.msg(
            "Calculating pandl for instrument for %s" % instrument_code,
            instrument_code=instrument_code)

        price = self.get_daily_price(instrument_code)
        positions = self.get_buffered_position(
            instrument_code, roundpositions=roundpositions)
        fx = self.get_fx_rate(instrument_code)
        value_of_price_point = self.get_value_of_price_move(instrument_code)
        get_daily_returns_volatility = self.get_daily_returns_volatility(
            instrument_code)

        capital = self.get_notional_capital()
        ann_risk_target = self.get_ann_risk_target()

        (SR_cost, cash_costs) = self.get_costs(instrument_code)

        instr_pandl = accountCurve(
            price,
            positions=positions,
            delayfill=delayfill,
            roundpositions=roundpositions,
            fx=fx,
            value_of_price_point=value_of_price_point,
            capital=capital,
            ann_risk_target=ann_risk_target,
            SR_cost=SR_cost,
            cash_costs=cash_costs,
            get_daily_returns_volatility=get_daily_returns_volatility)

        if SR_cost is not None:
            # Note that SR cost is done as a proportion of capital
            # Since we're only using part of the capital we need to correct
            # for this
            turnover_for_SR = self.instrument_turnover(
                instrument_code, roundpositions=roundpositions)
            SR_cost = SR_cost * turnover_for_SR
            weighting = self.get_instrument_scaling_factor(instrument_code)
            apply_weight_to_costs_only = True

            instr_pandl = weighted(
                instr_pandl,
                weighting=weighting,
                apply_weight_to_costs_only=apply_weight_to_costs_only)

        else:
            # Costs wil be correct
            # We don't need to do anything
            pass

        return instr_pandl
Exemplo n.º 10
0
    def pandl_for_instrument_with_multiplier(self,
                                             instrument_code,
                                             delayfill=True,
                                             roundpositions=True):
        """
        Get the p&l for one instrument, using variable capital

        :param instrument_code: instrument to get values for
        :type instrument_code: str

        :param delayfill: Lag fills by one day
        :type delayfill: bool

        :param roundpositions: Round positions to whole contracts
        :type roundpositions: bool

        :returns: accountCurve

        """

        self.log.msg(
            "Calculating pandl for instrument for %s with capital multiplier" %
            instrument_code,
            instrument_code=instrument_code)

        price = self.get_daily_price(instrument_code)
        positions = self.get_buffered_position_with_multiplier(
            instrument_code, roundpositions=roundpositions)
        fx = self.get_fx_rate(instrument_code)
        value_of_price_point = self.get_value_of_price_move(instrument_code)
        get_daily_returns_volatility = self.get_daily_returns_volatility(
            instrument_code)

        capital = self.get_actual_capital(
            delayfill=delayfill, roundpositions=roundpositions)

        ann_risk_target = self.get_ann_risk_target()

        (SR_cost, cash_costs) = self.get_costs(instrument_code)

        instr_pandl = accountCurve(
            price,
            positions=positions,
            delayfill=delayfill,
            roundpositions=roundpositions,
            fx=fx,
            value_of_price_point=value_of_price_point,
            capital=capital,
            ann_risk_target=ann_risk_target,
            SR_cost=SR_cost,
            cash_costs=cash_costs,
            get_daily_returns_volatility=get_daily_returns_volatility)

        if SR_cost is not None:
            # Note that SR cost is done as a proportion of capital
            # Since we're only using part of the capital we need to correct
            # for this
            turnover_for_SR = self.instrument_turnover(
                instrument_code, roundpositions=roundpositions)
            SR_cost = SR_cost * turnover_for_SR
            weighting = self.get_instrument_scaling_factor(instrument_code)
            apply_weight_to_costs_only = True

            instr_pandl = weighted(
                instr_pandl,
                weighting=weighting,
                apply_weight_to_costs_only=apply_weight_to_costs_only)

        else:
            # Costs wil be correct
            # We don't need to do anything
            pass

        return instr_pandl