def test_per_share_with_minimum(self): # minimum is met by the first trade self.verify_per_unit_commissions( PerShare(cost=0.0075, min_trade_cost=1), commission_totals=[1.725, 3, 3.75], sid=1, ) # minimum is met by the second trade self.verify_per_unit_commissions( PerShare(cost=0.0075, min_trade_cost=2.5), commission_totals=[2.5, 3, 3.75], sid=1, ) # minimum is met by the third trade self.verify_per_unit_commissions( PerShare(cost=0.0075, min_trade_cost=3.5), commission_totals=[3.5, 3.5, 3.75], sid=1, ) # minimum is not met by any of the trades self.verify_per_unit_commissions( PerShare(cost=0.0075, min_trade_cost=5.5), commission_totals=[5.5, 5.5, 5.5], sid=1, )
def test_per_share_no_minimum(self): model = PerShare(cost=0.0075, min_trade_cost=None) order, txns = self.generate_order_and_txns() # make sure each commission is pro-rated self.assertAlmostEqual(1.725, model.calculate(order, txns[0])) self.assertAlmostEqual(1.275, model.calculate(order, txns[1])) self.assertAlmostEqual(0.75, model.calculate(order, txns[2]))
def __init__(self, data_frequency, equity_slippage=None, future_slippage=None, equity_commission=None, future_commission=None, cancel_policy=None, stock_exchange='NYSE'): # these orders are aggregated by asset self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # holding orders that have come in since the last event. self.new_orders = [] self.current_dt = None self.max_shares = int(1e+11) self.slippage_models = { Equity: equity_slippage or FixedBasisPointsSlippage(), Future: future_slippage or VolatilityVolumeShare( volume_limit=DEFAULT_FUTURE_VOLUME_SLIPPAGE_BAR_LIMIT, ), } self.commission_models = { Equity: equity_commission or PerShare(), Future: future_commission or PerContract( cost=DEFAULT_PER_CONTRACT_COST, exchange_fee=FUTURE_EXCHANGE_FEES_BY_SYMBOL, ), } self.data_frequency = data_frequency self.cancel_policy = cancel_policy if cancel_policy else NeverCancel()
def __init__(self, data_frequency, broker): self.broker = broker self._processed_closed_orders = [] self._processed_transactions = [] self.data_frequency = data_frequency self.new_orders = [] self.max_shares = int(1e+11) self.slippage_models = { Equity: FixedBasisPointsSlippage(), Future: VolatilityVolumeShare( volume_limit=DEFAULT_FUTURE_VOLUME_SLIPPAGE_BAR_LIMIT, ), } self.commission_models = { Equity: PerShare(), Future: PerContract( cost=DEFAULT_PER_CONTRACT_COST, exchange_fee=FUTURE_EXCHANGE_FEES_BY_SYMBOL, ), } log.info('Initialized blotter_live')
def __init__(self, data_frequency, equity_slippage=None, future_slippage=None, equity_commission=None, future_commission=None, cancel_policy=None): # these orders are aggregated by asset self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # holding orders that have come in since the last event. self.new_orders = [] self.current_dt = None self.max_shares = int(1e+11) self.slippage_models = { Equity: equity_slippage or VolumeShareSlippage(), Future: future_slippage or VolumeShareSlippage(), } self.commission_models = { Equity: equity_commission or PerShare(), Future: future_commission or PerTrade(cost=DEFAULT_FUTURE_COST_PER_TRADE, ), } self.data_frequency = data_frequency self.cancel_policy = cancel_policy if cancel_policy else NeverCancel()
def __init__(self, data_frequency, asset_finder, slippage_func=None, commission=None, cancel_policy=None): # these orders are aggregated by sid self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # all our legacy order management code works with integer sids. # this lets us convert those to assets when needed. ideally, we'd just # revamp all the legacy code to work with assets. self.asset_finder = asset_finder # holding orders that have come in since the last event. self.new_orders = [] self.current_dt = None self.max_shares = int(1e+11) self.slippage_func = slippage_func or VolumeShareSlippage() self.commission = commission or PerShare() self.data_frequency = data_frequency self.cancel_policy = cancel_policy if cancel_policy else NeverCancel()
def __init__(self, *args, **kwargs): """ Initialize sids and other state variables. """ self.done = False self.order = None self.frame_count = 0 self._portfolio = None self.datetime = None self.registered_transforms = {} self.transforms = [] self.sources = [] self.logger = None # default components for transact self.slippage = VolumeShareSlippage() self.commission = PerShare() # an algorithm subclass needs to set initialized to True # when it is fully initialized. self.initialized = False # call to user-defined constructor method self.initialize(*args, **kwargs)
def initialize(self): self.ordered = False self.sale_price = None # this makes the math easier to check self.set_slippage(FixedSlippage()) self.set_commission(PerShare(0))
def test_per_share_shrinking_position(self): model = PerShare(cost=0.0075, min_trade_cost=None) fill_amounts = [-230, -170, -100] order, txns = self.generate_order_and_txns(sid=1, order_amount=-500, fill_amounts=fill_amounts) expected_commissions = [1.725, 1.275, 0.75] # make sure each commission is positive and pro-rated for fill_amount, expected_commission, txn in zip( fill_amounts, expected_commissions, txns): commission = model.calculate(order, txn) assert round(abs(expected_commission - commission), 7) == 0 order.filled += fill_amount order.commission += commission
def test_per_share_shrinking_position(self): model = PerShare(cost=0.0075, min_trade_cost=None) fill_amounts = [-230, -170, -100] order, txns = self.generate_order_and_txns( sid=1, order_amount=-500, fill_amounts=fill_amounts ) expected_commissions = [1.725, 1.275, 0.75] # make sure each commission is positive and pro-rated for fill_amount, expected_commission, txn in \ zip(fill_amounts, expected_commissions, txns): commission = model.calculate(order, txn) self.assertAlmostEqual(expected_commission, commission) order.filled += fill_amount order.commission += commission
def __init__(self): self.transact = transact_partial(VolumeShareSlippage(), PerShare()) # these orders are aggregated by sid self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # holding orders that have come in since the last # event. self.new_orders = []
def __init__(self, *args, **kwargs): """Initialize sids and other state variables. :Arguments: data_frequency : str (daily, hourly or minutely) The duration of the bars. annualizer : int <optional> Which constant to use for annualizing risk metrics. If not provided, will extract from data_frequency. capital_base : float <default: 1.0e5> How much capital to start with. """ self._portfolio = None self.datetime = None self.registered_transforms = {} self.transforms = [] self.sources = [] self._recorded_vars = {} self.logger = None self.benchmark_return_source = None # default components for transact self.slippage = VolumeShareSlippage() self.commission = PerShare() if 'data_frequency' in kwargs: self.set_data_frequency(kwargs.pop('data_frequency')) else: self.data_frequency = None self.instant_fill = kwargs.pop('instant_fill', False) # Override annualizer if set if 'annualizer' in kwargs: self.annualizer = kwargs['annualizer'] # set the capital base self.capital_base = kwargs.pop('capital_base', DEFAULT_CAPITAL_BASE) self.sim_params = kwargs.pop('sim_params', None) if self.sim_params: self.sim_params.data_frequency = self.data_frequency self.blotter = kwargs.pop('blotter', None) if not self.blotter: self.blotter = Blotter() # an algorithm subclass needs to set initialized to True when # it is fully initialized. self.initialized = False # call to user-defined constructor method self.initialize(*args, **kwargs)
def initialize_testing_algo(self, context): set_commission(PerShare()) set_slippage(VolumeShareSlippage()) if self.syms is None: self.syms = self.__validate_symbols__(self.ticker_syms) self.portfolio_memory = PortfolioMemory(len(self.syms), self.config.n_history) schedule_function(self.testing_rebalance, date_rule=date_rules.month_start(), time_rule=time_rules.market_open(minutes=1))
def initialize(self, window_length=60): self.spreads = [] self.invested = 0 self.window_length = window_length self.commission = PerShare(cost=0.0005) self.ols_transform = ols_transform(refresh_period=1, window_length=self.window_length) self.instant_fill = True self.slippage = FixedSlippage(spread=0) self.sscore = [ ] # store those sscores which can be regarded as the hist
def test_per_share_no_minimum(self): model = PerShare(cost=0.0075, min_trade_cost=None) fill_amounts = [230, 170, 100] order, txns = self.generate_order_and_txns(sid=1, order_amount=500, fill_amounts=fill_amounts) expected_commissions = [1.725, 1.275, 0.75] # make sure each commission is pro-rated for fill_amount, expected_commission, txn in zip( fill_amounts, expected_commissions, txns, ): commission = model.calculate(order, txn) self.assertAlmostEqual(expected_commission, commission) order.filled += fill_amount order.commission += commission
def __init__(self, take_market=False): self.transact = transact_partial(VolumeShareSlippage(), PerShare()) # these orders are aggregated by sid self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # holding orders that have come in since the last # event. self.new_orders = [] self.current_dt = None self.max_shares = int(1e+11) self.take_market = take_market
def test_commission_event(self): with trading.TradingEnvironment(): events = factory.create_trade_history( 1, [10, 10, 10, 10, 10], [100, 100, 100, 100, 100], oneday, self.sim_params ) # Test commission models and validate result # Expected commission amounts: # PerShare commission: 1.00, 1.00, 1.50 = $3.50 # PerTrade commission: 5.00, 5.00, 5.00 = $15.00 # PerDollar commission: 1.50, 3.00, 4.50 = $9.00 # Total commission = $3.50 + $15.00 + $9.00 = $27.50 # Create 3 transactions: 50, 100, 150 shares traded @ $20 transactions = [create_txn(events[0], 20, i) for i in [50, 100, 150]] # Create commission models models = [PerShare(cost=0.01, min_trade_cost=1.00), PerTrade(cost=5.00), PerDollar(cost=0.0015)] # Aggregate commission amounts total_commission = 0 for model in models: for trade in transactions: total_commission += model.calculate(trade)[1] self.assertEqual(total_commission, 27.5) cash_adj_dt = self.sim_params.first_open \ + datetime.timedelta(hours=3) cash_adjustment = factory.create_commission(1, 300.0, cash_adj_dt) # Insert a purchase order. events.insert(0, create_txn(events[0], 20, 1)) events.insert(1, cash_adjustment) results = calculate_results(self, events) # Validate that we lost 320 dollars from our cash pool. self.assertEqual(results[-1]['cumulative_perf']['ending_cash'], 9680) # Validate that the cost basis of our position changed. self.assertEqual(results[-1]['daily_perf']['positions'] [0]['cost_basis'], 320.0)
def test_commission_event(self): with trading.TradingEnvironment(): events = factory.create_trade_history(1, [10, 10, 10, 10, 10], [100, 100, 100, 100, 100], oneday, self.sim_params) # Test commission models and validate result # Expected commission amounts: # PerShare commission: 1.00, 1.00, 1.50 = $3.50 # PerTrade commission: 5.00, 5.00, 5.00 = $15.00 # PerDollar commission: 1.50, 3.00, 4.50 = $9.00 # Total commission = $3.50 + $15.00 + $9.00 = $27.50 # Create 3 transactions: 50, 100, 150 shares traded @ $20 transactions = [ create_txn(events[0], 20, i) for i in [50, 100, 150] ] # Create commission models and validate that produce expected # commissions. models = [ PerShare(cost=0.01, min_trade_cost=1.00), PerTrade(cost=5.00), PerDollar(cost=0.0015) ] expected_results = [3.50, 15.0, 9.0] for model, expected in zip(models, expected_results): total_commission = 0 for trade in transactions: total_commission += model.calculate(trade)[1] self.assertEqual(total_commission, expected) # Verify that commission events are handled correctly by # PerformanceTracker. cash_adj_dt = events[0].dt cash_adjustment = factory.create_commission(1, 300.0, cash_adj_dt) events.append(cash_adjustment) # Insert a purchase order. txns = [create_txn(events[0], 20, 1)] results = calculate_results(self, events, txns=txns) # Validate that we lost 320 dollars from our cash pool. self.assertEqual(results[-1]['cumulative_perf']['ending_cash'], 9680) # Validate that the cost basis of our position changed. self.assertEqual( results[-1]['daily_perf']['positions'][0]['cost_basis'], 320.0)
def test_close_position_equity(self): metadata = {1: {'symbol': 'TEST', 'asset_type': 'equity', 'end_date': self.days[3]}} self.algo = TestAlgorithm(sid=1, amount=1, order_count=1, instant_fill=True, commission=PerShare(0), asset_metadata=metadata) self.data = DataPanelSource(self.panel) # Check results expected_positions = [1, 1, 0] expected_pnl = [0, 1, 2] results = self.run_algo() self.check_algo_pnl(results, expected_pnl) self.check_algo_positions(results, expected_positions)
def __init__( self, equity_slippage=None, future_slippage=None, option_slippage=None, equity_commission=None, future_commission=None, option_commission=None, cancel_policy=None, ): super(SimulationBlotter, self).__init__(cancel_policy=cancel_policy) # these orders are aggregated by asset self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # holding orders that have come in since the last event. self.new_orders = [] self.max_shares = int(1e11) self.slippage_models = { Equity: equity_slippage or FixedBasisPointsSlippage(), Future: future_slippage or VolatilityVolumeShare( volume_limit=DEFAULT_FUTURE_VOLUME_SLIPPAGE_BAR_LIMIT), Option: option_slippage or CoverTheSpread(), } self.commission_models = { Equity: equity_commission or PerShare(), Future: future_commission or PerContract( cost=DEFAULT_PER_CONTRACT_COST, exchange_fee=FUTURE_EXCHANGE_FEES_BY_SYMBOL, ), Option: option_commission or PerOptionContract(cost=DEFAULT_PER_OPTION_CONTRACT_COST, exchange_fee=0.01), }
def __init__(self, data_frequency, asset_finder, equity_slippage=None, future_slippage=None, equity_commission=None, future_commission=None, cancel_policy=None): # these orders are aggregated by sid self.open_orders = defaultdict(list) # keep a dict of orders by their own id self.orders = {} # all our legacy order management code works with integer sids. # this lets us convert those to assets when needed. ideally, we'd just # revamp all the legacy code to work with assets. self.asset_finder = asset_finder # holding orders that have come in since the last event. self.new_orders = [] self.current_dt = None self.max_shares = int(1e+11) self.slippage_models = { Equity: equity_slippage or VolumeShareSlippage(), Future: future_slippage or VolumeShareSlippage(), } self.commission_models = { Equity: equity_commission or PerShare(), Future: future_commission or PerTrade(cost=DEFAULT_FUTURE_COST_PER_TRADE, ), } self.data_frequency = data_frequency self.cancel_policy = cancel_policy if cancel_policy else NeverCancel()
def __init__(self, *args, **kwargs): """Initialize sids and other state variables. :Arguments: :Optional: initialize : function Function that is called with a single argument at the begninning of the simulation. handle_data : function Function that is called with 2 arguments (context and data) on every bar. script : str Algoscript that contains initialize and handle_data function definition. data_frequency : str (daily, hourly or minutely) The duration of the bars. capital_base : float <default: 1.0e5> How much capital to start with. instant_fill : bool <default: False> Whether to fill orders immediately or on next bar. environment : str <default: 'zipline'> The environment that this algorithm is running in. """ self.datetime = None self.sources = [] # List of trading controls to be used to validate orders. self.trading_controls = [] # List of account controls to be checked on each bar. self.account_controls = [] self._recorded_vars = {} self.namespace = kwargs.get('namespace', {}) self._platform = kwargs.pop('platform', 'zipline') self.logger = None self.benchmark_return_source = None # default components for transact self.slippage = VolumeShareSlippage() self.commission = PerShare() self.instant_fill = kwargs.pop('instant_fill', False) # set the capital base self.capital_base = kwargs.pop('capital_base', DEFAULT_CAPITAL_BASE) self.sim_params = kwargs.pop('sim_params', None) if self.sim_params is None: self.sim_params = create_simulation_parameters( capital_base=self.capital_base ) self.perf_tracker = PerformanceTracker(self.sim_params) self.blotter = kwargs.pop('blotter', None) if not self.blotter: self.blotter = Blotter() self.portfolio_needs_update = True self.account_needs_update = True self.performance_needs_update = True self._portfolio = None self._account = None self.history_container_class = kwargs.pop( 'history_container_class', HistoryContainer, ) self.history_container = None self.history_specs = {} # If string is passed in, execute and get reference to # functions. self.algoscript = kwargs.pop('script', None) self._initialize = None self._before_trading_start = None self._analyze = None self.event_manager = EventManager() if self.algoscript is not None: filename = kwargs.pop('algo_filename', None) if filename is None: filename = '<string>' code = compile(self.algoscript, filename, 'exec') exec_(code, self.namespace) self._initialize = self.namespace.get('initialize') if 'handle_data' not in self.namespace: raise ValueError('You must define a handle_data function.') else: self._handle_data = self.namespace['handle_data'] self._before_trading_start = \ self.namespace.get('before_trading_start') # Optional analyze function, gets called after run self._analyze = self.namespace.get('analyze') elif kwargs.get('initialize') and kwargs.get('handle_data'): if self.algoscript is not None: raise ValueError('You can not set script and \ initialize/handle_data.') self._initialize = kwargs.pop('initialize') self._handle_data = kwargs.pop('handle_data') self._before_trading_start = kwargs.pop('before_trading_start', None) self.event_manager.add_event( zipline.utils.events.Event( zipline.utils.events.Always(), # We pass handle_data.__func__ to get the unbound method. # We will explicitly pass the algorithm to bind it again. self.handle_data.__func__, ), prepend=True, ) # If method not defined, NOOP if self._initialize is None: self._initialize = lambda x: None # Alternative way of setting data_frequency for backwards # compatibility. if 'data_frequency' in kwargs: self.data_frequency = kwargs.pop('data_frequency') self._most_recent_data = None # Subclasses that override initialize should only worry about # setting self.initialized = True if AUTO_INITIALIZE is # is manually set to False. self.initialized = False self.initialize(*args, **kwargs) if self.AUTO_INITIALIZE: self.initialized = True
def __init__(self, *args, **kwargs): """Initialize sids and other state variables. :Arguments: :Optional: initialize : function Function that is called with a single argument at the begninning of the simulation. handle_data : function Function that is called with 2 arguments (context and data) on every bar. script : str Algoscript that contains initialize and handle_data function definition. data_frequency : str (daily, hourly or minutely) The duration of the bars. capital_base : float <default: 1.0e5> How much capital to start with. instant_fill : bool <default: False> Whether to fill orders immediately or on next bar. """ self.datetime = None self.registered_transforms = {} self.transforms = [] self.sources = [] # List of trading controls to be used to validate orders. self.trading_controls = [] self._recorded_vars = {} self.namespace = kwargs.get('namespace', {}) self.logger = None self.benchmark_return_source = None # default components for transact self.slippage = VolumeShareSlippage() self.commission = PerShare() self.instant_fill = kwargs.pop('instant_fill', False) # set the capital base self.capital_base = kwargs.pop('capital_base', DEFAULT_CAPITAL_BASE) self.sim_params = kwargs.pop('sim_params', None) if self.sim_params is None: self.sim_params = create_simulation_parameters( capital_base=self.capital_base ) self.perf_tracker = PerformanceTracker(self.sim_params) self.blotter = kwargs.pop('blotter', None) if not self.blotter: self.blotter = Blotter() self.portfolio_needs_update = True self._portfolio = None self.history_container = None self.history_specs = {} # If string is passed in, execute and get reference to # functions. self.algoscript = kwargs.pop('script', None) self._initialize = None self._analyze = None if self.algoscript is not None: exec_(self.algoscript, self.namespace) self._initialize = self.namespace.get('initialize', None) if 'handle_data' not in self.namespace: raise ValueError('You must define a handle_data function.') else: self._handle_data = self.namespace['handle_data'] # Optional analyze function, gets called after run self._analyze = self.namespace.get('analyze', None) elif kwargs.get('initialize', False) and kwargs.get('handle_data'): if self.algoscript is not None: raise ValueError('You can not set script and \ initialize/handle_data.') self._initialize = kwargs.pop('initialize') self._handle_data = kwargs.pop('handle_data') # If method not defined, NOOP if self._initialize is None: self._initialize = lambda x: None # Alternative way of setting data_frequency for backwards # compatibility. if 'data_frequency' in kwargs: self.data_frequency = kwargs.pop('data_frequency') # Subclasses that override initialize should only worry about # setting self.initialized = True if AUTO_INITIALIZE is # is manually set to False. self.initialized = False self.initialize(*args, **kwargs) if self.AUTO_INITIALIZE: self.initialized = True
def __init__(self, *args, **kwargs): """Initialize sids and other state variables. :Arguments: :Optional: initialize : function Function that is called with a single argument at the begninning of the simulation. handle_data : function Function that is called with 2 arguments (context and data) on every bar. script : str Algoscript that contains initialize and handle_data function definition. data_frequency : {'daily', 'minute'} The duration of the bars. capital_base : float <default: 1.0e5> How much capital to start with. instant_fill : bool <default: False> Whether to fill orders immediately or on next bar. asset_finder : An AssetFinder object A new AssetFinder object to be used in this TradingEnvironment asset_metadata: can be either: - dict - pandas.DataFrame - object with 'read' property If dict is provided, it must have the following structure: * keys are the identifiers * values are dicts containing the metadata, with the metadata field name as the key If pandas.DataFrame is provided, it must have the following structure: * column names must be the metadata fields * index must be the different asset identifiers * array contents should be the metadata value If an object with a 'read' property is provided, 'read' must return rows containing at least one of 'sid' or 'symbol' along with the other metadata fields. identifiers : List Any asset identifiers that are not provided in the asset_metadata, but will be traded by this TradingAlgorithm """ self.sources = [] # List of trading controls to be used to validate orders. self.trading_controls = [] # List of account controls to be checked on each bar. self.account_controls = [] self._recorded_vars = {} self.namespace = kwargs.get('namespace', {}) self._platform = kwargs.pop('platform', 'zipline') self.logger = None self.benchmark_return_source = None # default components for transact self.slippage = VolumeShareSlippage() self.commission = PerShare() self.instant_fill = kwargs.pop('instant_fill', False) # set the capital base self.capital_base = kwargs.pop('capital_base', DEFAULT_CAPITAL_BASE) self.sim_params = kwargs.pop('sim_params', None) if self.sim_params is None: self.sim_params = create_simulation_parameters( capital_base=self.capital_base, start=kwargs.pop('start', None), end=kwargs.pop('end', None)) self.perf_tracker = PerformanceTracker(self.sim_params) # Update the TradingEnvironment with the provided asset metadata self.trading_environment = kwargs.pop('env', TradingEnvironment.instance()) self.trading_environment.update_asset_finder( asset_finder=kwargs.pop('asset_finder', None), asset_metadata=kwargs.pop('asset_metadata', None), identifiers=kwargs.pop('identifiers', None)) # Pull in the environment's new AssetFinder for quick reference self.asset_finder = self.trading_environment.asset_finder self.init_engine(kwargs.pop('ffc_loader', None)) # Maps from name to Term self._filters = {} self._factors = {} self._classifiers = {} self.blotter = kwargs.pop('blotter', None) if not self.blotter: self.blotter = Blotter() # Set the dt initally to the period start by forcing it to change self.on_dt_changed(self.sim_params.period_start) self.portfolio_needs_update = True self.account_needs_update = True self.performance_needs_update = True self._portfolio = None self._account = None self.history_container_class = kwargs.pop( 'history_container_class', HistoryContainer, ) self.history_container = None self.history_specs = {} # If string is passed in, execute and get reference to # functions. self.algoscript = kwargs.pop('script', None) self._initialize = None self._before_trading_start = None self._analyze = None self.event_manager = EventManager() if self.algoscript is not None: filename = kwargs.pop('algo_filename', None) if filename is None: filename = '<string>' code = compile(self.algoscript, filename, 'exec') exec_(code, self.namespace) self._initialize = self.namespace.get('initialize') if 'handle_data' not in self.namespace: raise ValueError('You must define a handle_data function.') else: self._handle_data = self.namespace['handle_data'] self._before_trading_start = \ self.namespace.get('before_trading_start') # Optional analyze function, gets called after run self._analyze = self.namespace.get('analyze') elif kwargs.get('initialize') and kwargs.get('handle_data'): if self.algoscript is not None: raise ValueError('You can not set script and \ initialize/handle_data.') self._initialize = kwargs.pop('initialize') self._handle_data = kwargs.pop('handle_data') self._before_trading_start = kwargs.pop('before_trading_start', None) self.event_manager.add_event( zipline.utils.events.Event( zipline.utils.events.Always(), # We pass handle_data.__func__ to get the unbound method. # We will explicitly pass the algorithm to bind it again. self.handle_data.__func__, ), prepend=True, ) # If method not defined, NOOP if self._initialize is None: self._initialize = lambda x: None # Alternative way of setting data_frequency for backwards # compatibility. if 'data_frequency' in kwargs: self.data_frequency = kwargs.pop('data_frequency') self._most_recent_data = None # Prepare the algo for initialization self.initialized = False self.initialize_args = args self.initialize_kwargs = kwargs
def __init__(self, *args, **kwargs): """Initialize sids and other state variables. :Arguments: :Optional: initialize : function Function that is called with a single argument at the begninning of the simulation. handle_data : function Function that is called with 2 arguments (context and data) on every bar. script : str Algoscript that contains initialize and handle_data function definition. data_frequency : str (daily, hourly or minutely) The duration of the bars. annualizer : int <optional> Which constant to use for annualizing risk metrics. If not provided, will extract from data_frequency. capital_base : float <default: 1.0e5> How much capital to start with. instant_fill : bool <default: False> Whether to fill orders immediately or on next bar. """ self.datetime = None self.registered_transforms = {} self.transforms = [] self.sources = [] self._recorded_vars = {} self.logger = None self.benchmark_return_source = None self.perf_tracker = None # default components for transact self.slippage = VolumeShareSlippage() self.commission = PerShare() if 'data_frequency' in kwargs: self.set_data_frequency(kwargs.pop('data_frequency')) else: self.data_frequency = None self.instant_fill = kwargs.pop('instant_fill', False) # Override annualizer if set if 'annualizer' in kwargs: self.annualizer = kwargs['annualizer'] # set the capital base self.capital_base = kwargs.pop('capital_base', DEFAULT_CAPITAL_BASE) self.sim_params = kwargs.pop('sim_params', None) if self.sim_params: if self.data_frequency is None: self.data_frequency = self.sim_params.data_frequency else: self.sim_params.data_frequency = self.data_frequency self.perf_tracker = PerformanceTracker(self.sim_params) self.blotter = kwargs.pop('blotter', None) if not self.blotter: self.blotter = Blotter() self.portfolio_needs_update = True self._portfolio = None # If string is passed in, execute and get reference to # functions. self.algoscript = kwargs.pop('script', None) self._initialize = None if self.algoscript is not None: self.ns = {} exec_(self.algoscript, self.ns) if 'initialize' not in self.ns: raise ValueError('You must define an initialze function.') if 'handle_data' not in self.ns: raise ValueError('You must define a handle_data function.') self._initialize = self.ns['initialize'] self._handle_data = self.ns['handle_data'] # If two functions are passed in assume initialize and # handle_data are passed in. elif kwargs.get('initialize', False) and kwargs.get('handle_data'): if self.algoscript is not None: raise ValueError('You can not set script and \ initialize/handle_data.') self._initialize = kwargs.pop('initialize') self._handle_data = kwargs.pop('handle_data') if self._initialize is None: self._initialize = lambda x: None # an algorithm subclass needs to set initialized to True when # it is fully initialized. self.initialized = False self.initialize(*args, **kwargs)
def __init__(self): self.transact = transact_partial(VolumeShareSlippage(), PerShare()) self.open_orders = defaultdict(list)