sys.path.append('../..') import numpy as np from systems.basesystem import System from systems.forecast_combine import ForecastCombineEstimated from sysdata.csvdata import csvFuturesData from systems.futures.rawdata import FuturesRawData from systems.forecasting import Rules from sysdata.configdata import Config from systems.forecast_scale_cap import ForecastScaleCapFixed, ForecastScaleCapEstimated from systems.account import Account data = csvFuturesData("sysdata.tests") rawdata = FuturesRawData() rules = Rules() config = Config("examples.test14.yaml") fcs = ForecastScaleCapEstimated() accounts = Account() from systems.portfolio import PortfoliosEstimated from systems.positionsizing import PositionSizing system = System([ accounts, rawdata, rules, fcs, ForecastCombineEstimated(), PositionSizing(), PortfoliosEstimated() ], data, config) print(system.portfolio.get_instrument_correlation_matrix().corr_list) #array([[ 1. , 0.87041785], # [ 0.87041785, 1. ]])
ewmac_rule """ ... or two... """ ewmac_8 = TradingRule((ewmac, [], dict(Lfast=8, Lslow=32))) ewmac_32 = TradingRule( dict(function=ewmac, other_args=dict(Lfast=32, Lslow=128))) my_rules = Rules(dict(ewmac8=ewmac_8, ewmac32=ewmac_32)) print(my_rules.trading_rules()['ewmac32']) my_system = System([my_rules], data) my_system.rules.get_raw_forecast("EDOLLAR", "ewmac32").tail(5) from sysdata.configdata import Config my_config = Config() my_config empty_rules = Rules() my_config.trading_rules = dict(ewmac8=ewmac_8, ewmac32=ewmac_32) my_system = System([empty_rules], data, my_config) my_system.rules.get_raw_forecast("EDOLLAR", "ewmac32").tail(5) from systems.forecast_scale_cap import ForecastScaleCapFixed, ForecastScaleCapEstimated ## we can estimate these ourselves my_config.instruments = ["US10", "EDOLLAR", "CORN", "SP500"] fcs_estimate = ForecastScaleCapEstimated() my_system = System([fcs_estimate, my_rules], data, my_config) print( my_system.forecastScaleCap.get_forecast_scalar("EDOLLAR",
print("mean %.3f std %.3f" % (np.nanmean(all_turnover_values), np.nanstd(all_turnover_values))) ## limit the rules to just breakout for now my_config = Config("examples.breakout.breakoutfuturesestimateconfig.yaml") my_config.trading_rules = dict([(rule_name, my_config.trading_rules[rule_name]) for rule_name in variations]) system = futures_system(config=my_config, log_level="on") print(system.combForecast.get_forecast_weights("EUROSTX").irow(-1)) print(system.combForecast.get_forecast_weights("V2X").irow(-1)) ## now include other rules """ my_config = Config("examples.breakout.breakoutfuturesestimateconfig.yaml") #my_config.forecast_weight_estimate["method"]="bootstrap" system = futures_system(config=my_config, log_level="on") bvariations=["breakout"+str(ws) for ws in [10, 20, 40, 80, 160, 320]] #cProfile.run("system.accounts.pandl_for_all_trading_rules_unweighted().to_frame()","restats") system.accounts.pandl_for_all_trading_rules_unweighted().to_frame().loc[:, bvariations].cumsum().plot() show() """ variations=["breakout"+str(ws) for ws in [10, 20, 40, 80, 160, 320]]+[ "ewmac%d_%d" % (fast, fast*4) for fast in [2,4,8,16,32, 64]]+["carry"] corr_result=system.combForecast.get_forecast_correlation_matrices("US10")
def __init__(self, stage_list, data, config=None, log=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.Data (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.csvdata import csvFuturesData >>> data=csvFuturesData() >>> System([stage], data) System with stages: unnamed """ if config is None: # Default - for very dull systems this is sufficient config = Config() config.fill_with_defaults() setattr(self, "data", data) setattr(self, "config", config) setattr(self, "log", log) setattr(data, "log", log.setup(stage="data")) setattr(config, "log", log.setup(stage="config")) protected = [] nopickle = [] stage_names = [] assert isinstance(stage_list, list) for stage in stage_list: """ This is where we put the methods to store various stages of the process """ # Stages have names, which are also how we find them in the system # attributes sub_name = stage.name # Each stage has a link back to the parent system stage._system_init(self) # and a log log = log.setup(stage=sub_name) setattr(stage, "log", log) if sub_name in stage_names: raise Exception( "You have duplicate subsystems with the name %s. Remove " "one of them, or change a name." % sub_name) setattr(self, sub_name, stage) stage_names.append(sub_name) # list of attributes / methods of the stage which are protected stage_protected = getattr(stage, "_protected", []) stage_protected = [(sub_name, protected_item, "*") for protected_item in stage_protected] protected += stage_protected stage_nopickle = getattr(stage, "_nopickle", []) stage_nopickle = [(sub_name, protected_item, "*") for protected_item in stage_nopickle] nopickle += stage_nopickle setattr(self, "_stage_names", stage_names) """ The cache hides all intermediate results We call optimal_positions and then that propogates back finding all the data we need The results are then cached in the object. Should we call delete_instrument_data (in base class system) then everything related to a particular instrument is removed from these 'nodes' except for protected items This is very useful in live trading when we don't want to update eg cross sectional data every sample """ setattr(self, "_cache", dict()) setattr(self, "_protected", protected) setattr(self, "_nopickle", nopickle)
from systems.account import Account from systems.forecast_combine import ForecastCombine from systems.forecast_scale_cap import ForecastScaleCap from systems.basesystem import System from sysdata.csvdata import csvFuturesData from systems.forecasting import Rules from systems.forecasting import TradingRule data = csvFuturesData() ewmac_8 = TradingRule((ewmac, [], dict(Lfast=8, Lslow=32))) ewmac_32 = TradingRule( dict(function=ewmac, other_args=dict(Lfast=32, Lslow=128))) my_rules = Rules(dict(ewmac8=ewmac_8, ewmac32=ewmac_32)) my_config = Config() my_config my_config.trading_rules = dict(ewmac8=ewmac_8, ewmac32=ewmac_32) ## we can estimate these ourselves #my_config.instruments=[ "US20", "NASDAQ", "SP500"] my_config.instruments = ["SP500"] #my_config.forecast_weight_estimate=dict(method="one_period") my_config.forecast_weight_estimate = dict(method="bootstrap") my_config.forecast_weight_estimate['monte_runs'] = 50 my_config.use_forecast_weight_estimates = True my_account = Account() combiner = ForecastCombine() fcs = ForecastScaleCap() my_system = System([my_account, fcs, my_rules, combiner], data, my_config)
def __init__(self, stage_list, data, config=None, log=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.csv.csv_sim_futures_data import csvFuturesSimData >>> data=csvFuturesSimData() >>> System([stage], data) System base_system with .config, .data, and .stages: unnamed """ if config is None: # Default - for very dull systems this is sufficient config = Config() setattr(self, "data", data) setattr(self, "config", config) self._log = log self.config._system_init(self) self.data._system_init(self) stage_names = [] try: iter(stage_list) except AssertionError: raise Exception( "You didn't pass a list into this System instance; even just one stage should be System([stage_instance])" ) for stage in stage_list: """ This is where we put the methods to store various stages of the process """ # Stages have names, which are also how we find them in the system # attributes sub_name = stage.name # Each stage has a link back to the parent system # This init sets this, and also passes the system logging object stage._system_init(self) if sub_name in stage_names: raise Exception( "You have duplicate subsystems with the name %s. Remove " "one of them, or change a name." % sub_name) setattr(self, sub_name, stage) stage_names.append(sub_name) setattr(self, "_stage_names", stage_names) """ The cache hides all intermediate results We call optimal_positions and then that propogates back finding all the data we need The results are then cached in the object. Should we call delete_instrument_data (in base class system) then everything related to a particular instrument is removed from these 'nodes' except for protected items This is very useful in live trading when we don't want to update eg cross sectional data every sample """ setattr(self, "cache", systemCache(self)) self.name = "base_system" # makes caching work and for general consistency
PortfoliosFixed(), PositionSizing(), ForecastCombineEstimated(), ForecastScaleCapEstimated(), rules, RawData() ], csvFuturesData(), config) my_system.set_logging_level(log_level) return my_system rules = create_rules_for_random_system() config = Config( dict(use_forecast_scale_estimates=True, use_forecast_weight_estimates=True, forecast_scalar_estimate=dict(pool_instruments=True), instrument_weights=dict(EDOLLAR=.25, US10=.25, CORN=.25, SP500=.25), instrument_div_multiplier=1.5)) system = random_system_for_regression(config, rules) system.accounts.portfolio().cumsum().plot() show() ans = system.accounts.pandl_for_all_trading_rules_unweighted() ans.gross.to_frame().cumsum().plot() legend() show() ans.costs.to_frame().cumsum().plot()
from systems.provided.example.simplesystem import simplesystem my_system = simplesystem(log_level="on") print(my_system) print(my_system.portfolio.get_notional_position("EDOLLAR").tail(5)) from sysdata.csv.csv_sim_futures_data import csvFuturesSimData from sysdata.configdata import Config """ Now loading config and data """ my_config = Config("systems.provided.example.simplesystemconfig.yaml") my_data = csvFuturesSimData() my_system = simplesystem(config=my_config, data=my_data) print(my_system.portfolio.get_notional_position("EDOLLAR").tail(5)) """ Let's get the chapter 15 system """ from systems.provided.futures_chapter15.basesystem import futures_system from matplotlib.pyplot import show system = futures_system(log_level="on") print(system.accounts.portfolio().sharpe()) system.accounts.portfolio().curve().plot() show() """ Same for estimated system """
return new_position simple_mav_rule = TradingRule( dict(function=simple_mav, other_args=dict(long=2, short=8))) simple_mav_rule_with_vol = TradingRule( dict(function=mav_with_vol, data=["rawdata.get_daily_prices", "rawdata.daily_returns_volatility"], other_args=dict(long=16, short=4))) """ now run the basic system; 16,64 crossover plus X=8 """ # weights = dict(EDOLLAR=1.0) config = Config( dict(trading_rules=dict(simple_mav=simple_mav_rule), Xfactor=8, percentage_vol_target=16.0)) config_2 = Config( dict(trading_rules=dict(simple_mav_with_vol=simple_mav_rule_with_vol), Xfactor=8, percentage_vol_target=16.0)) config_3 = Config( dict(trading_rules=dict(simple_mav_with_vol=simple_mav_rule_with_vol), Xfactor=8, percentage_vol_target=16.0, use_forecast_scale_estimates=True)) data = csvFuturesSimData()
from systems.provided.futures_chapter15.basesystem import futures_system from systems.provided.example.rules import ewmac_forecast_with_defaults as ewmac from systems.forecasting import TradingRule from systems.forecasting import Rules from sysdata.configdata import Config my_config = Config("interface.futuresconfig.yaml") # Config object system = futures_system(log_level="on", config=my_config) # We parse the config object acording the class, for basesystem, the keyword is config, this change # accordding to class, as you can see we don't need to parse the stages.It makes everything # futures_system does but with customs atributes. portfolio = system.accounts.portfolio() print(system.positionSize.get_subsystem_position("EDOLLAR").tail(2)) # The output is somenthing like below # ss_position # 2015-12-10 1.811465 # 2015-12-11 2.544598
import pandas as pd from pprint import pprint from matplotlib import pyplot as plt from private.estimatedsystemavanti import futures_system from sysdata.configdata import Config from sysdata.csvdata import csvFuturesData pandl_df = pd.DataFrame() # Initializing system. my_config = Config("private.nocarryconfig2.yaml") data = csvFuturesData("private.noCarryData") #This is the path to the CSV data. system = futures_system(log_level="on", config=my_config, data=data) # Making the backtest for the complete portfolio. instruments = system.config.instruments portfolio = system.accounts.portfolio() info = {} for item in instruments: series = [] series.append(data.daily_prices(item)) series.append(system.accounts.get_buffered_position(item)) series.append(system.combForecast.get_combined_forecast(item)) series.append(portfolio.to_frame()[item]) series.append(portfolio.to_frame()[item].cumsum())