def test_simple_trading_rule(self): """ This is (mostly) the code from 'examples.introduction.asimpletradingrule', but without graph plotting """ # Get some data data = csvFuturesSimData() print(data) print(data.get_instrument_list()) print(data.get_raw_price("EDOLLAR").tail(5)) print(data["VIX"]) print(data.keys()) print(data.get_instrument_raw_carry_data("EDOLLAR").tail(6)) instrument_code = "VIX" price = data.daily_prices(instrument_code) ewmac = self.calc_ewmac_forecast(price, 32, 128) ewmac2 = self.calc_ewmac_forecast(price, 16, 64) ewmac.columns = ["forecast"] print(ewmac.tail(5)) account = accountCurve(price, forecast=ewmac) account2 = accountCurve(price, forecast=ewmac2) account.curve() account2.curve() print(account.percent().stats()) print(account2.percent().stats())
def pandl_for_subsystem(self, instrument_code, delayfill=True, roundpositions=False): """ 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_subsystem("US10", percentage=True).ann_std() 0.23422378634127036 """ self.log.msg( "Calculating pandl for subsystem for instrument %s" % instrument_code, instrument_code=instrument_code) price = self.get_daily_price(instrument_code) positions = self.get_aligned_subsystem_position(instrument_code) 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) (SR_cost, cash_costs) = self.get_costs(instrument_code) capital = self.get_notional_capital() ann_risk_target = self.get_ann_risk_target() instr_pandl = accountCurve( price, positions=positions, delayfill=delayfill, roundpositions=roundpositions, fx=fx, value_of_price_point=value_of_price_point, capital=capital, SR_cost=SR_cost, cash_costs=cash_costs, get_daily_returns_volatility=get_daily_returns_volatility, ann_risk_target=ann_risk_target) return instr_pandl
def main(): lector = Reader() activo = "FRED/AAA10Y" # df = lector.read_quandl_option(activo) df = lector.read_csv_option('BTCdata') df = pd.read_csv('BTCdata.csv', parse_dates={'Date': ["date", "time"]}) df = df.set_index('Date')[['close']] #Se descarga un DF desde quandl, esto con el fin de cambiar la forma en que se cargan los datos data = getDataFrame(df) def calc_ewmac_forecast(price, Lfast, Lslow=None): """ Calculate the ewmac trading fule forecast, given a price and EWMA speeds Lfast, Lslow and vol_lookback """ # price: This is the stitched price series # We can't use the price of the contract we're trading, or the volatility # will be jumpy # And we'll miss out on the rolldown. See # http://qoppac.blogspot.co.uk/2015/05/systems-building-futures-rolling.html if Lslow is None: Lslow = 4 * Lfast # We don't need to calculate the decay parameter, just use the span # directly fast_ewma = price.ewm(span=Lfast).mean() slow_ewma = price.ewm(span=Lslow).mean() raw_ewmac = fast_ewma - slow_ewma vol = robust_vol_calc(price.diff()) return raw_ewmac / vol price = data.get_close_price(df) #Obtengo los precios de cierre. print(price.tail(5)) ewmac = calc_ewmac_forecast(price, 32, 128) ewmac.columns = ['forecast'] print(ewmac.tail(5)) from matplotlib.pyplot import show ewmac.plot() show() from syscore.accounting import accountCurve account = accountCurve(price, forecast=ewmac) account.curve() account.curve().plot() show() print(account.percent().stats()) return data, price, ewmac
def _pandl_for_instrument( system, instrument_code, this_stage, percentage, delayfill, roundpositions): this_stage.log.msg("Calculating pandl for instrument for %s" % instrument_code, instrument_code=instrument_code) price = this_stage.get_daily_price(instrument_code) positions = this_stage.get_notional_position(instrument_code) fx = this_stage.get_fx_rate(instrument_code) value_of_price_point = this_stage.get_value_of_price_move( instrument_code) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) capital = this_stage.get_notional_capital() ann_risk_target = this_stage.get_ann_risk_target() ## FIX ME place holder cost_per_block=None SR_cost=0.0 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, percentage=percentage, SR_cost=SR_cost, cost_per_block=cost_per_block, get_daily_returns_volatility=get_daily_returns_volatility) return instr_pandl
def _pandl_for_subsystem( system, instrument_code, this_stage, percentage, delayfill, roundpositions): this_stage.log.msg("Calculating pandl for subsystem for instrument %s" % instrument_code, instrument_code=instrument_code) price = this_stage.get_daily_price(instrument_code) positions = this_stage.get_subsystem_position(instrument_code) fx = this_stage.get_fx_rate(instrument_code) value_of_price_point = this_stage.get_value_of_price_move( instrument_code) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) (SR_cost, cash_costs)=this_stage.get_costs(instrument_code) if SR_cost is not None: turnover_for_SR = this_stage.subsystem_turnover(instrument_code, roundpositions = roundpositions) SR_cost = SR_cost * turnover_for_SR capital = this_stage.get_notional_capital() ann_risk_target = this_stage.get_ann_risk_target() instr_pandl = accountCurve(price, positions = positions, delayfill = delayfill, roundpositions = roundpositions, fx=fx, value_of_price_point=value_of_price_point, capital=capital, percentage=percentage, SR_cost=SR_cost, cash_costs = cash_costs, get_daily_returns_volatility=get_daily_returns_volatility, ann_risk_target = ann_risk_target) return instr_pandl
def pandl_for_subsystem(self, instrument_code, delayfill=True, roundpositions=False): """ 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_subsystem("US10", percentage=True).ann_std() 0.23422378634127036 """ self.log.msg("Calculating pandl for subsystem for instrument %s" % instrument_code, instrument_code=instrument_code) price = self.get_daily_price(instrument_code) positions = self.get_aligned_subsystem_position(instrument_code) 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) (SR_cost, cash_costs) = self.get_costs(instrument_code) SR_cost = SR_cost * self.subsystem_turnover(instrument_code) capital = self.get_notional_capital() ann_risk_target = self.get_ann_risk_target() instr_pandl = accountCurve( price, positions=positions, delayfill=delayfill, roundpositions=roundpositions, fx=fx, value_of_price_point=value_of_price_point, capital=capital, SR_cost=SR_cost, cash_costs=cash_costs, get_daily_returns_volatility=get_daily_returns_volatility, ann_risk_target=ann_risk_target) return instr_pandl
def pandl_for_instrument_forecast(self, instrument_code, rule_variation_name, delayfill=True): """ Get the p&l for one instrument and forecast; as % of arbitrary 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 >>> 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_forecast("EDOLLAR", "ewmac8").ann_std() 0.20270495775586916 """ self.log.msg( "Calculating pandl for instrument forecast for %s %s" % (instrument_code, rule_variation_name), instrument_code=instrument_code, rule_variation_name=rule_variation_name) # by construction all these things are aligned price = self.get_daily_price(instrument_code) forecast = self.get_aligned_forecast(instrument_code, rule_variation_name) get_daily_returns_volatility = self.get_daily_returns_volatility( instrument_code) # We NEVER use cash costs for forecasts ... SR_cost = self.get_SR_cost_for_instrument_forecast( instrument_code, rule_variation_name) # We use percentage returns (as no 'capital') and don't round # positions pandl_fcast = accountCurve( price, forecast=forecast, delayfill=delayfill, roundpositions=False, value_of_price_point=1.0, capital=ARBITRARY_FORECAST_CAPITAL, SR_cost=SR_cost, cash_costs=None, get_daily_returns_volatility=get_daily_returns_volatility) return pandl_fcast
def pandl_for_instrument_forecast( self, instrument_code, rule_variation_name, delayfill=True, weighting=None): """ Get the p&l for one instrument and forecast; as % of arbitrary capital This is not cached as it is calculated with different weighting schemes :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 :param weighting: Weights to use which will be multiplied by returns :type weighting: pd.Dataframe :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_forecast("EDOLLAR", "ewmac8").ann_std() 0.20270495775586916 """ ## NOT CACHED - this is deliberate - as we call with different weights... this_stage=self this_stage.log.msg("Calculating pandl for instrument forecast for %s %s" % (instrument_code, rule_variation_name), instrument_code=instrument_code, rule_variation_name=rule_variation_name) price = this_stage.get_daily_price(instrument_code) forecast = this_stage.get_capped_forecast( instrument_code, rule_variation_name) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) ## We NEVER use cash costs for forecasts ... turnover_for_SR=this_stage.forecast_turnover(instrument_code, rule_variation_name) SR_cost=this_stage.get_SR_cost(instrument_code)* turnover_for_SR ## We use percentage returns (as no 'capital') and don't round positions pandl_fcast = accountCurve(price, forecast=forecast, delayfill=delayfill, roundpositions=False, value_of_price_point=1.0, capital=None, percentage=True, SR_cost=SR_cost, cash_costs=None, get_daily_returns_volatility=get_daily_returns_volatility, weighting = weighting) return pandl_fcast
def _portfolio(system, not_used, this_stage, percentage, delayfill, roundpositions): instruments=this_stage.get_instrument_list() port_pandl=[this_stage.pandl_for_instrument(instrument_code, percentage=percentage, delayfill=delayfill, roundpositions=roundpositions) for instrument_code in instruments] port_pandl=pd.concat(port_pandl, axis=1).sum(axis=1) port_pandl=accountCurve(port_pandl) return port_pandl
def _pandl_for_instrument(system, instrument_code, this_stage, percentage, delayfill, roundpositions): this_stage.log.msg("Calculating pandl for instrument for %s" % instrument_code, instrument_code=instrument_code) price = this_stage.get_daily_price(instrument_code) positions = this_stage.get_buffered_position( instrument_code, roundpositions=roundpositions) fx = this_stage.get_fx_rate(instrument_code) value_of_price_point = this_stage.get_value_of_price_move( instrument_code) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) capital = this_stage.get_notional_capital() ann_risk_target = this_stage.get_ann_risk_target() (SR_cost, cash_costs) = this_stage.get_costs(instrument_code) 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 = this_stage.instrument_turnover( instrument_code, roundpositions=roundpositions) SR_cost = SR_cost * turnover_for_SR weighting = this_stage.get_instrument_scaling_factor( instrument_code) apply_weight_to_costs_only = True else: ## Costs wil be correct ## We don't need to do anything weighting = None apply_weight_to_costs_only = False 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, percentage=percentage, SR_cost=SR_cost, cash_costs=cash_costs, get_daily_returns_volatility=get_daily_returns_volatility, weighting=weighting, apply_weight_to_costs_only=apply_weight_to_costs_only) return instr_pandl
def _portfolio(system, not_used, this_stage, percentage, delayfill, roundpositions): this_stage.log.terse("Calculating pandl for portfolio") instruments = this_stage.get_instrument_list() port_pandl = [ this_stage.pandl_for_instrument(instrument_code, percentage=percentage, delayfill=delayfill, roundpositions=roundpositions) for instrument_code in instruments ] port_pandl = pd.concat(port_pandl, axis=1).sum(axis=1) port_pandl = accountCurve(port_pandl) return port_pandl
def _pandl_for_instrument( system, instrument_code, this_stage, percentage, delayfill, roundpositions): this_stage.log.msg("Calculating pandl for instrument for %s" % instrument_code, instrument_code=instrument_code) price = this_stage.get_daily_price(instrument_code) positions = this_stage.get_buffered_position(instrument_code, roundpositions = roundpositions) fx = this_stage.get_fx_rate(instrument_code) value_of_price_point = this_stage.get_value_of_price_move( instrument_code) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) capital = this_stage.get_notional_capital() ann_risk_target = this_stage.get_ann_risk_target() (SR_cost, cash_costs)=this_stage.get_costs(instrument_code) 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=this_stage.instrument_turnover(instrument_code, roundpositions = roundpositions) SR_cost = SR_cost * turnover_for_SR weighting = this_stage.get_instrument_scaling_factor(instrument_code) apply_weight_to_costs_only=True else: ## Costs wil be correct ## We don't need to do anything weighting = None apply_weight_to_costs_only=False 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, percentage=percentage, SR_cost=SR_cost, cash_costs = cash_costs, get_daily_returns_volatility=get_daily_returns_volatility, weighting = weighting, apply_weight_to_costs_only=apply_weight_to_costs_only) return instr_pandl
def _pandl_for_subsystem(system, instrument_code, this_stage, percentage, delayfill, roundpositions): this_stage.log.msg( "Calculating pandl for subsystem for instrument %s" % instrument_code, instrument_code=instrument_code) price = this_stage.get_daily_price(instrument_code) positions = this_stage.get_subsystem_position(instrument_code) fx = this_stage.get_fx_rate(instrument_code) value_of_price_point = this_stage.get_value_of_price_move( instrument_code) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) (SR_cost, cash_costs) = this_stage.get_costs(instrument_code) if SR_cost is not None: turnover_for_SR = this_stage.subsystem_turnover( instrument_code, roundpositions=roundpositions) SR_cost = SR_cost * turnover_for_SR capital = this_stage.get_notional_capital() ann_risk_target = this_stage.get_ann_risk_target() instr_pandl = accountCurve( price, positions=positions, delayfill=delayfill, roundpositions=roundpositions, fx=fx, value_of_price_point=value_of_price_point, capital=capital, percentage=percentage, SR_cost=SR_cost, cash_costs=cash_costs, get_daily_returns_volatility=get_daily_returns_volatility, ann_risk_target=ann_risk_target) return instr_pandl
def _pandl_for_instrument_forecast( system, instrument_code, rule_variation_name, this_stage, delayfill): this_stage.log.msg("Calculating pandl for instrument forecast for %s %s" % (instrument_code, rule_variation_name), instrument_code=instrument_code, rule_variation_name=rule_variation_name) price = this_stage.get_daily_price(instrument_code) forecast = this_stage.get_capped_forecast( instrument_code, rule_variation_name) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) ## FIX ME place holder SR_cost=0.0 pandl_fcast = accountCurve(price, forecast=forecast, delayfill=delayfill, roundpositions=False, value_of_price_point=1.0, capital=None, percentage=True, SR_cost=SR_cost, cost_per_block=None, get_daily_returns_volatility=get_daily_returns_volatility) return pandl_fcast
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
import inspect import logging import pandas as pd import sys; sys.path.append('../..') from matplotlib.pyplot import show, title from systems.provided.futures_chapter15.estimatedsystem import futures_system system=futures_system() #system.forecastScaleCap.get_scaled_forecast("EDOLLAR", "ewmac64_256").plot() res=system.rules.get_raw_forecast("CRUDE_W", "carry") res.to_csv("out.csv") print (res.head(5)) f = '../../sysdata/legacycsv/CRUDE_W_price.csv' df = pd.read_csv(f,index_col=0,parse_dates=True) from syscore.accounting import accountCurve account = accountCurve(df.PRICE, forecast=res) tmp = account.percent() print(tmp.stats())
vol = robust_vol_calc(price.diff()) return raw_ewmac / vol """ Try it out (this isn't properly scaled at this stage of course) """ instrument_code = 'EDOLLAR' price = data.daily_prices(instrument_code) ewmac = calc_ewmac_forecast(price, 32, 128) ewmac.columns = ['forecast'] print(ewmac.tail(5)) from matplotlib.pyplot import show ewmac.plot() show() """ Did we make money? """ from syscore.accounting import accountCurve account = accountCurve(price, forecast=ewmac) account.curve() account.curve().plot() show() print(account.percent().stats())
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
(this isn't properly scaled at this stage of course) """ instrument_code = "VIX" price = data.daily_prices(instrument_code) ewmac = calc_ewmac_forecast(price, 32, 128) ewmac2 = calc_ewmac_forecast(price, 16, 64) ewmac.columns = ["forecast"] print(ewmac.tail(5)) from matplotlib.pyplot import show ewmac.plot() show() """ Did we make money? """ from syscore.accounting import accountCurve account = accountCurve(price, forecast=ewmac) account2 = accountCurve(price, forecast=ewmac2) account.curve() account.curve().plot() show() print(account.percent().stats())
import inspect import logging import pandas as pd import sys sys.path.append('../..') from matplotlib.pyplot import show, title from systems.provided.futures_chapter15.estimatedsystem import futures_system system = futures_system() forecast = system.rules.get_raw_forecast("MXP", "carry") #forecast=system.rules.get_raw_forecast("CRUDE_W", "ewmac64_256") #f = '../../sysdata/legacycsv/CRUDE_W_price.csv' #f = '../../sysdata/legacycsv/EDOLLAR_price.csv' f = '../../sysdata/legacycsv/MXP_price.csv' df = pd.read_csv(f, index_col=0, parse_dates=True) from syscore.accounting import accountCurve account = accountCurve(df.PRICE, forecast=forecast) print(account.sharpe())
raw_ewmac = fast_ewma - slow_ewma vol = robust_vol_calc(price.diff()) return divide_df_single_column(raw_ewmac, vol) """ Try it out (this isn't properly scaled at this stage of course) """ instrument_code = 'EDOLLAR' price = data.daily_prices(instrument_code) ewmac = calc_ewmac_forecast(price, 32, 128) ewmac.columns=['forecast'] print(ewmac.tail(5)) from matplotlib.pyplot import show ewmac.plot() show() """ Did we make money? """ from syscore.accounting import accountCurve account = accountCurve(price, forecast=ewmac, percentage=True) account.curve().plot() show() print(account.stats())
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
def pandl_for_instrument_forecast(self, instrument_code, rule_variation_name, delayfill=True, weighting=None): """ Get the p&l for one instrument and forecast; as % of arbitrary capital This is not cached as it is calculated with different weighting schemes :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 :param weighting: Weights to use which will be multiplied by returns :type weighting: pd.Dataframe :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_forecast("EDOLLAR", "ewmac8").ann_std() 0.20270495775586916 """ ## NOT CACHED - this is deliberate - as we call with different weights... this_stage = self this_stage.log.msg( "Calculating pandl for instrument forecast for %s %s" % (instrument_code, rule_variation_name), instrument_code=instrument_code, rule_variation_name=rule_variation_name) price = this_stage.get_daily_price(instrument_code) forecast = this_stage.get_capped_forecast(instrument_code, rule_variation_name) get_daily_returns_volatility = this_stage.get_daily_returns_volatility( instrument_code) ## We NEVER use cash costs for forecasts ... turnover_for_SR = this_stage.forecast_turnover(instrument_code, rule_variation_name) SR_cost = this_stage.get_SR_cost(instrument_code) * turnover_for_SR ## We use percentage returns (as no 'capital') and don't round positions pandl_fcast = accountCurve( price, forecast=forecast, delayfill=delayfill, roundpositions=False, value_of_price_point=1.0, capital=None, percentage=True, SR_cost=SR_cost, cash_costs=None, get_daily_returns_volatility=get_daily_returns_volatility, weighting=weighting) return pandl_fcast
raw_ewmac = fast_ewma - slow_ewma vol = robust_vol_calc(price.diff()) return divide_df_single_column(raw_ewmac, vol) """ Try it out (this isn't properly scaled at this stage of course) """ instrument_code = 'EDOLLAR' price = data.get_daily_price(instrument_code) ewmac = calc_ewmac_forecast(price, 32, 128) ewmac.columns=['forecast'] print(ewmac.tail(5)) from matplotlib.pyplot import show ewmac.plot() show() """ Did we make money? """ from syscore.accounting import accountCurve account = accountCurve(price, forecast=ewmac, percentage=True) account.curve().plot() show() print(account.stats())
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