DOC: update docs for api functions

This commit is contained in:
Joe Jevnik
2016-05-05 14:16:30 -04:00
parent 0562179060
commit d888c4faaa
9 changed files with 798 additions and 139 deletions
+134 -2
View File
@@ -15,10 +15,142 @@ The following methods are available for use in the ``initialize``,
In all listed functions, the ``self`` argument is implicitly the
currently-executing :class:`~zipline.algorithm.TradingAlgorithm` instance.
.. automodule:: zipline.api
Scheduling Functions
````````````````````
.. autofunction:: zipline.api.schedule_function
.. autoclass:: zipline.api.date_rules
:members:
:undoc-members:
.. autoclass:: zipline.api.time_rules
:members:
.. autoclass:: zipline.algorithm.TradingAlgorithm
Orders
``````
.. autofunction:: zipline.api.order
.. autofunction:: zipline.api.order_value
.. autofunction:: zipline.api.order_percent
.. autofunction:: zipline.api.order_target
.. autofunction:: zipline.api.order_target_value
.. autofunction:: zipline.api.order_target_percent
.. autoclass:: zipline.finance.execution.ExecutionStyle
:members:
.. autoclass:: zipline.finance.execution.MarketOrder
.. autoclass:: zipline.finance.execution.LimitOrder
.. autoclass:: zipline.finance.execution.StopOrder
.. autoclass:: zipline.finance.execution.StopLimitOrder
.. autofunction:: zipline.api.get_order
.. autofunction:: zipline.api.get_open_orders
.. autofunction:: zipline.api.cancel_order
Order Cancellation Policies
'''''''''''''''''''''''''''
.. autofunction:: zipline.api.set_cancel_policy
.. autoclass:: zipline.finance.cancel_policy.CancelPolicy
:members:
.. autofunction:: zipline.api.EODCancel
.. autofunction:: zipline.api.NeverCancel
Assets
``````
.. autofunction:: zipline.api.symbol
.. autofunction:: zipline.api.symbols
.. autofunction:: zipline.api.future_symbol
.. autofunction:: zipline.api.future_chain
.. autofunction:: zipline.api.set_symbol_lookup_date
.. autofunction:: zipline.api.sid
Trading Controls
````````````````
Zipline provides trading controls to help ensure that the algorithm is
performing as expected. The functions help protect the algorithm from certian
bugs that could cause undesirable behavior when trading with real money.
.. autofunction:: zipline.api.set_do_not_order_list
.. autofunction:: zipline.api.set_long_only
.. autofunction:: zipline.api.set_max_leverage
.. autofunction:: zipline.api.set_max_order_count
.. autofunction:: zipline.api.set_max_order_size
.. autofunction:: zipline.api.set_max_position_size
Simulation Parameters
`````````````````````
.. autofunction:: zipline.api.set_commission
.. autoclass:: zipline.finance.commission.PerShare
.. autoclass:: zipline.finance.commission.PerTrade
.. autoclass:: zipline.finance.commission.PerDollar
.. autofunction:: zipline.api.set_slippage
.. autoclass:: zipline.finance.slippage.SlippageModel
:members:
.. autoclass:: zipline.finance.slippage.FixedSlippage
.. autoclass:: zipline.finance.slippage.VolumeShareSlippage
.. autofunction:: zipline.api.set_benchmark
Pipeline
````````
For more information, see :ref:`pipeline-api`
.. autofunction:: zipline.api.attach_pipeline
.. autofunction:: zipline.api.pipeline_output
Miscellaneous
`````````````
.. autofunction:: zipline.api.record
.. autofunction:: zipline.api.get_environment
.. autofunction:: zipline.api.fetch_csv
.. _pipeline-api:
Pipeline API
~~~~~~~~~~~~
+1 -3
View File
@@ -161,7 +161,7 @@ from zipline.utils.api_support import ZiplineAPI, set_algo_instance
from zipline.utils.context_tricks import CallbackManager
from zipline.utils.control_flow import nullctx
import zipline.utils.events
from zipline.utils.events import DateRuleFactory, TimeRuleFactory, Always
from zipline.utils.events import date_rules, time_rules, Always
import zipline.utils.factory as factory
from zipline.utils.tradingcalendar import trading_day, trading_days
@@ -389,8 +389,6 @@ def handle_data(context, data):
algo.run(self.data_portal)
def test_schedule_function(self):
date_rules = DateRuleFactory
time_rules = TimeRuleFactory
us_eastern = pytz.timezone('US/Eastern')
def incrementer(algo, data):
+564 -84
View File
@@ -96,8 +96,8 @@ import zipline.utils.events
from zipline.utils.events import (
EventManager,
make_eventrule,
DateRuleFactory,
TimeRuleFactory,
date_rules,
time_rules,
)
from zipline.utils.factory import create_simulation_parameters
from zipline.utils.math_utils import (
@@ -764,6 +764,41 @@ class TradingAlgorithm(object):
@api_method
def get_environment(self, field='platform'):
"""Query the execution environment.
Parameters
----------
field : {'platform', 'arena', 'data_frequency',
'start', 'end', 'capital_base', 'platform', '*'}
The field to query. The options have the following meanings:
arena : str
The arena from the simulation parameters. This will normally
be ``'backtest'`` but some systems may use this distinguish
live trading from backtesting.
data_frequency : {'daily', 'minute'}
data_frequency tells the algorithm if it is running with
daily data or minute data.
start : datetime
The start date for the simulation.
end : datetime
The end date for the simulation.
capital_base : float
The starting capital for the simulation.
platform : str
The platform that the code is running on. By default this
will be the string 'zipline'. This can allow algorithms to
know if they are running on the Quantopian platform instead.
Returns
-------
val : any
The value for the field queried. See above for more information.
Raises
------
KeyError
Raised when ``field`` is not a valid option.
"""
env = {
'arena': self.sim_params.arena,
'data_frequency': self.sim_params.data_frequency,
@@ -778,7 +813,8 @@ class TradingAlgorithm(object):
return env[field]
@api_method
def fetch_csv(self, url,
def fetch_csv(self,
url,
pre_func=None,
post_func=None,
date_column='date',
@@ -789,6 +825,47 @@ class TradingAlgorithm(object):
symbol_column=None,
special_params_checker=None,
**kwargs):
"""Fetch a csv from a remote url.
Parameters
----------
url : str
The url of the csv file to load.
pre_func : callable[pd.DataFrame -> pd.DataFrame], optional
A callback to allow preprocessing the raw data returned from
fetch_csv before dates are paresed or symbols are mapped.
post_func : callable[pd.DataFrame -> pd.DataFrame], optional
A callback to allow postprocessing of the data after dates and
symbols have been mapped.
date_column : str, optional
The name of the column in the preprocessed dataframe containing
datetime information to map the data.
date_format : str, optional
The format of the dates in the ``date_column``. If not provided
``fetch_csv`` will attempt to infer the format. For information
about the format of this string, see :func:`pandas.read_csv`.
timezone : tzinfo or str, optional
The timezone for the datetime in the ``date_column``.
symbol : str, optional
If the data is about a new asset or index then this string will
be the name used to identify the values in ``data``. For example,
one may use ``fetch_csv`` to load data for VIX, then this field
could be the string ``'VIX'``.
mask : bool, optional
Drop any rows which cannot be symbol mapped.
symbol_column : str
If the data is attaching some new attribute to each asset then this
argument is the name of the column in the preprocessed dataframe
containing the symbols. This will be used along with the date
information to map the sids in the asset finder.
**kwargs
Forwarded to :func:`pandas.read_csv`.
Returns
-------
csv_data_source : zipline.sources.requests_csv.PandasRequestsCSV
A requests source that will pull data from the url specified.
"""
# Show all the logs every time fetcher is used.
csv_data_source = PandasRequestsCSV(
@@ -816,8 +893,14 @@ class TradingAlgorithm(object):
return csv_data_source
def add_event(self, rule=None, callback=None):
"""
Adds an event to the algorithm's EventManager.
"""Adds an event to the algorithm's EventManager.
Parameters
----------
rule : EventRule
The rule for when the callback should be triggered.
callback : callable[(context, data) -> None]
The function to execute when the rule is triggered.
"""
self.event_manager.add_event(
zipline.utils.events.Event(rule, callback),
@@ -829,11 +912,26 @@ class TradingAlgorithm(object):
date_rule=None,
time_rule=None,
half_days=True):
"""Schedules a function to be called with some timed rules.
Parameters
----------
func : callable[(context, data) -> None]
The function to execute when the rule is triggered.
date_rule : EventRule, optional
The rule for the dates to execute this function.
time_rule : EventRule, optional
The rule for the times to execute this function.
half_days : bool, optional
Should this rule fire on half days?
See Also
--------
:class:`zipline.api.date_rules`
:class:`zipline.api.time_rules`
"""
Schedules a function to be called with some timed rules.
"""
date_rule = date_rule or DateRuleFactory.every_day()
time_rule = ((time_rule or TimeRuleFactory.market_open())
date_rule = date_rule or date_rules.every_day()
time_rule = ((time_rule or time_rules.market_open())
if self.sim_params.data_frequency == 'minute' else
# If we are in daily mode the time_rule is ignored.
zipline.utils.events.Always())
@@ -845,8 +943,18 @@ class TradingAlgorithm(object):
@api_method
def record(self, *args, **kwargs):
"""
Track and record local variable (i.e. attributes) each day.
"""Track and record values each day.
Parameters
----------
**kwargs
The names and values to record.
Notes
-----
These values will appear in the performance packets and the performance
dataframe passed to ``analyze`` and returned from
:func:`~zipline.run_algorithm`.
"""
# Make 2 objects both referencing the same iterator
args = [iter(args)] * 2
@@ -860,18 +968,48 @@ class TradingAlgorithm(object):
self._recorded_vars[name] = value
@api_method
def set_benchmark(self, benchmark_sid):
def set_benchmark(self, benchmark):
"""Set the benchmark asset.
Parameters
----------
benchmark : Asset
The asset to set as the new benchmark.
Notes
-----
Any dividends payed out for that new benchmark asset will be
automatically reinvested.
"""
if self.initialized:
raise SetBenchmarkOutsideInitialize()
self.benchmark_sid = benchmark_sid
self.benchmark_sid = benchmark
@api_method
@preprocess(symbol_str=ensure_upper_case)
def symbol(self, symbol_str):
"""
Default symbol lookup for any source that directly maps the
symbol to the Asset (e.g. yahoo finance).
"""Lookup an Equity by its ticker symbol.
Parameters
----------
symbol_str : str
The ticker symbol for the equity to lookup.
Returns
-------
equity : Equity
The equity that held the ticker symbol on the current
symbol lookup date.
Raises
------
SymbolNotFound
Raised when the symbols was not held on the current lookup date.
See Also
--------
:func:`zipline.api.set_symbol_lookup_date`
"""
# If the user has not set the symbol lookup date,
# use the period_end as the date for sybmol->sid resolution.
@@ -885,19 +1023,51 @@ class TradingAlgorithm(object):
@api_method
def symbols(self, *args):
"""
Default symbols lookup for any source that directly maps the
symbol to the Asset (e.g. yahoo finance).
"""Lookup multuple Equities as a list.
Parameters
----------
*args : iterable[str]
The ticker symbols to lookup.
Returns
-------
equities : list[Equity]
The equities that held the given ticker symbols on the current
symbol lookup date.
Raises
------
SymbolNotFound
Raised when one of the symbols was not held on the current
lookup date.
See Also
--------
:func:`zipline.api.set_symbol_lookup_date`
"""
return [self.symbol(identifier) for identifier in args]
@api_method
def sid(self, a_sid):
def sid(self, sid):
"""Lookup an Asset by its unique asset identifier.
Parameters
----------
sid : int
The unique integer that identifies an asset.
Returns
-------
asset : Asset
The asset with the given ``sid``.
Raises
------
SidsNotFound
When a requested sid is not found and default_none=False.
"""
Default sid lookup for any source that directly maps the integer sid
to the Asset.
"""
return self.asset_finder.retrieve_asset(a_sid)
return self.asset_finder.retrieve_asset(sid)
@api_method
@preprocess(symbol=ensure_upper_case)
@@ -911,21 +1081,20 @@ class TradingAlgorithm(object):
Returns
-------
Future
A Future object.
future : Future
The future that trades with the name ``symbol``.
Raises
------
SymbolNotFound
Raised when no contract named 'symbol' is found.
"""
return self.asset_finder.lookup_future_symbol(symbol)
@api_method
@preprocess(root_symbol=ensure_upper_case)
def future_chain(self, root_symbol, as_of_date=None):
""" Look up a future chain with the specified parameters.
"""Look up a future chain with the specified parameters.
Parameters
----------
@@ -938,7 +1107,7 @@ class TradingAlgorithm(object):
Returns
-------
FutureChain
chain : FutureChain
The future chain matching the specified parameters.
Raises
@@ -1031,12 +1200,34 @@ class TradingAlgorithm(object):
@api_method
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order(self, asset, amount,
def order(self,
asset,
amount,
limit_price=None,
stop_price=None,
style=None):
"""
Place an order using the specified parameters.
"""Place an order.
Parameters
----------
asset : Asset
The asset that this order is for.
amount : int
The amount of shares to order. If this is negative, this is the
number of shares to sell or short.
style : ExecutionStyle, optional
The execution style for the order.
Returns
-------
order_id : str
The unique identifier for this order.
See Also
--------
:class:`zipline.finance.execution.ExecutionStyle`
:func:`zipline.api.order_value`
:func:`zipline.api.order_percent`
"""
if not self._can_order_asset(asset):
return None
@@ -1119,21 +1310,40 @@ class TradingAlgorithm(object):
@api_method
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order_value(self, asset, value,
limit_price=None, stop_price=None, style=None):
"""
Place an order by desired value rather than desired number of shares.
If the requested asset exists, the requested value is
divided by its price to imply the number of shares to transact.
If the Asset being ordered is a Future, the 'value' calculated
is actually the exposure, as Futures have no 'value'.
def order_value(self,
asset,
value,
limit_price=None,
stop_price=None,
style=None):
"""Place an order by desired value rather than desired number of
shares.
value > 0 :: Buy/Cover
value < 0 :: Sell/Short
Market order: order(sid, value)
Limit order: order(sid, value, limit_price)
Stop order: order(sid, value, None, stop_price)
StopLimit order: order(sid, value, limit_price, stop_price)
Parameters
----------
asset : Asset
The asset that this order is for.
value : float
If the requested asset exists, the requested value is
divided by its price to imply the number of shares to transact.
If the Asset being ordered is a Future, the 'value' calculated
is actually the exposure, as Futures have no 'value'.
value > 0 :: Buy/Cover
value < 0 :: Sell/Short
style : ExecutionStyle
The execution style for the order.
Returns
-------
order_id : str
The unique identifier for this order.
See Also
--------
:class:`zipline.finance.execution.ExecutionStyle`
:func:`zipline.api.order`
:func:`zipline.api.order_percent`
"""
if not self._can_order_asset(asset):
return None
@@ -1197,8 +1407,17 @@ class TradingAlgorithm(object):
@api_method
def get_datetime(self, tz=None):
"""
Returns the simulation datetime.
"""Returns the current simulation datetime.
Parameters
----------
tz : tzinfo or str, optional
The timezone to return the datetime in. This defaults to utc.
Returns
-------
dt : datetime
The current simulation datetime converted to ``tz``.
"""
dt = self.datetime
assert dt.tzinfo == pytz.utc, "Algorithm should have a utc datetime"
@@ -1220,6 +1439,17 @@ class TradingAlgorithm(object):
@api_method
def set_slippage(self, slippage):
"""Set the slippage model for the simulation.
Parameters
----------
slippage : SlippageModel
The slippage model to use.
See Also
--------
:class:`zipline.finance.slippage.SlippageModel`
"""
if not isinstance(slippage, SlippageModel):
raise UnsupportedSlippageModel()
if self.initialized:
@@ -1228,6 +1458,19 @@ class TradingAlgorithm(object):
@api_method
def set_commission(self, commission):
"""Sets the commision model for the simulation.
Parameters
----------
commision : PerShare, PerTrade, or PerDollar
The commision model to use.
See Also
--------
:class:`zipline.finance.commission.PerShare`
:class:`zipline.finance.commission.PerTrade`
:class:`zipline.finance.commission.PerDollar`
"""
if not isinstance(commission, (PerShare, PerTrade, PerDollar)):
raise UnsupportedCommissionModel()
@@ -1237,6 +1480,18 @@ class TradingAlgorithm(object):
@api_method
def set_cancel_policy(self, cancel_policy):
"""Sets the order cancellation policy for the simulation.
Parameters
----------
cancel_policy : CancelPolicy
The cancellation policy to use.
See Also
--------
:class:`zipline.api.EODCancel`
:class:`zipline.api.NeverCancel`
"""
if not isinstance(cancel_policy, CancelPolicy):
raise UnsupportedCancelPolicy()
@@ -1247,10 +1502,14 @@ class TradingAlgorithm(object):
@api_method
def set_symbol_lookup_date(self, dt):
"""
Set the date for which symbols will be resolved to their assets
"""Set the date for which symbols will be resolved to their assets
(symbols may map to different firms or underlying assets at
different times)
Parameters
----------
dt : datetime
The new symbol lookup date.
"""
try:
self._symbol_lookup_date = pd.Timestamp(dt, tz='UTC')
@@ -1270,13 +1529,35 @@ class TradingAlgorithm(object):
@api_method
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order_percent(self, asset, percent,
limit_price=None, stop_price=None, style=None):
"""
Place an order in the specified asset corresponding to the given
def order_percent(self,
asset,
percent,
limit_price=None,
stop_price=None,
style=None):
"""Place an order in the specified asset corresponding to the given
percent of the current portfolio value.
Note that percent must expressed as a decimal (0.50 means 50\%).
Parameters
----------
asset : Asset
The asset that this order is for.
percent : float
The percentage of the porfolio value to allocate to ``asset``.
This is specified as a decimal, for example: 0.50 means 50%.
style : ExecutionStyle
The execution style for the order.
Returns
-------
order_id : str
The unique identifier for this order.
See Also
--------
:class:`zipline.finance.execution.ExecutionStyle`
:func:`zipline.api.order`
:func:`zipline.api.order_value`
"""
if not self._can_order_asset(asset):
return None
@@ -1289,14 +1570,53 @@ class TradingAlgorithm(object):
@api_method
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order_target(self, asset, target,
limit_price=None, stop_price=None, style=None):
"""
Place an order to adjust a position to a target number of shares. If
def order_target(self,
asset,
target,
limit_price=None,
stop_price=None,
style=None):
"""Place an order to adjust a position to a target number of shares. If
the position doesn't already exist, this is equivalent to placing a new
order. If the position does exist, this is equivalent to placing an
order for the difference between the target number of shares and the
current number of shares.
Parameters
----------
asset : Asset
The asset that this order is for.
target : int
The desired number of shares of ``asset``.
style : ExecutionStyle
The execution style for the order.
Returns
-------
order_id : str
The unique identifier for this order.
Notes
-----
``order_target`` does not take into account any open orders. For
example:
.. code-block:: python
order_target(sid(0), 10)
order_target(sid(0), 10)
This code will result in 20 shares of ``sid(0)`` because the first
call to ``order_target`` will not have been filled when the second
``order_target`` call is made.
See Also
--------
:class:`zipline.finance.execution.ExecutionStyle`
:func:`zipline.api.order`
:func:`zipline.api.order_target_percent`
:func:`zipline.api.order_target_value`
"""
if not self._can_order_asset(asset):
return None
@@ -1316,16 +1636,54 @@ class TradingAlgorithm(object):
@api_method
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order_target_value(self, asset, target,
limit_price=None, stop_price=None, style=None):
"""
Place an order to adjust a position to a target value. If
def order_target_value(self,
asset,
target,
limit_price=None,
stop_price=None,
style=None):
"""Place an order to adjust a position to a target value. If
the position doesn't already exist, this is equivalent to placing a new
order. If the position does exist, this is equivalent to placing an
order for the difference between the target value and the
current value.
If the Asset being ordered is a Future, the 'target value' calculated
is actually the target exposure, as Futures have no 'value'.
Parameters
----------
asset : Asset
The asset that this order is for.
target : float
The desired total value of ``asset``.
style : ExecutionStyle
The execution style for the order.
Returns
-------
order_id : str
The unique identifier for this order.
Notes
-----
``order_target_value`` does not take into account any open orders. For
example:
.. code-block:: python
order_target_value(sid(0), 10)
order_target_value(sid(0), 10)
This code will result in 20 dollars of ``sid(0)`` because the first
call to ``order_target_value`` will not have been filled when the
second ``order_target_value`` call is made.
See Also
--------
:class:`zipline.finance.execution.ExecutionStyle`
:func:`zipline.api.order`
:func:`zipline.api.order_target`
:func:`zipline.api.order_target_percent`
"""
if not self._can_order_asset(asset):
return None
@@ -1340,14 +1698,48 @@ class TradingAlgorithm(object):
@disallowed_in_before_trading_start(OrderInBeforeTradingStart())
def order_target_percent(self, asset, target,
limit_price=None, stop_price=None, style=None):
"""
Place an order to adjust a position to a target percent of the
"""Place an order to adjust a position to a target percent of the
current portfolio value. If the position doesn't already exist, this is
equivalent to placing a new order. If the position does exist, this is
equivalent to placing an order for the difference between the target
percent and the current percent.
Note that target must expressed as a decimal (0.50 means 50\%).
Parameters
----------
asset : Asset
The asset that this order is for.
percent : float
The desired percentage of the porfolio value to allocate to
``asset``. This is specified as a decimal, for example:
0.50 means 50%.
style : ExecutionStyle
The execution style for the order.
Returns
-------
order_id : str
The unique identifier for this order.
Notes
-----
``order_target_value`` does not take into account any open orders. For
example:
.. code-block:: python
order_target_percent(sid(0), 10)
order_target_percent(sid(0), 10)
This code will result in 20% of the portfolio being allocated to sid(0)
because the first call to ``order_target_percent`` will not have been
filled when the second ``order_target_percent`` call is made.
See Also
--------
:class:`zipline.finance.execution.ExecutionStyle`
:func:`zipline.api.order`
:func:`zipline.api.order_target`
:func:`zipline.api.order_target_value`
"""
if not self._can_order_asset(asset):
return None
@@ -1362,6 +1754,19 @@ class TradingAlgorithm(object):
'get_open_orders. Use `asset` instead.')
@api_method
def get_open_orders(self, asset=None):
"""Retrieve all of the current open orders.
Parameters
----------
asset : Asset
If passed, return only the open orders for the given asset instead
of all open orders.
Returns
-------
open_orders : list[Order]
The open orders.
"""
if asset is None:
return {
key: [order.to_api_obj() for order in orders]
@@ -1375,11 +1780,31 @@ class TradingAlgorithm(object):
@api_method
def get_order(self, order_id):
"""Lookup an order based on the order id returned from one of the
order functions.
Parameters
----------
order_id : str
The unique identifier for the order.
Returns
-------
order : Order
The order object.
"""
if order_id in self.blotter.orders:
return self.blotter.orders[order_id].to_api_obj()
@api_method
def cancel_order(self, order_param):
"""Cancel an open order.
Parameters
----------
order_param : str or Order
The order_id or order object to cancel.
"""
order_id = order_param
if isinstance(order_param, zipline.protocol.Order):
order_id = order_param.id
@@ -1389,6 +1814,8 @@ class TradingAlgorithm(object):
@api_method
@require_initialized(HistoryInInitialize())
def history(self, bar_count, frequency, field, ffill=True):
"""DEPRECATED: use ``data.history`` instead.
"""
warnings.warn(
"The `history` method is deprecated. Use `data.history` instead.",
category=ZiplineDeprecationWarning,
@@ -1461,8 +1888,13 @@ class TradingAlgorithm(object):
@api_method
def set_max_leverage(self, max_leverage=None):
"""
Set a limit on the maximum leverage of the algorithm.
"""Set a limit on the maximum leverage of the algorithm.
Parameters
----------
max_leverage : float, optional
The maximum leverage for the algorithm. If not provided there will
be no maximum.
"""
control = MaxLeverage(max_leverage)
self.register_account_control(control)
@@ -1484,8 +1916,7 @@ class TradingAlgorithm(object):
asset=None,
max_shares=None,
max_notional=None):
"""
Set a limit on the number of shares and/or dollar value held for the
"""Set a limit on the number of shares and/or dollar value held for the
given sid. Limits are treated as absolute values and are enforced at
the time that the algo attempts to place an order for sid. This means
that it's possible to end up with more than the max number of shares
@@ -1495,6 +1926,16 @@ class TradingAlgorithm(object):
If an algorithm attempts to place an order that would result in
increasing the absolute value of shares/dollar value exceeding one of
these limits, raise a TradingControlException.
Parameters
----------
asset : Asset, optional
If provided, this sets the guard only on positions in the given
asset.
max_shares : int, optional
The maximum number of shares to hold for an asset.
max_notional : float, optional
The maximum value to hold for an asset.
"""
control = MaxPositionSize(asset=asset,
max_shares=max_shares,
@@ -1502,15 +1943,26 @@ class TradingAlgorithm(object):
self.register_trading_control(control)
@api_method
def set_max_order_size(self, asset=None, max_shares=None,
def set_max_order_size(self,
asset=None,
max_shares=None,
max_notional=None):
"""
Set a limit on the number of shares and/or dollar value of any single
"""Set a limit on the number of shares and/or dollar value of any single
order placed for sid. Limits are treated as absolute values and are
enforced at the time that the algo attempts to place an order for sid.
If an algorithm attempts to place an order that would result in
exceeding one of these limits, raise a TradingControlException.
Parameters
----------
asset : Asset, optional
If provided, this sets the guard only on positions in the given
asset.
max_shares : int, optional
The maximum number of shares that can be ordered at one time.
max_notional : float, optional
The maximum value that can be ordered at one time.
"""
control = MaxOrderSize(asset=asset,
max_shares=max_shares,
@@ -1519,25 +1971,33 @@ class TradingAlgorithm(object):
@api_method
def set_max_order_count(self, max_count):
"""
Set a limit on the number of orders that can be placed within the given
time interval.
"""Set a limit on the number of orders that can be placed in a single
day.
Parameters
----------
max_count : int
The maximum number of orders that can be placed on any single day.
"""
control = MaxOrderCount(max_count)
self.register_trading_control(control)
@api_method
def set_do_not_order_list(self, restricted_list):
"""
Set a restriction on which assets can be ordered.
"""Set a restriction on which assets can be ordered.
Parameters
----------
restricted_list : set[Asset]
The assets that cannot be ordered.
"""
control = RestrictedListOrder(restricted_list)
self.register_trading_control(control)
@api_method
def set_long_only(self):
"""
Set a rule specifying that this algorithm cannot take short positions.
"""Set a rule specifying that this algorithm cannot take short
positions.
"""
self.register_trading_control(LongOnly())
@@ -1547,8 +2007,27 @@ class TradingAlgorithm(object):
@api_method
@require_not_initialized(AttachPipelineAfterInitialize())
def attach_pipeline(self, pipeline, name, chunksize=None):
"""
Register a pipeline to be computed at the start of each day.
"""Register a pipeline to be computed at the start of each day.
Parameters
----------
pipeline : Pipeline
The pipeline to have computed.
name : str
The name of the pipeline.
chunksize : int, optional
The number of days to compute pipeline results for. Increasing
this number will make it longer to get the first results but
may improve the total runtime of the simulation.
Returns
-------
pipeline : Pipeline
Returns the pipeline that was attached unchanged.
See Also
--------
:func:`zipline.api.pipeline_output`
"""
if self._pipelines:
raise NotImplementedError("Multiple pipelines are not supported.")
@@ -1567,8 +2046,8 @@ class TradingAlgorithm(object):
@api_method
@require_initialized(PipelineOutputDuringInitialize())
def pipeline_output(self, name):
"""
Get the results of pipeline with name `name`.
"""Get the results of the pipeline that was attached with the name:
``name``.
Parameters
----------
@@ -1588,6 +2067,7 @@ class TradingAlgorithm(object):
See Also
--------
:func:`zipline.api.attach_pipeline`
:meth:`zipline.pipeline.engine.PipelineEngine.run_pipeline`
"""
# NOTE: We don't currently support multiple pipelines, but we plan to
+16 -19
View File
@@ -15,36 +15,33 @@
# Note that part of the API is implemented in TradingAlgorithm as
# methods (e.g. order). These are added to this namespace via the
# decorator `api_methods` inside of algorithm.py.
from .finance import (commission, slippage, cancel_policy)
from .utils import math_utils, events
from zipline.finance.slippage import (
FixedSlippage,
VolumeShareSlippage,
)
from zipline.finance.cancel_policy import (
# decorator ``api_method`` inside of algorithm.py.
from .finance import commission, execution, slippage, cancel_policy
from .finance.cancel_policy import (
NeverCancel,
EODCancel
)
from zipline.utils.events import (
from .finance.slippage import (
FixedSlippage,
VolumeShareSlippage,
)
from .utils import math_utils, events
from .utils.events import (
date_rules,
time_rules
)
__all__ = [
'slippage',
'commission',
'cancel_policy',
'NeverCancel',
'EODCancel',
'events',
'math_utils',
'FixedSlippage',
'NeverCancel',
'VolumeShareSlippage',
'cancel_policy',
'commission',
'date_rules',
'events',
'execution',
'math_utils',
'slippage',
'time_rules'
]
+26 -5
View File
@@ -21,16 +21,38 @@ from zipline.gens.sim_engine import DAY_END
class CancelPolicy(with_metaclass(abc.ABCMeta)):
"""Abstract cancellation policy interface.
"""
@abstractmethod
def should_cancel(self, event):
"""Should all open orders be cancelled?
Parameters
----------
event : enum-value
An event type, one of:
- :data:`zipline.gens.sim_engine.BAR`
- :data:`zipline.gens.sim_engine.DAY_START`
- :data:`zipline.gens.sim_engine.DAY_END`
- :data:`zipline.gens.sim_engine.MINUTE_END`
Returns
-------
should_cancel : bool
Should all open orders be cancelled?
"""
pass
class EODCancel(CancelPolicy):
"""
This policy cancels open orders at the end of the day. For now, Zipline
will only apply this policy to minutely simulations.
"""This policy cancels open orders at the end of the day. For now,
Zipline will only apply this policy to minutely simulations.
Parameters
----------
warn_on_cancel : bool, optional
Should a warning be raised if this causes an order to be cancelled?
"""
def __init__(self, warn_on_cancel=True):
self.warn_on_cancel = warn_on_cancel
@@ -40,8 +62,7 @@ class EODCancel(CancelPolicy):
class NeverCancel(CancelPolicy):
"""
Orders are never automatically canceled.
"""Orders are never automatically canceled.
"""
def __init__(self):
self.warn_on_cancel = False
+20 -6
View File
@@ -18,9 +18,15 @@ DEFAULT_MINIMUM_COST_PER_TRADE = 1.0 # $1 per trade
class PerShare(object):
"""
Calculates a commission for a transaction based on a per
"""Calculates a commission for a transaction based on a per
share cost with an optional minimum cost per trade.
Parameters
----------
cost : float, optional
The amount of commissions paid per share traded.
min_trade_cost : optional
The minimum amount of commisions paid per trade.
"""
def __init__(self,
@@ -57,9 +63,13 @@ class PerShare(object):
class PerTrade(object):
"""
Calculates a commission for a transaction based on a per
"""Calculates a commission for a transaction based on a per
trade cost.
Parameters
----------
cost : float, optional
The flat amount of commisions paid per trade.
"""
def __init__(self, cost=DEFAULT_MINIMUM_COST_PER_TRADE):
@@ -84,9 +94,13 @@ class PerTrade(object):
class PerDollar(object):
"""
Calculates a commission for a transaction based on a per
"""Calculates a commission for a transaction based on a per
dollar cost.
Parameters
----------
cost : float, optional
The amount of commissions paid per dollar traded.
"""
def __init__(self, cost=0.0015):
+29 -5
View File
@@ -34,6 +34,8 @@ DEFAULT_VOLUME_SLIPPAGE_BAR_LIMIT = 0.025
class SlippageModel(with_metaclass(abc.ABCMeta)):
"""Abstract interface for defining a new slippage model.
"""
def __init__(self):
self._volume_for_bar = 0
@@ -43,6 +45,24 @@ class SlippageModel(with_metaclass(abc.ABCMeta)):
@abc.abstractproperty
def process_order(self, data, order):
"""Process how orders get filled.
Parameters
----------
data : BarData
The data for the given bar.
order : Order
The order to simulate.
Returns
-------
execution_price : float
The price to execute the trade at.
execution_volume : int
The number of shares that could be filled. This may not be all
the shares ordered in which case the order will be filled over
multiple bars.
"""
pass
def simulate(self, data, asset, orders_for_asset):
@@ -91,6 +111,8 @@ class SlippageModel(with_metaclass(abc.ABCMeta)):
class VolumeShareSlippage(SlippageModel):
"""Model slippage as a function of the volume of shares traded.
"""
def __init__(self, volume_limit=DEFAULT_VOLUME_SLIPPAGE_BAR_LIMIT,
price_impact=0.1):
@@ -162,13 +184,15 @@ class VolumeShareSlippage(SlippageModel):
class FixedSlippage(SlippageModel):
"""Model slippage as a fixed spread.
Parameters
----------
spread : float, optional
spread / 2 will be added to buys and subtracted from sells.
"""
def __init__(self, spread=0.0):
"""
Use the fixed slippage model, which will just add/subtract
a specified spread spread/2 will be added on buys and subtracted
on sells per share
"""
self.spread = spread
def process_order(self, data, order):
+6 -6
View File
@@ -1,15 +1,16 @@
from six import StringIO, iteritems
from abc import ABCMeta, abstractmethod
from collections import namedtuple
import hashlib
from textwrap import dedent
import warnings
from logbook import Logger
import numpy
import pandas as pd
from pandas import read_csv
import numpy
from logbook import Logger
import pytz
import warnings
import requests
from six import StringIO, iteritems, with_metaclass
from zipline.errors import (
MultipleSymbolsFound,
@@ -138,8 +139,7 @@ def mask_requests_args(url, validating=False, params_checker=None, **kwargs):
return request_pair(requests_kwargs, url)
class PandasCSV(object):
__metaclass__ = ABCMeta
class PandasCSV(with_metaclass(ABCMeta, object)):
def __init__(self,
pre_func,
+2 -9
View File
@@ -42,8 +42,6 @@ __all__ = [
'OncePerDay',
# Factory API
'DateRuleFactory',
'TimeRuleFactory',
'date_rules',
'time_rules',
'make_eventrule',
@@ -668,7 +666,7 @@ class OncePerDay(StatefulRule):
# Factory API
class DateRuleFactory(object):
class date_rules(object):
every_day = Always
@staticmethod
@@ -688,16 +686,11 @@ class DateRuleFactory(object):
return NDaysBeforeLastTradingDayOfWeek(n=days_offset)
class TimeRuleFactory(object):
class time_rules(object):
market_open = AfterOpen
market_close = BeforeClose
# Convenience aliases.
date_rules = DateRuleFactory
time_rules = TimeRuleFactory
def make_eventrule(date_rule, time_rule, half_days=True):
"""
Constructs an event rule from the factory api.