diff --git a/_sources/appendix.rst.txt b/_sources/appendix.rst.txt deleted file mode 100644 index 6b3590a7..00000000 --- a/_sources/appendix.rst.txt +++ /dev/null @@ -1,371 +0,0 @@ -API Reference -------------- - -Running a Backtest -~~~~~~~~~~~~~~~~~~ - -.. autofunction:: catalyst.run_algorithm(...) - -Algorithm API -~~~~~~~~~~~~~ - -The following methods are available for use in the ``initialize``, -``handle_data``, and ``before_trading_start`` API functions. - -In all listed functions, the ``self`` argument is implicitly the -currently-executing :class:`~zipline.algorithm.TradingAlgorithm` instance. - -Data Object -``````````` - -.. autoclass:: catalyst.protocol.BarData - :members: - -Scheduling Functions -```````````````````` - -.. autofunction:: catalyst.api.schedule_function - -.. autoclass:: catalyst.api.date_rules - :members: - :undoc-members: - -.. autoclass:: catalyst.api.time_rules - :members: - -Orders -`````` - -.. autofunction:: catalyst.api.order - -.. autofunction:: catalyst.api.order_value - -.. autofunction:: catalyst.api.order_percent - -.. autofunction:: catalyst.api.order_target - -.. autofunction:: catalyst.api.order_target_value - -.. autofunction:: catalyst.api.order_target_percent - -.. autoclass:: catalyst.finance.execution.ExecutionStyle - :members: - -.. autoclass:: catalyst.finance.execution.MarketOrder - -.. autoclass:: catalyst.finance.execution.LimitOrder - -.. autoclass:: catalyst.finance.execution.StopOrder - -.. autoclass:: catalyst.finance.execution.StopLimitOrder - -.. autofunction:: catalyst.api.get_order - -.. autofunction:: catalyst.api.get_open_orders - -.. autofunction:: catalyst.api.cancel_order - -Order Cancellation Policies -''''''''''''''''''''''''''' - -.. autofunction:: catalyst.api.set_cancel_policy - -.. autoclass:: catalyst.finance.cancel_policy.CancelPolicy - :members: - -.. autofunction:: catalyst.api.EODCancel - -.. autofunction:: catalyst.api.NeverCancel - - -Assets -`````` - -.. autofunction:: catalyst.api.symbol - -.. autofunction:: catalyst.api.symbols - -.. autofunction:: catalyst.api.set_symbol_lookup_date - -.. autofunction:: catalyst.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:: catalyst.api.set_do_not_order_list - -.. autofunction:: catalyst.api.set_long_only - -.. autofunction:: catalyst.api.set_max_leverage - -.. autofunction:: catalyst.api.set_max_order_count - -.. autofunction:: catalyst.api.set_max_order_size - -.. autofunction:: catalyst.api.set_max_position_size - - -Simulation Parameters -````````````````````` - -.. autofunction:: catalyst.api.set_benchmark - -Commission Models -''''''''''''''''' - -.. autofunction:: catalyst.api.set_commission - -.. autoclass:: catalyst.finance.commission.CommissionModel - :members: - -.. autoclass:: catalyst.finance.commission.PerShare - -.. autoclass:: catalyst.finance.commission.PerTrade - -.. autoclass:: catalyst.finance.commission.PerDollar - -Slippage Models -''''''''''''''' - -.. autofunction:: catalyst.api.set_slippage - -.. autoclass:: catalyst.finance.slippage.SlippageModel - :members: - -.. autoclass:: catalyst.finance.slippage.FixedSlippage - -.. autoclass:: catalyst.finance.slippage.VolumeShareSlippage - -Pipeline -```````` - -Not supported yet. - -.. For more information, see :ref:`pipeline-api` - -.. .. autofunction:: catalyst.api.attach_pipeline - -.. .. autofunction:: catalyst.api.pipeline_output - - -Miscellaneous -````````````` - -.. autofunction:: catalyst.api.record - -.. autofunction:: catalyst.api.get_environment - -.. autofunction:: catalyst.api.fetch_csv - - -.. _pipeline-api: - -.. Pipeline API -.. ~~~~~~~~~~~~ - -.. .. autoclass:: zipline.pipeline.Pipeline -.. :members: -.. :member-order: groupwise - -.. .. autoclass:: zipline.pipeline.CustomFactor -.. :members: -.. :member-order: groupwise - -.. .. autoclass:: zipline.pipeline.filters.Filter -.. :members: __and__, __or__ -.. :exclude-members: dtype - -.. .. autoclass:: zipline.pipeline.factors.Factor -.. :members: bottom, deciles, demean, linear_regression, pearsonr, -.. percentile_between, quantiles, quartiles, quintiles, rank, -.. spearmanr, top, winsorize, zscore, isnan, notnan, isfinite, eq, -.. \__add__, \__sub__, \__mul__, \__div__, \__mod__, \__pow__, -.. \__lt__, \__le__, \__ne__, \__ge__, \__gt__ -.. :exclude-members: dtype -.. :member-order: bysource - -.. .. autoclass:: zipline.pipeline.term.Term -.. :members: -.. :exclude-members: compute_extra_rows, dependencies, inputs, mask, windowed - -.. .. autoclass:: zipline.pipeline.data.USEquityPricing -.. :members: open, high, low, close, volume -.. :undoc-members: - -.. Built-in Factors -.. ```````````````` - -.. .. autoclass:: zipline.pipeline.factors.AverageDollarVolume -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.BollingerBands -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.BusinessDaysSincePreviousEvent -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.BusinessDaysUntilNextEvent -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.ExponentialWeightedMovingAverage -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.ExponentialWeightedMovingStdDev -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.Latest -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.MaxDrawdown -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.Returns -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.RollingLinearRegressionOfReturns -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.RollingPearsonOfReturns -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.RollingSpearmanOfReturns -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.RSI -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.SimpleMovingAverage -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.VWAP -.. :members: - -.. .. autoclass:: zipline.pipeline.factors.WeightedAverageValue -.. :members: - -.. Pipeline Engine -.. ``````````````` - -.. .. autoclass:: zipline.pipeline.engine.PipelineEngine -.. :members: run_pipeline, run_chunked_pipeline -.. :member-order: bysource - -.. .. autoclass:: zipline.pipeline.engine.SimplePipelineEngine -.. :members: __init__, run_pipeline, run_chunked_pipeline -.. :member-order: bysource - -.. .. autofunction:: zipline.pipeline.engine.default_populate_initial_workspace - -.. Data Loaders -.. ```````````` - -.. .. autoclass:: zipline.pipeline.loaders.equity_pricing_loader.USEquityPricingLoader -.. :members: __init__, from_files, load_adjusted_array -.. :member-order: bysource - -Asset Metadata -~~~~~~~~~~~~~~ - -.. autoclass:: catalyst.assets.Asset - :members: - -.. autoclass:: catalyst.assets.AssetConvertible - :members: - - -Trading Calendar API -~~~~~~~~~~~~~~~~~~~~ - -.. autofunction:: catalyst.utils.calendars.get_calendar - -.. autoclass:: catalyst.utils.calendars.TradingCalendar - :members: - -.. autofunction:: catalyst.utils.calendars.register_calendar - -.. autofunction:: catalyst.utils.calendars.register_calendar_type - -.. autofunction:: catalyst.utils.calendars.deregister_calendar - -.. autofunction:: catalyst.utils.calendars.clear_calendars - - -Data API -~~~~~~~~ - -.. Writers -.. ``````` -.. .. autoclass:: zipline.data.minute_bars.BcolzMinuteBarWriter -.. :members: - -.. .. autoclass:: zipline.data.us_equity_pricing.BcolzDailyBarWriter -.. :members: - -.. .. autoclass:: zipline.data.us_equity_pricing.SQLiteAdjustmentWriter -.. :members: - -.. .. autoclass:: zipline.assets.AssetDBWriter -.. :members: - -.. Readers -.. ``````` -.. .. autoclass:: zipline.data.minute_bars.BcolzMinuteBarReader -.. :members: - -.. .. autoclass:: zipline.data.us_equity_pricing.BcolzDailyBarReader -.. :members: - -.. .. autoclass:: zipline.data.us_equity_pricing.SQLiteAdjustmentReader -.. :members: - -.. .. autoclass:: zipline.assets.AssetFinder -.. :members: - -.. .. autoclass:: zipline.data.data_portal.DataPortal -.. :members: - -.. Bundles -.. ``````` -.. .. autofunction:: zipline.data.bundles.register - -.. .. autofunction:: zipline.data.bundles.ingest(name, environ=os.environ, date=None, show_progress=True) - -.. .. autofunction:: zipline.data.bundles.load(name, environ=os.environ, date=None) - -.. .. autofunction:: zipline.data.bundles.unregister - -.. .. data:: zipline.data.bundles.bundles - -.. The bundles that have been registered as a mapping from bundle name to bundle -.. data. This mapping is immutable and should only be updated through -.. :func:`~zipline.data.bundles.register` or -.. :func:`~zipline.data.bundles.unregister`. - -.. .. autofunction:: zipline.data.bundles.yahoo_equities - - - -Utilities -~~~~~~~~~ - -Caching -``````` - -.. autoclass:: catalyst.utils.cache.CachedObject - -.. autoclass:: catalyst.utils.cache.ExpiringCache - -.. autoclass:: catalyst.utils.cache.dataframe_cache - -.. autoclass:: catalyst.utils.cache.working_file - -.. autoclass:: catalyst.utils.cache.working_dir - -Command Line -```````````` -.. autofunction:: catalyst.utils.cli.maybe_show_progress diff --git a/_sources/beginner-tutorial.rst.txt b/_sources/beginner-tutorial.rst.txt deleted file mode 100644 index 129fe90c..00000000 --- a/_sources/beginner-tutorial.rst.txt +++ /dev/null @@ -1,16623 +0,0 @@ -Catalyst Beginner Tutorial --------------------------- - -Basics -~~~~~~ - -Catalyst is an open-source algorithmic trading simulator for crypto -assets written in Python. The source code can be found at: -https://github.com/enigmampc/catalyst - -Some benefits include: - -- Support for several of the top crypto-exchanges by trading volume. -- Realistic: slippage, transaction costs, order delays. -- Stream-based: Process each event individually, avoids look-ahead - bias. -- Batteries included: Common transforms (moving average) as well as - common risk calculations (Sharpe). -- Developed and continuously updated by - `Enigma MPC `__ which is building the Enigma - data marketplace protocol as well as Catalyst, the first application - that will run on our protocol. Powered by our financial data - marketplace, Catalyst empowers users to share and curate data and - build profitable, data-driven investment strategies. - -This tutorial assumes that you have Catalyst correctly installed, see the -:doc:`Install` section if you haven't set up Catalyst yet. - -Every ``catalyst`` algorithm consists of at least two functions you have to -define: - -* ``initialize(context)`` -* ``handle_data(context, data)`` - -Before the start of the algorithm, ``catalyst`` calls the -``initialize()`` function and passes in a ``context`` variable. -``context`` is a persistent namespace for you to store variables you -need to access from one algorithm iteration to the next. - -After the algorithm has been initialized, ``catalyst`` calls the -``handle_data()`` function on each iteration, that's one per day (daily) or -once every minute (minute), depending on the frequency we choose to run our -simulation. On every iteration, ``handle_data()`` passes the same ``context`` -variable and an event-frame called ``data`` containing the current trading bar -with open, high, low, and close (OHLC) prices as well as volume for each -crypto asset in your universe. - -.. For more information on these functions, see the `relevant part of the -.. Quantopian docs `. - -My first algorithm -~~~~~~~~~~~~~~~~~~ - -Lets take a look at a very simple algorithm from the ``examples`` directory: -`buy_btc_simple.py `_: - -.. code-block:: python - - from catalyst.api import order, record, symbol - - - def initialize(context): - context.asset = symbol('btc_usd') - - - def handle_data(context, data): - order(context.asset, 1) - record(btc = data.current(context.asset, 'price')) - - -As you can see, we first have to import some functions we would like to -use. All functions commonly used in your algorithm can be found in -``catalyst.api``. Here we are using :func:`~catalyst.api.order()` which takes -twoarguments: a cryptoasset object, and a number specifying how many assets you -wouldlike to order (if negative, :func:`~catalyst.api.order()` will sell/short -assets). In this case we want to order 1 bitcoin at each iteration. - -.. For more documentation on ``order()``, see the `Quantopian docs -.. `__. - -Finally, the :func:`~catalyst.api.record` function allows you to save the value -of a variable at each iteration. You provide it with a name for the variable -together with the variable itself: ``varname=var``. After the algorithm -finished running you will have access to each variable value you tracked -with :func:`~catalyst.api.record` under the name you provided (we will see this -further below). You also see how we can access the current price data of -a bitcoin in the ``data`` event frame. - -.. (for more information see `here `__. - -Ingesting data -~~~~~~~~~~~~~~ - -Before you can backtest your algorithm, you first need to load the historical -pricing data that Catalyst needs to run your simulation through a process called -``ingestion``. When you ingest data, Catalyst downloads that data in compressed -form from the Enigma servers (which eventually will migrate to the Enigma Data -Marketplace), and stores it locally to make it available at runtime. - -In order to ingest data, you need to run a command like the following: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -i btc_usd - -This instructs Catalyst to download pricing data from the ``Bitfinex`` exchange -for the ``btc_usd`` currency pair (this follows from the simple algorithm -presented above where we want to trade ``btc_usd``), and we're choosing to test -our algorithm using historical pricing data from the Bitfinex exchange. By -default, Catalyst assumes that you want data with ``daily`` frequency (one candle -bar per day). If you want instead ``minute`` frequency (one candle bar for every -minute), you would need to specify it as follows: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -i btc_usd -f minute - -.. parsed-literal:: - - Ingesting exchange bundle bitfinex... - [====================================] Ingesting daily price data on bitfinex: 100% - -We believe it is important for you to have a high-level understanding of how -data is managed, hence the following overview: - -- Pricing data is split and packaged into ``bundles``: chunks of data organized - as time series that are kept up to date daily on Enigma's servers. Catalyst - downloads the requested bundles and reconstructs the full dataset in your - hard drive. - -- Pricing data is provided in ``daily`` and ``minute`` resolution. Those are - different bundle datasets, and are managed separately. - -- Bundles are exchange-specific, as the pricing data is specific to the trades - that happen in each exchange. As a result, you must specify which - exchange you want pricing data from when ingesting data. - -- Catalyst keeps track of all the downloaded bundles, so that it only has to - download them once, and will do incremental updates as needed. - -- When running in ``live trading`` mode, Catalyst will first look for - historical pricing data in the locally stored bundles. If there is anything - missing, Catalyst will hit the exchange for the most recent data, and merge - it with the local bundle to optimize the number of requests it needs to make - to the exchange. - -The ``ingest-exchange`` command in catalyst offers additional parameters to -further tweak the data ingestion process. You can learn more by running the -following from the command line: - -.. code-block:: bash - - catalyst ingest-exchange --help - -Running the algorithm -~~~~~~~~~~~~~~~~~~~~~ - -You can now test your algorithm using cryptoassets' historical pricing data, -``catalyst`` provides three interfaces: - -- A command-line interface (CLI), -- a :func:`~catalyst.run_algorithm()` that you can call from other - Python scripts, -- and the ``Jupyter Notebook`` magic. - - -We'll start with the CLI, and introduce the ``run_algorithm()`` in the last -example of this tutorial. Some of the :doc:`example algorithms ` -provide instructions on how to run them both from the CLI, and using the -:func:`~catalyst.run_algorithm` function. For the third method, refer to the -corresponding section on :ref:`Catalyst & Jupyter Notebook ` after you -have assimilated the contents of this tutorial. - -Command line interface -^^^^^^^^^^^^^^^^^^^^^^ - -After you installed Catalyst, you should be able to execute the following -from your command line (e.g. ``cmd.exe`` or the ``Anaconda Prompt`` on Windows, -or the Terminal application on MacOS). - -.. code-block:: bash - - $ catalyst --help - -This is the resulting output, simplified for eductional purposes: - -.. parsed-literal:: - - Usage: catalyst [OPTIONS] COMMAND [ARGS]... - - Top level catalyst entry point. - - Options: - --version Show the version and exit. - --help Show this message and exit. - - Commands: - ingest-exchange Ingest data for the given exchange. - live Trade live with the given algorithm. - run Run a backtest for the given algorithm. - -There are three main modes you can run on Catalyst. The first being -``ingest-exchange`` for data ingestion, which we have covered in the previous -section. The second is ``live`` to use your algorithm to trade live against a -given exchange, and the third mode ``run`` is to backtest your algorithm before -trading live with it. - -Let's start with backtesting, so run this other command to learn more about -the available options: - -.. code-block:: bash - - $ catalyst run --help - -.. parsed-literal:: - - Usage: catalyst run [OPTIONS] - - Run a backtest for the given algorithm. - - Options: - -f, --algofile FILENAME The file that contains the algorithm to run. - -t, --algotext TEXT The algorithm script to run. - -D, --define TEXT Define a name to be bound in the namespace - before executing the algotext. For example - '-Dname=value'. The value may be any python - expression. These are evaluated in order so - they may refer to previously defined names. - --data-frequency [daily|minute] - The data frequency of the simulation. - [default: daily] - --capital-base FLOAT The starting capital for the simulation. - [default: 10000000.0] - -b, --bundle BUNDLE-NAME The data bundle to use for the simulation. - [default: poloniex] - --bundle-timestamp TIMESTAMP The date to lookup data on or before. - [default: ] - -s, --start DATE The start date of the simulation. - -e, --end DATE The end date of the simulation. - -o, --output FILENAME The location to write the perf data. If this - is '-' the perf will be written to stdout. - [default: -] - --print-algo / --no-print-algo Print the algorithm to stdout. - -x, --exchange-name [poloniex|bitfinex|bittrex] - The name of the targeted exchange - (supported: bitfinex, bittrex, poloniex). - -n, --algo-namespace TEXT A label assigned to the algorithm for data - storage purposes. - -c, --base-currency TEXT The base currency used to calculate - statistics (e.g. usd, btc, eth). - --help Show this message and exit. - - -As you can see there are a couple of flags that specify where to find your -algorithm (``-f``) as well as a the ``-x`` flag to specify which exchange to -use. There are also arguments for the date range to run the algorithm over -(``--start`` and ``--end``). You also need to set the base currency for your -algorithm through the ``-c`` flag, and the ``--capital_base``. All the -aforementioned parameters are required. Optionally, you will want to save the -performance metrics of your algorithm so that you can analyze how it performed. -This is done via the ``--output`` flag and will cause it to write the -performance ``DataFrame`` in the pickle Python file format. Note that you can -also define a configuration file with these parameters that you can then -conveniently pass to the ``-c`` option so that you don't have to supply the -command line args all the time. - -Thus, to execute our algorithm from above and save the results to -``buy_btc_simple_out.pickle`` we would call ``catalyst run`` as follows: - -.. code-block:: bash - - catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -c usd --capital-base 100000 -o buy_btc_simple_out.pickle - - -.. parsed-literal:: - - INFO: run_algo: running algo in backtest mode - INFO: exchange_algorithm: initialized trading algorithm in backtest mode - INFO: Performance: Simulated 639 trading days out of 639. - INFO: Performance: first open: 2016-01-01 00:00:00+00:00 - INFO: Performance: last close: 2017-09-30 23:59:00+00:00 - - -``run`` first calls the ``initialize()`` function, and then -streams the historical asset price day-by-day through ``handle_data()``. -After each call to ``handle_data()`` we instruct ``catalyst`` to order 1 -bitcoin. After the call of the ``order()`` function, ``catalyst`` -enters the ordered stock and amount in the order book. After the -``handle_data()`` function has finished, ``catalyst`` looks for any open -orders and tries to fill them. If the trading volume is high enough for -this asset, the order is executed after adding the commission and -applying the slippage model which models the influence of your order on -the stock price, so your algorithm will be charged more than just the -asset price. (Note, that you can also change the commission and -slippage model that ``catalyst`` uses). - -.. see the `Quantopian docs `__ -.. for more information). - - -Let's take a quick look at the performance ``DataFrame``. For this, we write -different Python script--let's call it ``print_results.py``--and we make use of -the fantastic ``pandas`` library to print the first ten rows. Note that -``catalyst`` makes heavy usage of `pandas `_, -especially for data analysis and outputting so it's worth spending some time to -learn it. - -.. code-block:: python - - import pandas as pd - perf = pd.read_pickle('buy_btc_simple_out.pickle') # read in perf DataFrame - print(perf.head()) - -Which we execute by running: - -.. code-block:: bash - - $ python print_results.py - -.. raw:: html - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
algo_volatilityalgorithm_period_returnalphabenchmark_period_returnbenchmark_volatilitybetabtccapital_usedending_cashending_exposure...short_exposureshort_valueshorts_countsortinostarting_cashstarting_exposurestarting_valuetrading_daystransactionstreasury_period_return
2016-01-01 23:59:00+00:00NaN0.000000e+00NaN-0.010937NaNNaN433.9799990.0000001.000000e+070.00...000NaN1.000000e+070.000.001[]0.0227
2016-01-02 23:59:00+00:000.000011-9.536708e-07-0.000170-0.0064800.173338-0.000062432.700000-442.2367089.999558e+06432.70...000-11.2249721.000000e+070.000.002[{u'order_id': u'7869f7828fa140328eb40477bb7de...0.0227
2016-01-03 23:59:00+00:000.000011-2.328842e-06-0.000176-0.0265120.1978570.000009428.390000-437.8317169.999120e+06856.78...000-12.7542629.999558e+06432.70432.703[{u'order_id': u'be62ff77760c4599abaac43be9cc9...0.0227
2016-01-04 23:59:00+00:000.000011-2.380954e-06-0.000139-0.0086400.2697900.000020432.900000-442.4411169.998677e+061298.70...000-11.2872059.999120e+06856.78856.784[{u'order_id': u'd6dca79513214346a646079213526...0.0224
2016-01-05 23:59:00+00:000.000011-3.650729e-06-0.000158-0.0214260.2459890.000024431.840000-441.3577549.998236e+061727.36...000-12.3338479.998677e+061298.701298.705[{u'order_id': u'505275d6646a41f3856b22b16678d...0.0225
-
- -| - -There is a row for each trading day, starting on the first day of our -simulation Jan 1st, 2016. In the columns you can find various -information about the state of your algorithm. The column -``btc`` was placed there by the ``record()`` function mentioned earlier -and allows us to plot the price of bitcoin. For example, we could easily -examine now how our portfolio value changed over time compared to the -bitcoin price. - -Now we will run the simulation again, but this time we extend our original -algorithm with the addition of the ``analyze()`` function. Somewhat analogously -as how ``initialize()`` gets called once before the start of the algorithm, -``analyze()`` gets called once at the end of the algorithm, and receives two -variables: ``context``, which we discussed at the very beginning, and ``perf``, -which is the pandas dataframe containing the performance data for our algorithm -that we reviewed above. Inside the ``analyze()`` function is where we can -analyze and visualize the results of our strategy. Here's the revised simple -algorithm (note the addition of Line 1, and Lines 11-18) - -.. code-block:: python - - import matplotlib.pyplot as plt - from catalyst.api import order, record, symbol - - def initialize(context): - context.asset = symbol('btc_usd') - - def handle_data(context, data): - order(context.asset, 1) - record(btc = data.current(context.asset, 'price')) - - def analyze(context, perf): - ax1 = plt.subplot(211) - perf.portfolio_value.plot(ax=ax1) - ax1.set_ylabel('portfolio value') - ax2 = plt.subplot(212, sharex=ax1) - perf.btc.plot(ax=ax2) - ax2.set_ylabel('bitcoin price') - plt.show() - -Here we make use of the external visualization library called -`matplotlib `_, which you might recall we installed -alongside enigma-catalyst (with the exception of the ``Conda`` install, where it -was included by default inside the conda environment we created). If for any -reason you don't have it installed, you can add it by running: - -.. code-block:: bash - - (catalyst)$ pip install matplotlib - -If everything works well, you'll see the following chart: - -.. image:: https://s3.amazonaws.com/enigmaco-docs/github.io/buy_btc_simple_graph.png - -Our algorithm performance as assessed by the ``portfolio_value`` closely -matches that of the bitcoin price. This is not surprising as our algorithm -only bought bitcoin every chance it got. - - If you get an error when invoking matplotlib to visualize the performance - results refer to `MacOS + Matplotlib `_. - Alternatively, some users have reported the following error when running an algo - in a Linux environment: - - .. parsed-literal:: - - ImportError: No module named _tkinter, please install the python-tk package - - Which can easily solved by running (in Ubuntu/Debian-based systems): - - .. code-block:: python - - sudo apt install python-tk - - -.. _history: - -Access to previous prices using ``history`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Working example: Dual Moving Average Cross-Over -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The Dual Moving Average (DMA) is a classic momentum strategy. It's -probably not used by any serious trader anymore but is still very -instructive. The basic idea is that we compute two rolling or moving -averages (mavg) -- one with a longer window that is supposed to capture -long-term trends and one shorter window that is supposed to capture -short-term trends. Once the short-mavg crosses the long-mavg from below -we assume that the stock price has upwards momentum and long the stock. -If the short-mavg crosses from above we exit the positions as we assume -the stock to go down further. - -As we need to have access to previous prices to implement this strategy -we need a new concept: History. ``data.history()`` is a convenience function -that keeps a rolling window of data for you. The first argument is the number -of bars you want to collect, the second argument is the unit (either ``'1d'`` -for daily or ``'1m'`` for minute frequency, but note that you need to have -minute-level data when using ``1m``). This is a function we use in the -``handle_data()`` section. - -You will note that the code below is substantially longer than the previous -examples. Don't get overwhelmed by it as the logic is fairly simple and easy to -follow. Most of the added some complexity has been added to beautify the output, -which you can skim through for now. A copy of this algorithm is available in -the ``examples`` directory: -`dual_moving_average.py `_. - -.. code-block:: python - - import numpy as np - import pandas as pd - from logbook import Logger - import matplotlib.pyplot as plt - - from catalyst import run_algorithm - from catalyst.api import (order, record, symbol, order_target_percent, - get_open_orders) - from catalyst.exchange.utils.stats_utils import extract_transactions - - NAMESPACE = 'dual_moving_average' - log = Logger(NAMESPACE) - - def initialize(context): - context.i = 0 - context.asset = symbol('ltc_usd') - context.base_price = None - - - def handle_data(context, data): - # define the windows for the moving averages - short_window = 50 - long_window = 200 - - # Skip as many bars as long_window to properly compute the average - context.i += 1 - if context.i < long_window: - return - - # Compute moving averages calling data.history() for each - # moving average with the appropriate parameters. We choose to use - # minute bars for this simulation -> freq="1m" - # Returns a pandas dataframe. - short_mavg = data.history(context.asset, 'price', - bar_count=short_window, frequency="1m").mean() - long_mavg = data.history(context.asset, 'price', - bar_count=long_window, frequency="1m").mean() - - # Let's keep the price of our asset in a more handy variable - price = data.current(context.asset, 'price') - - # If base_price is not set, we use the current value. This is the - # price at the first bar which we reference to calculate price_change. - if context.base_price is None: - context.base_price = price - price_change = (price - context.base_price) / context.base_price - - # Save values for later inspection - record(price=price, - cash=context.portfolio.cash, - price_change=price_change, - short_mavg=short_mavg, - long_mavg=long_mavg) - - # Since we are using limit orders, some orders may not execute immediately - # we wait until all orders are executed before considering more trades. - orders = get_open_orders(context.asset) - if len(orders) > 0: - return - - # Exit if we cannot trade - if not data.can_trade(context.asset): - return - - # We check what's our position on our portfolio and trade accordingly - pos_amount = context.portfolio.positions[context.asset].amount - - # Trading logic - if short_mavg > long_mavg and pos_amount == 0: - # we buy 100% of our portfolio for this asset - order_target_percent(context.asset, 1) - elif short_mavg < long_mavg and pos_amount > 0: - # we sell all our positions for this asset - order_target_percent(context.asset, 0) - - - def analyze(context, perf): - - # Get the base_currency that was passed as a parameter to the simulation - exchange = list(context.exchanges.values())[0] - base_currency = exchange.base_currency.upper() - - # First chart: Plot portfolio value using base_currency - ax1 = plt.subplot(411) - perf.loc[:, ['portfolio_value']].plot(ax=ax1) - ax1.legend_.remove() - ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency)) - start, end = ax1.get_ylim() - ax1.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - - # Second chart: Plot asset price, moving averages and buys/sells - ax2 = plt.subplot(412, sharex=ax1) - perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price') - ax2.legend_.remove() - ax2.set_ylabel('{asset}\n({base})'.format( - asset = context.asset.symbol, - base = base_currency - )) - start, end = ax2.get_ylim() - ax2.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - - transaction_df = extract_transactions(perf) - if not transaction_df.empty: - buy_df = transaction_df[transaction_df['amount'] > 0] - sell_df = transaction_df[transaction_df['amount'] < 0] - ax2.scatter( - buy_df.index.to_pydatetime(), - perf.loc[buy_df.index, 'price'], - marker='^', - s=100, - c='green', - label='' - ) - ax2.scatter( - sell_df.index.to_pydatetime(), - perf.loc[sell_df.index, 'price'], - marker='v', - s=100, - c='red', - label='' - ) - - # Third chart: Compare percentage change between our portfolio - # and the price of the asset - ax3 = plt.subplot(413, sharex=ax1) - perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3) - ax3.legend_.remove() - ax3.set_ylabel('Percent Change') - start, end = ax3.get_ylim() - ax3.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - - # Fourth chart: Plot our cash - ax4 = plt.subplot(414, sharex=ax1) - perf.cash.plot(ax=ax4) - ax4.set_ylabel('Cash\n({})'.format(base_currency)) - start, end = ax4.get_ylim() - ax4.yaxis.set_ticks(np.arange(0, end, end/5)) - - plt.show() - - - if __name__ == '__main__': - run_algorithm( - capital_base=1000, - data_frequency='minute', - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - algo_namespace=NAMESPACE, - base_currency='usd', - start=pd.to_datetime('2017-9-22', utc=True), - end=pd.to_datetime('2017-9-23', utc=True), - ) - -In order to run the code above, you have to ingest the needed data first: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -f minute -i ltc_usd - -And then run the code above with the following command: - -.. code-block:: bash - - catalyst run -f dual_moving_average.py -x bitfinex -s 2017-9-22 -e 2017-9-23 --capital-base 1000 --base-currency usd --data-frequency minute -o out.pickle - -Alternatively, we can make use of the ``run_algorithm()`` function included at -the end of the file, where we can specify all the simulation parameters, and -execute this file as a Python script: - -.. code-block:: bash - - python dual_moving_average.py - -Either way, we obtain the following charts: - -.. image:: https://s3.amazonaws.com/enigmaco-docs/github.io/tutorial_dual_moving_average.png - - -A few comments on the code above: - - At the beginning of our code, we import a number of Python libraries that we - will be using in different parts of our script. It's good practice to keep all - imports at the beginning of the file, as they are available globally - throughout our script. All the libraries imported in this example are already - present in your environment since they are prerequisites for the Catalyst - installation. - - Focus on the code that is inside ``handle_data()`` that is where all the - trading logic occurs. You can safely dismiss most of the code in the - ``analyze()`` section, which is mostly to customize the visualization of the - performance of our algorithm using the matplotlib library. You can copy and - paste this whole section into other algorithms to obtain a similar display. - - Inside the ``handle_data()``, we also used the ``order_target_percent()`` - function above. This and other functions like it can make order management - and portfolio rebalancing much easier. - - The ``ltc_usd`` asset was arbitrarily chosen. The values of 50 and 200 for the - ``short_window`` and ``long_window`` parameters are fairly common for a dual - moving average crossover strategy from the world of traditional stocks (but - bear in mind that they are usually used with daily bars instead of minute - bars). The ``start`` and ``end`` dates have been chosen so as to demonstrate - how our strategy can both perform better (blue line above green line on the - ``Percent Change`` chart) and worse (green line above blue line towards the end) than the - price of the asset we are trading. - - You can change any of these parameters: ``asset``, ``short_window``, - ``long_window``, ``start_date`` and ``end_date`` and compare the results, and - you will see that in most cases, the performance is either worse than the - price of the asset, or you are overfitting to one specific case. As we said - at the beginning of this section, this strategy is probably not used by any - serious trader anymore, but its educational purpose. - -Although it might not be directly apparent, the power of ``history()`` -(pun intended) can not be under-estimated as most algorithms make use of -prior market developments in one form or another. You could easily -devise a strategy that trains a classifier with -`scikit-learn `__ which tries to -predict future market movements based on past prices (note, that most of -the ``scikit-learn`` functions require ``numpy.ndarray``\ s rather than -``pandas.DataFrame``\ s, so you can simply pass the underlying -``ndarray`` of a ``DataFrame`` via ``.values``). - -.. _jupyter: - -Jupyter Notebook -~~~~~~~~~~~~~~~~ - -(`This is actual Notebook `_ referenced in the text below) - -The `Jupyter Notebook `__ is a very powerful -browser-based interface to a Python interpreter. As it is already the -de-facto interface for most quantitative researchers, ``catalyst`` -provides an easy way to run your algorithm inside the Notebook without -requiring you to use the CLI. We include this section here as an alternative to -running algorithms through the command line. - -Install -^^^^^^^ - -In order to use Jupyter Notebook, you first have to install it inside your -environment. It's available as ``pip`` package, so regardless of how you -installed Catalyst, go inside your catalyst environemnt and run: - -.. code-block:: bash - - (catalyst)$ pip install jupyter - -Once you have Jupyter Notebook installed, every time you want to use it run: - -.. code-block:: bash - - (catalyst)$ jupyter notebook - -A local server will launch, and will open a new window on your browser. That's -the interface through which you will interact with Jupyter Notebook. - -Running Algorithms -^^^^^^^^^^^^^^^^^^ - -Before running your algorithms inside the Jupyter Notebook, remember to ingest -the data from the command line interface (CLI). In the example below, you would -need to run first: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -i btc_usd - -To use Catalyst inside a Jupyter Noebook, you have to write your algorithm in a -cell and let the Jupyter know that it is supposed to execute this algorithm with -Catalyst. This is done via the ``%%catalyst`` IPython magic command that is -available after you import ``catalyst`` from within the Notebook. This magic -takes the same arguments as the command line interface. Thus to run the -algorithm just supply the same parameters as the CLI but without the -f -and -o arguments. We just have to execute the following cell after -importing ``catalyst`` to register the magic. - -.. code:: python - - # Register the catalyst magic - %load_ext catalyst - -.. code:: python - - # Setup matplotlib to display graphs inline in this Notebook - %matplotlib inline - -Note below that we do not have to specify an input file (-f) since the -magic will use the contents of the cell and look for your algorithm -functions. - -.. code:: python - - %%catalyst --start 2015-3-2 --end 2017-6-28 --capital-base 100000 -x bitfinex -c usd - - from catalyst.finance.slippage import VolumeShareSlippage - - from catalyst.api import ( - order_target_value, - symbol, - record, - cancel_order, - get_open_orders, - ) - - def initialize(context): - context.ASSET_NAME = 'btc_usd' - context.TARGET_HODL_RATIO = 0.8 - context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO - - # For all trading pairs in the poloniex bundle, the default denomination - # currently supported by Catalyst is 1/1000th of a full coin. Use this - # constant to scale the price of up to that of a full coin if desired. - context.TICK_SIZE = 1000.0 - - context.is_buying = True - context.asset = symbol(context.ASSET_NAME) - - context.i = 0 - - def handle_data(context, data): - context.i += 1 - - starting_cash = context.portfolio.starting_cash - target_hodl_value = context.TARGET_HODL_RATIO * starting_cash - reserve_value = context.RESERVE_RATIO * starting_cash - - # Cancel any outstanding orders - orders = get_open_orders(context.asset) or [] - for order in orders: - cancel_order(order) - - # Stop buying after passing the reserve threshold - cash = context.portfolio.cash - if cash <= reserve_value: - context.is_buying = False - - # Retrieve current asset price from pricing data - price = data.current(context.asset, 'price') - - # Check if still buying and could (approximately) afford another purchase - if context.is_buying and cash > price: - # Place order to make position in asset equal to target_hodl_value - order_target_value( - context.asset, - target_hodl_value, - limit_price=price*1.1, - ) - - record( - price=price, - volume=data.current(context.asset, 'volume'), - cash=cash, - starting_cash=context.portfolio.starting_cash, - leverage=context.account.leverage, - ) - - def analyze(context=None, results=None): - import matplotlib.pyplot as plt - - # Plot the portfolio and asset data. - ax1 = plt.subplot(611) - results[['portfolio_value']].plot(ax=ax1) - ax1.set_ylabel('Portfolio Value (USD)') - - ax2 = plt.subplot(612, sharex=ax1) - ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME)) - (context.TICK_SIZE * results[['price']]).plot(ax=ax2) - - trans = results.ix[[t != [] for t in results.transactions]] - buys = trans.ix[ - [t[0]['amount'] > 0 for t in trans.transactions] - ] - ax2.plot( - buys.index, - context.TICK_SIZE * results.price[buys.index], - '^', - markersize=10, - color='g', - ) - - ax3 = plt.subplot(613, sharex=ax1) - results[['leverage', 'alpha', 'beta']].plot(ax=ax3) - ax3.set_ylabel('Leverage ') - - ax4 = plt.subplot(614, sharex=ax1) - results[['starting_cash', 'cash']].plot(ax=ax4) - ax4.set_ylabel('Cash (USD)') - - results[[ - 'treasury', - 'algorithm', - 'benchmark', - ]] = results[[ - 'treasury_period_return', - 'algorithm_period_return', - 'benchmark_period_return', - ]] - - ax5 = plt.subplot(615, sharex=ax1) - results[[ - 'treasury', - 'algorithm', - 'benchmark', - ]].plot(ax=ax5) - ax5.set_ylabel('Percent Change') - - ax6 = plt.subplot(616, sharex=ax1) - results[['volume']].plot(ax=ax6) - ax6.set_ylabel('Volume (mCoins/5min)') - - plt.legend(loc=3) - - # Show the plot. - plt.gcf().set_size_inches(18, 8) - plt.show() - -:: - - [2017-08-11 07:19:46.411748] INFO: Loader: Loading benchmark data for 'USDT_BTC' from 1989-12-31 00:00:00+00:00 to 2017-08-09 00:00:00+00:00 - [2017-08-11 07:19:46.418983] INFO: Loader: Loading data for /Users//.catalyst/data/USDT_BTC_benchmark.csv failed with error [Unknown string format]. - [2017-08-11 07:19:46.419740] INFO: Loader: Cache at /Users//.catalyst/data/USDT_BTC_benchmark.csv does not have data from 1990-01-01 00:00:00+00:00 to 2017-08-09 00:00:00+00:00. - - [2017-08-11 07:19:46.420770] INFO: Loader: Downloading benchmark data for 'USDT_BTC' from 1989-12-31 00:00:00+00:00 to 2017-08-09 00:00:00+00:00 - [2017-08-11 07:19:50.060244] WARNING: Loader: Still don't have expected data after redownload! - [2017-08-11 07:19:50.097334] WARNING: Loader: Refusing to download new treasury data because a download succeeded at 2017-08-11 06:56:49+00:00. - [2017-08-11 07:19:54.618399] INFO: Performance: Simulated 851 trading days out of 851. - [2017-08-11 07:19:54.619301] INFO: Performance: first open: 2015-03-01 00:00:00+00:00 - [2017-08-11 07:19:54.620430] INFO: Performance: last close: 2017-06-28 23:59:00+00:00 - -.. figure:: https://i.imgur.com/DS5w47q.png - :alt: png - -.. raw:: html - -
- -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - -
- -.. raw:: html - - - -algo_volatility - -.. raw:: html - - - -algorithm_period_return - -.. raw:: html - - - -alpha - -.. raw:: html - - - -benchmark_period_return - -.. raw:: html - - - -benchmark_volatility - -.. raw:: html - - - -beta - -.. raw:: html - - - -capital_used - -.. raw:: html - - - -cash - -.. raw:: html - - - -ending_cash - -.. raw:: html - - - -ending_exposure - -.. raw:: html - - - -… - -.. raw:: html - - - -starting_cash - -.. raw:: html - - - -starting_exposure - -.. raw:: html - - - -starting_value - -.. raw:: html - - - -trading_days - -.. raw:: html - - - -transactions - -.. raw:: html - - - -treasury_period_return - -.. raw:: html - - - -volume - -.. raw:: html - - - -treasury - -.. raw:: html - - - -algorithm - -.. raw:: html - - - -benchmark - -.. raw:: html - -
- -2015-03-01 23:59:00+00:00 - -.. raw:: html - - - -NaN - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -NaN - -.. raw:: html - - - -0.045833 - -.. raw:: html - - - -NaN - -.. raw:: html - - - -NaN - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -100000.000000 - -.. raw:: html - - - -100000.000000 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -1 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0200 - -.. raw:: html - - - -317 - -.. raw:: html - - - -0.0200 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -0.045833 - -.. raw:: html - -
- -2015-03-02 23:59:00+00:00 - -.. raw:: html - - - -0.000278 - -.. raw:: html - - - --0.000025 - -.. raw:: html - - - -0.011045 - -.. raw:: html - - - -0.120833 - -.. raw:: html - - - -0.290503 - -.. raw:: html - - - --0.000956 - -.. raw:: html - - - --85544.474955 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -85542.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -2 - -.. raw:: html - - - -[{u’commission’: None, u’amount’: 318, u’sid’:… - -.. raw:: html - - - -0.0208 - -.. raw:: html - - - -98063 - -.. raw:: html - - - -0.0208 - -.. raw:: html - - - --0.000025 - -.. raw:: html - - - -0.120833 - -.. raw:: html - -
- -2015-03-03 23:59:00+00:00 - -.. raw:: html - - - -0.051796 - -.. raw:: html - - - --0.005688 - -.. raw:: html - - - --1.197544 - -.. raw:: html - - - -0.113416 - -.. raw:: html - - - -0.633538 - -.. raw:: html - - - -0.077239 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -84975.642 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -85542.000 - -.. raw:: html - - - -85542.000 - -.. raw:: html - - - -3 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - -442983 - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - --0.005688 - -.. raw:: html - - - -0.113416 - -.. raw:: html - -
- -2015-03-04 23:59:00+00:00 - -.. raw:: html - - - -0.342118 - -.. raw:: html - - - -0.034955 - -.. raw:: html - - - -0.401861 - -.. raw:: html - - - -0.166666 - -.. raw:: html - - - -0.524400 - -.. raw:: html - - - -0.181468 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -89040.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -84975.642 - -.. raw:: html - - - -84975.642 - -.. raw:: html - - - -4 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - -245889 - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - -0.034955 - -.. raw:: html - - - -0.166666 - -.. raw:: html - -
- -2015-03-05 23:59:00+00:00 - -.. raw:: html - - - -0.637226 - -.. raw:: html - - - --0.038185 - -.. raw:: html - - - --3.914003 - -.. raw:: html - - - -0.070834 - -.. raw:: html - - - -0.976896 - -.. raw:: html - - - -0.550520 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -81726.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -89040.000 - -.. raw:: html - - - -89040.000 - -.. raw:: html - - - -5 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0211 - -.. raw:: html - - - -117440 - -.. raw:: html - - - -0.0211 - -.. raw:: html - - - --0.038185 - -.. raw:: html - - - -0.070834 - -.. raw:: html - -
- -2015-03-06 23:59:00+00:00 - -.. raw:: html - - - -0.580521 - -.. raw:: html - - - --0.028645 - -.. raw:: html - - - --3.100822 - -.. raw:: html - - - -0.083333 - -.. raw:: html - - - -0.874082 - -.. raw:: html - - - -0.546703 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -81726.000 - -.. raw:: html - - - -81726.000 - -.. raw:: html - - - -6 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0224 - -.. raw:: html - - - -84197 - -.. raw:: html - - - -0.0224 - -.. raw:: html - - - --0.028645 - -.. raw:: html - - - -0.083333 - -.. raw:: html - -
- -2015-03-07 23:59:00+00:00 - -.. raw:: html - - - -0.530557 - -.. raw:: html - - - --0.028645 - -.. raw:: html - - - --2.625704 - -.. raw:: html - - - -0.083333 - -.. raw:: html - - - -0.802793 - -.. raw:: html - - - -0.536589 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -7 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0224 - -.. raw:: html - - - -181 - -.. raw:: html - - - -0.0224 - -.. raw:: html - - - --0.028645 - -.. raw:: html - - - -0.083333 - -.. raw:: html - -
- -2015-03-08 23:59:00+00:00 - -.. raw:: html - - - -0.491628 - -.. raw:: html - - - --0.028645 - -.. raw:: html - - - --2.276841 - -.. raw:: html - - - -0.083333 - -.. raw:: html - - - -0.746605 - -.. raw:: html - - - -0.529163 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -8 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0224 - -.. raw:: html - - - -30900 - -.. raw:: html - - - -0.0224 - -.. raw:: html - - - --0.028645 - -.. raw:: html - - - -0.083333 - -.. raw:: html - -
- -2015-03-09 23:59:00+00:00 - -.. raw:: html - - - -0.467885 - -.. raw:: html - - - --0.015925 - -.. raw:: html - - - --1.895269 - -.. raw:: html - - - -0.100000 - -.. raw:: html - - - -0.698764 - -.. raw:: html - - - -0.532652 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -83952.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -82680.000 - -.. raw:: html - - - -9 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0220 - -.. raw:: html - - - -128367 - -.. raw:: html - - - -0.0220 - -.. raw:: html - - - --0.015925 - -.. raw:: html - - - -0.100000 - -.. raw:: html - -
- -2015-03-10 23:59:00+00:00 - -.. raw:: html - - - -0.626552 - -.. raw:: html - - - -0.069935 - -.. raw:: html - - - --1.625285 - -.. raw:: html - - - -0.212500 - -.. raw:: html - - - -0.800983 - -.. raw:: html - - - -0.676289 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -92538.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -83952.000 - -.. raw:: html - - - -83952.000 - -.. raw:: html - - - -10 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0214 - -.. raw:: html - - - -54961 - -.. raw:: html - - - -0.0214 - -.. raw:: html - - - -0.069935 - -.. raw:: html - - - -0.212500 - -.. raw:: html - -
- -2015-03-11 23:59:00+00:00 - -.. raw:: html - - - -0.644515 - -.. raw:: html - - - -0.022235 - -.. raw:: html - - - --1.727710 - -.. raw:: html - - - -0.150000 - -.. raw:: html - - - -0.834650 - -.. raw:: html - - - -0.684052 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -87768.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -92538.000 - -.. raw:: html - - - -92538.000 - -.. raw:: html - - - -11 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0211 - -.. raw:: html - - - -42511 - -.. raw:: html - - - -0.0211 - -.. raw:: html - - - -0.022235 - -.. raw:: html - - - -0.150000 - -.. raw:: html - -
- -2015-03-12 23:59:00+00:00 - -.. raw:: html - - - -0.614650 - -.. raw:: html - - - -0.022235 - -.. raw:: html - - - --1.573455 - -.. raw:: html - - - -0.150000 - -.. raw:: html - - - -0.798403 - -.. raw:: html - - - -0.680882 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -87768.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -87768.000 - -.. raw:: html - - - -87768.000 - -.. raw:: html - - - -12 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0210 - -.. raw:: html - - - -2909 - -.. raw:: html - - - -0.0210 - -.. raw:: html - - - -0.022235 - -.. raw:: html - - - -0.150000 - -.. raw:: html - -
- -2015-03-13 23:59:00+00:00 - -.. raw:: html - - - -0.588942 - -.. raw:: html - - - -0.019405 - -.. raw:: html - - - --1.454733 - -.. raw:: html - - - -0.146291 - -.. raw:: html - - - -0.767688 - -.. raw:: html - - - -0.677881 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -87484.980 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -87768.000 - -.. raw:: html - - - -87768.000 - -.. raw:: html - - - -13 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0213 - -.. raw:: html - - - -57613 - -.. raw:: html - - - -0.0213 - -.. raw:: html - - - -0.019405 - -.. raw:: html - - - -0.146291 - -.. raw:: html - -
- -2015-03-14 23:59:00+00:00 - -.. raw:: html - - - -0.565911 - -.. raw:: html - - - -0.019373 - -.. raw:: html - - - --1.344915 - -.. raw:: html - - - -0.146250 - -.. raw:: html - - - -0.739230 - -.. raw:: html - - - -0.675665 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -87481.800 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -87484.980 - -.. raw:: html - - - -87484.980 - -.. raw:: html - - - -14 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0213 - -.. raw:: html - - - -48310 - -.. raw:: html - - - -0.0213 - -.. raw:: html - - - -0.019373 - -.. raw:: html - - - -0.146250 - -.. raw:: html - -
- -2015-03-15 23:59:00+00:00 - -.. raw:: html - - - -0.551394 - -.. raw:: html - - - -0.041659 - -.. raw:: html - - - --1.191436 - -.. raw:: html - - - -0.175450 - -.. raw:: html - - - -0.714876 - -.. raw:: html - - - -0.680484 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -89710.344 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -87481.800 - -.. raw:: html - - - -87481.800 - -.. raw:: html - - - -15 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0213 - -.. raw:: html - - - -29454 - -.. raw:: html - - - -0.0213 - -.. raw:: html - - - -0.041659 - -.. raw:: html - - - -0.175450 - -.. raw:: html - -
- -2015-03-16 23:59:00+00:00 - -.. raw:: html - - - -0.541846 - -.. raw:: html - - - -0.019055 - -.. raw:: html - - - --1.188212 - -.. raw:: html - - - -0.145833 - -.. raw:: html - - - -0.706049 - -.. raw:: html - - - -0.680281 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -87450.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -89710.344 - -.. raw:: html - - - -89710.344 - -.. raw:: html - - - -16 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0210 - -.. raw:: html - - - -25564 - -.. raw:: html - - - -0.0210 - -.. raw:: html - - - -0.019055 - -.. raw:: html - - - -0.145833 - -.. raw:: html - -
- -2015-03-17 23:59:00+00:00 - -.. raw:: html - - - -0.524682 - -.. raw:: html - - - -0.019055 - -.. raw:: html - - - --1.115149 - -.. raw:: html - - - -0.145833 - -.. raw:: html - - - -0.684599 - -.. raw:: html - - - -0.678870 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -87450.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -87450.000 - -.. raw:: html - - - -87450.000 - -.. raw:: html - - - -17 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0206 - -.. raw:: html - - - -9 - -.. raw:: html - - - -0.0206 - -.. raw:: html - - - -0.019055 - -.. raw:: html - - - -0.145833 - -.. raw:: html - -
- -2015-03-18 23:59:00+00:00 - -.. raw:: html - - - -0.532621 - -.. raw:: html - - - --0.021999 - -.. raw:: html - - - --1.180440 - -.. raw:: html - - - -0.092041 - -.. raw:: html - - - -0.696261 - -.. raw:: html - - - -0.685307 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -83344.620 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -87450.000 - -.. raw:: html - - - -87450.000 - -.. raw:: html - - - -18 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - -164911 - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - --0.021999 - -.. raw:: html - - - -0.092041 - -.. raw:: html - -
- -2015-03-19 23:59:00+00:00 - -.. raw:: html - - - -0.518811 - -.. raw:: html - - - --0.013234 - -.. raw:: html - - - --1.096387 - -.. raw:: html - - - -0.103526 - -.. raw:: html - - - -0.676861 - -.. raw:: html - - - -0.686186 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -84221.028 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -83344.620 - -.. raw:: html - - - -83344.620 - -.. raw:: html - - - -19 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0198 - -.. raw:: html - - - -713904 - -.. raw:: html - - - -0.0198 - -.. raw:: html - - - --0.013234 - -.. raw:: html - - - -0.103526 - -.. raw:: html - -
- -2015-03-20 23:59:00+00:00 - -.. raw:: html - - - -0.505168 - -.. raw:: html - - - --0.017324 - -.. raw:: html - - - --1.050273 - -.. raw:: html - - - -0.098170 - -.. raw:: html - - - -0.659945 - -.. raw:: html - - - -0.685070 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -83812.080 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -84221.028 - -.. raw:: html - - - -84221.028 - -.. raw:: html - - - -20 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - -132725 - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - --0.017324 - -.. raw:: html - - - -0.098170 - -.. raw:: html - -
- -2015-03-21 23:59:00+00:00 - -.. raw:: html - - - -0.492384 - -.. raw:: html - - - --0.018494 - -.. raw:: html - - - --1.002051 - -.. raw:: html - - - -0.096637 - -.. raw:: html - - - -0.643679 - -.. raw:: html - - - -0.684283 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -83695.056 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -83812.080 - -.. raw:: html - - - -83812.080 - -.. raw:: html - - - -21 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - -201155 - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - --0.018494 - -.. raw:: html - - - -0.096637 - -.. raw:: html - -
- -2015-03-22 23:59:00+00:00 - -.. raw:: html - - - -0.482998 - -.. raw:: html - - - --0.004744 - -.. raw:: html - - - --0.927947 - -.. raw:: html - - - -0.114653 - -.. raw:: html - - - -0.629319 - -.. raw:: html - - - -0.686478 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -85070.088 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -83695.056 - -.. raw:: html - - - -83695.056 - -.. raw:: html - - - -22 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - -64378 - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - --0.004744 - -.. raw:: html - - - -0.114653 - -.. raw:: html - -
- -2015-03-23 23:59:00+00:00 - -.. raw:: html - - - -0.477523 - -.. raw:: html - - - --0.026505 - -.. raw:: html - - - --0.935352 - -.. raw:: html - - - -0.086139 - -.. raw:: html - - - -0.623502 - -.. raw:: html - - - -0.687025 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -82894.014 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -85070.088 - -.. raw:: html - - - -85070.088 - -.. raw:: html - - - -23 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0192 - -.. raw:: html - - - -61850 - -.. raw:: html - - - -0.0192 - -.. raw:: html - - - --0.026505 - -.. raw:: html - - - -0.086139 - -.. raw:: html - -
- -2015-03-24 23:59:00+00:00 - -.. raw:: html - - - -0.504086 - -.. raw:: html - - - --0.084215 - -.. raw:: html - - - --1.021023 - -.. raw:: html - - - -0.010523 - -.. raw:: html - - - -0.655188 - -.. raw:: html - - - -0.701025 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -77122.950 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -82894.014 - -.. raw:: html - - - -82894.014 - -.. raw:: html - - - -24 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0188 - -.. raw:: html - - - -490180 - -.. raw:: html - - - -0.0188 - -.. raw:: html - - - --0.084215 - -.. raw:: html - - - -0.010523 - -.. raw:: html - -
- -2015-03-25 23:59:00+00:00 - -.. raw:: html - - - -0.497690 - -.. raw:: html - - - --0.068474 - -.. raw:: html - - - --0.952786 - -.. raw:: html - - - -0.031148 - -.. raw:: html - - - -0.644272 - -.. raw:: html - - - -0.704251 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -78697.050 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -77122.950 - -.. raw:: html - - - -77122.950 - -.. raw:: html - - - -25 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - -90862 - -.. raw:: html - - - -0.0193 - -.. raw:: html - - - --0.068474 - -.. raw:: html - - - -0.031148 - -.. raw:: html - -
- -2015-03-26 23:59:00+00:00 - -.. raw:: html - - - -0.489730 - -.. raw:: html - - - --0.084215 - -.. raw:: html - - - --0.943240 - -.. raw:: html - - - -0.010523 - -.. raw:: html - - - -0.634965 - -.. raw:: html - - - -0.703738 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -77122.950 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -78697.050 - -.. raw:: html - - - -78697.050 - -.. raw:: html - - - -26 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0201 - -.. raw:: html - - - -2299 - -.. raw:: html - - - -0.0201 - -.. raw:: html - - - --0.084215 - -.. raw:: html - - - -0.010523 - -.. raw:: html - -
- -2015-03-27 23:59:00+00:00 - -.. raw:: html - - - -0.495916 - -.. raw:: html - - - --0.049785 - -.. raw:: html - - - --0.857592 - -.. raw:: html - - - -0.055636 - -.. raw:: html - - - -0.636644 - -.. raw:: html - - - -0.713671 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -80565.936 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -77122.950 - -.. raw:: html - - - -77122.950 - -.. raw:: html - - - -27 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0195 - -.. raw:: html - - - -663 - -.. raw:: html - - - -0.0195 - -.. raw:: html - - - --0.049785 - -.. raw:: html - - - -0.055636 - -.. raw:: html - -
- -2015-03-28 23:59:00+00:00 - -.. raw:: html - - - -0.488469 - -.. raw:: html - - - --0.064490 - -.. raw:: html - - - --0.848769 - -.. raw:: html - - - -0.036368 - -.. raw:: html - - - -0.627920 - -.. raw:: html - - - -0.713212 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -79095.504 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -80565.936 - -.. raw:: html - - - -80565.936 - -.. raw:: html - - - -28 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0195 - -.. raw:: html - - - -7061 - -.. raw:: html - - - -0.0195 - -.. raw:: html - - - --0.064490 - -.. raw:: html - - - -0.036368 - -.. raw:: html - -
- -2015-03-29 23:59:00+00:00 - -.. raw:: html - - - -0.479671 - -.. raw:: html - - - --0.066903 - -.. raw:: html - - - --0.822844 - -.. raw:: html - - - -0.033205 - -.. raw:: html - - - -0.616787 - -.. raw:: html - - - -0.712868 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -78854.142 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -79095.504 - -.. raw:: html - - - -79095.504 - -.. raw:: html - - - -29 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0195 - -.. raw:: html - - - -8526 - -.. raw:: html - - - -0.0195 - -.. raw:: html - - - --0.066903 - -.. raw:: html - - - -0.033205 - -.. raw:: html - -
- -2015-03-30 23:59:00+00:00 - -.. raw:: html - - - -0.476306 - -.. raw:: html - - - --0.046605 - -.. raw:: html - - - --0.769239 - -.. raw:: html - - - -0.059803 - -.. raw:: html - - - -0.610002 - -.. raw:: html - - - -0.716464 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -80883.936 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -78854.142 - -.. raw:: html - - - -78854.142 - -.. raw:: html - - - -30 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0196 - -.. raw:: html - - - -29654 - -.. raw:: html - - - -0.0196 - -.. raw:: html - - - --0.046605 - -.. raw:: html - - - -0.059803 - -.. raw:: html - -
- -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - - - -… - -.. raw:: html - -
- -2017-05-30 23:59:00+00:00 - -.. raw:: html - - - -0.495432 - -.. raw:: html - - - -5.949752 - -.. raw:: html - - - --0.016611 - -.. raw:: html - - - -7.916664 - -.. raw:: html - - - -0.554369 - -.. raw:: html - - - -0.888883 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -680519.682 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -701826.000 - -.. raw:: html - - - -701826.000 - -.. raw:: html - - - -822 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -40157964723 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -5.949752 - -.. raw:: html - - - -7.916664 - -.. raw:: html - -
- -2017-05-31 23:59:00+00:00 - -.. raw:: html - - - -0.495243 - -.. raw:: html - - - -6.102328 - -.. raw:: html - - - --0.017086 - -.. raw:: html - - - -8.154164 - -.. raw:: html - - - -0.554182 - -.. raw:: html - - - -0.888844 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -695777.322 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -680519.682 - -.. raw:: html - - - -680519.682 - -.. raw:: html - - - -823 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -31098652109 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -6.102328 - -.. raw:: html - - - -8.154164 - -.. raw:: html - -
- -2017-06-01 23:59:00+00:00 - -.. raw:: html - - - -0.495836 - -.. raw:: html - - - -6.504967 - -.. raw:: html - - - --0.014668 - -.. raw:: html - - - -8.644144 - -.. raw:: html - - - -0.554541 - -.. raw:: html - - - -0.889303 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -736041.210 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -695777.322 - -.. raw:: html - - - -695777.322 - -.. raw:: html - - - -824 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -40944880757 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -6.504967 - -.. raw:: html - - - -8.644144 - -.. raw:: html - -
- -2017-06-02 23:59:00+00:00 - -.. raw:: html - - - -0.495948 - -.. raw:: html - - - -6.801995 - -.. raw:: html - - - --0.013641 - -.. raw:: html - - - -9.033331 - -.. raw:: html - - - -0.554581 - -.. raw:: html - - - -0.889440 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -765744.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -736041.210 - -.. raw:: html - - - -736041.210 - -.. raw:: html - - - -825 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -22364557424 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -6.801995 - -.. raw:: html - - - -9.033331 - -.. raw:: html - -
- -2017-06-03 23:59:00+00:00 - -.. raw:: html - - - -0.495729 - -.. raw:: html - - - -6.952409 - -.. raw:: html - - - --0.013100 - -.. raw:: html - - - -9.230418 - -.. raw:: html - - - -0.554317 - -.. raw:: html - - - -0.889470 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -780785.400 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -765744.000 - -.. raw:: html - - - -765744.000 - -.. raw:: html - - - -826 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -23687278961 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -6.952409 - -.. raw:: html - - - -9.230418 - -.. raw:: html - -
- -2017-06-04 23:59:00+00:00 - -.. raw:: html - - - -0.495450 - -.. raw:: html - - - -7.042244 - -.. raw:: html - - - --0.012768 - -.. raw:: html - - - -9.348122 - -.. raw:: html - - - -0.553999 - -.. raw:: html - - - -0.889479 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -789768.900 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -780785.400 - -.. raw:: html - - - -780785.400 - -.. raw:: html - - - -827 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -21332021248 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -7.042244 - -.. raw:: html - - - -9.348122 - -.. raw:: html - -
- -2017-06-05 23:59:00+00:00 - -.. raw:: html - - - -0.496148 - -.. raw:: html - - - -7.524987 - -.. raw:: html - - - --0.011320 - -.. raw:: html - - - -9.980649 - -.. raw:: html - - - -0.554578 - -.. raw:: html - - - -0.889805 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -838043.208 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -789768.900 - -.. raw:: html - - - -789768.900 - -.. raw:: html - - - -828 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0218 - -.. raw:: html - - - -22372229837 - -.. raw:: html - - - -0.0218 - -.. raw:: html - - - -7.524987 - -.. raw:: html - - - -9.980649 - -.. raw:: html - -
- -2017-06-06 23:59:00+00:00 - -.. raw:: html - - - -0.497592 - -.. raw:: html - - - -8.194835 - -.. raw:: html - - - --0.009554 - -.. raw:: html - - - -10.858330 - -.. raw:: html - - - -0.555841 - -.. raw:: html - - - -0.890368 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -905028.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -838043.208 - -.. raw:: html - - - -838043.208 - -.. raw:: html - - - -829 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0214 - -.. raw:: html - - - -81923184446 - -.. raw:: html - - - -0.0214 - -.. raw:: html - - - -8.194835 - -.. raw:: html - - - -10.858330 - -.. raw:: html - -
- -2017-06-07 23:59:00+00:00 - -.. raw:: html - - - -0.498895 - -.. raw:: html - - - -7.557258 - -.. raw:: html - - - --0.011975 - -.. raw:: html - - - -10.022932 - -.. raw:: html - - - -0.557003 - -.. raw:: html - - - -0.890845 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -841270.272 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -905028.000 - -.. raw:: html - - - -905028.000 - -.. raw:: html - - - -830 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0218 - -.. raw:: html - - - -49070430356 - -.. raw:: html - - - -0.0218 - -.. raw:: html - - - -7.557258 - -.. raw:: html - - - -10.022932 - -.. raw:: html - -
- -2017-06-08 23:59:00+00:00 - -.. raw:: html - - - -0.499349 - -.. raw:: html - - - -8.010395 - -.. raw:: html - - - --0.010676 - -.. raw:: html - - - -10.616664 - -.. raw:: html - - - -0.557357 - -.. raw:: html - - - -0.891092 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -886584.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -841270.272 - -.. raw:: html - - - -841270.272 - -.. raw:: html - - - -831 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0219 - -.. raw:: html - - - -34013412940 - -.. raw:: html - - - -0.0219 - -.. raw:: html - - - -8.010395 - -.. raw:: html - - - -10.616664 - -.. raw:: html - -
- -2017-06-09 23:59:00+00:00 - -.. raw:: html - - - -0.499063 - -.. raw:: html - - - -8.099750 - -.. raw:: html - - - --0.010386 - -.. raw:: html - - - -10.733746 - -.. raw:: html - - - -0.557033 - -.. raw:: html - - - -0.891098 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -895519.482 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -886584.000 - -.. raw:: html - - - -886584.000 - -.. raw:: html - - - -832 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -25275425996 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -8.099750 - -.. raw:: html - - - -10.733746 - -.. raw:: html - -
- -2017-06-10 23:59:00+00:00 - -.. raw:: html - - - -0.498769 - -.. raw:: html - - - -8.086143 - -.. raw:: html - - - --0.010416 - -.. raw:: html - - - -10.715915 - -.. raw:: html - - - -0.556705 - -.. raw:: html - - - -0.891098 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -894158.760 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -895519.482 - -.. raw:: html - - - -895519.482 - -.. raw:: html - - - -833 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -30620792046 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -8.086143 - -.. raw:: html - - - -10.715915 - -.. raw:: html - -
- -2017-06-11 23:59:00+00:00 - -.. raw:: html - - - -0.498971 - -.. raw:: html - - - -8.484533 - -.. raw:: html - - - --0.009305 - -.. raw:: html - - - -11.237914 - -.. raw:: html - - - -0.556827 - -.. raw:: html - - - -0.891266 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -933997.800 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -894158.760 - -.. raw:: html - - - -894158.760 - -.. raw:: html - - - -834 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -30830678595 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -8.484533 - -.. raw:: html - - - -11.237914 - -.. raw:: html - -
- -2017-06-12 23:59:00+00:00 - -.. raw:: html - - - -0.503448 - -.. raw:: html - - - -7.320494 - -.. raw:: html - - - --0.014065 - -.. raw:: html - - - -9.712706 - -.. raw:: html - - - -0.560936 - -.. raw:: html - - - -0.892695 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -817593.900 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -933997.800 - -.. raw:: html - - - -933997.800 - -.. raw:: html - - - -835 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -88704710635 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -7.320494 - -.. raw:: html - - - -9.712706 - -.. raw:: html - -
- -2017-06-13 23:59:00+00:00 - -.. raw:: html - - - -0.503565 - -.. raw:: html - - - -7.656697 - -.. raw:: html - - - --0.013054 - -.. raw:: html - - - -10.153225 - -.. raw:: html - - - -0.560981 - -.. raw:: html - - - -0.892830 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -851214.132 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -817593.900 - -.. raw:: html - - - -817593.900 - -.. raw:: html - - - -836 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -42251296767 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -7.656697 - -.. raw:: html - - - -10.153225 - -.. raw:: html - -
- -2017-06-14 23:59:00+00:00 - -.. raw:: html - - - -0.506845 - -.. raw:: html - - - -6.734516 - -.. raw:: html - - - --0.016873 - -.. raw:: html - - - -8.944917 - -.. raw:: html - - - -0.563995 - -.. raw:: html - - - -0.893862 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -758996.040 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -851214.132 - -.. raw:: html - - - -851214.132 - -.. raw:: html - - - -837 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -63183088135 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -6.734516 - -.. raw:: html - - - -8.944917 - -.. raw:: html - -
- -2017-06-15 23:59:00+00:00 - -.. raw:: html - - - -0.506562 - -.. raw:: html - - - -6.695367 - -.. raw:: html - - - --0.016991 - -.. raw:: html - - - -8.893622 - -.. raw:: html - - - -0.563678 - -.. raw:: html - - - -0.893865 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -755081.142 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -758996.040 - -.. raw:: html - - - -758996.040 - -.. raw:: html - - - -838 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -104677533974 - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -6.695367 - -.. raw:: html - - - -8.893622 - -.. raw:: html - -
- -2017-06-16 23:59:00+00:00 - -.. raw:: html - - - -0.506404 - -.. raw:: html - - - -6.887855 - -.. raw:: html - - - --0.016343 - -.. raw:: html - - - -9.145831 - -.. raw:: html - - - -0.563472 - -.. raw:: html - - - -0.893913 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -774330.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -755081.142 - -.. raw:: html - - - -755081.142 - -.. raw:: html - - - -839 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -43479966625 - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -6.887855 - -.. raw:: html - - - -9.145831 - -.. raw:: html - -
- -2017-06-17 23:59:00+00:00 - -.. raw:: html - - - -0.507407 - -.. raw:: html - - - -7.435283 - -.. raw:: html - - - --0.014812 - -.. raw:: html - - - -9.863113 - -.. raw:: html - - - -0.564341 - -.. raw:: html - - - -0.894311 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -829072.746 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -774330.000 - -.. raw:: html - - - -774330.000 - -.. raw:: html - - - -840 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -36800919715 - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -7.435283 - -.. raw:: html - - - -9.863113 - -.. raw:: html - -
- -2017-06-18 23:59:00+00:00 - -.. raw:: html - - - -0.507740 - -.. raw:: html - - - -7.070069 - -.. raw:: html - - - --0.016112 - -.. raw:: html - - - -9.384581 - -.. raw:: html - - - -0.564605 - -.. raw:: html - - - -0.894482 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -792551.400 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -829072.746 - -.. raw:: html - - - -829072.746 - -.. raw:: html - - - -841 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -46411759478 - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -7.070069 - -.. raw:: html - - - -9.384581 - -.. raw:: html - -
- -2017-06-19 23:59:00+00:00 - -.. raw:: html - - - -0.507754 - -.. raw:: html - - - -7.358645 - -.. raw:: html - - - --0.015226 - -.. raw:: html - - - -9.762694 - -.. raw:: html - - - -0.564557 - -.. raw:: html - - - -0.894583 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -821408.946 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -792551.400 - -.. raw:: html - - - -792551.400 - -.. raw:: html - - - -842 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0219 - -.. raw:: html - - - -28294406623 - -.. raw:: html - - - -0.0219 - -.. raw:: html - - - -7.358645 - -.. raw:: html - - - -9.762694 - -.. raw:: html - -
- -2017-06-20 23:59:00+00:00 - -.. raw:: html - - - -0.507705 - -.. raw:: html - - - -7.628795 - -.. raw:: html - - - --0.014414 - -.. raw:: html - - - -10.116664 - -.. raw:: html - - - -0.564451 - -.. raw:: html - - - -0.894665 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -848424.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -821408.946 - -.. raw:: html - - - -821408.946 - -.. raw:: html - - - -843 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -36903854052 - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -7.628795 - -.. raw:: html - - - -10.116664 - -.. raw:: html - -
- -2017-06-21 23:59:00+00:00 - -.. raw:: html - - - -0.507531 - -.. raw:: html - - - -7.476155 - -.. raw:: html - - - --0.014900 - -.. raw:: html - - - -9.916664 - -.. raw:: html - - - -0.564238 - -.. raw:: html - - - -0.894696 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -833160.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -848424.000 - -.. raw:: html - - - -848424.000 - -.. raw:: html - - - -844 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -43815656010 - -.. raw:: html - - - -0.0216 - -.. raw:: html - - - -7.476155 - -.. raw:: html - - - -9.916664 - -.. raw:: html - -
- -2017-06-22 23:59:00+00:00 - -.. raw:: html - - - -0.507315 - -.. raw:: html - - - -7.645891 - -.. raw:: html - - - --0.014372 - -.. raw:: html - - - -10.139065 - -.. raw:: html - - - -0.563979 - -.. raw:: html - - - -0.894725 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -850133.568 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -833160.000 - -.. raw:: html - - - -833160.000 - -.. raw:: html - - - -845 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -22304647568 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -7.645891 - -.. raw:: html - - - -10.139065 - -.. raw:: html - -
- -2017-06-23 23:59:00+00:00 - -.. raw:: html - - - -0.507020 - -.. raw:: html - - - -7.635155 - -.. raw:: html - - - --0.014388 - -.. raw:: html - - - -10.124997 - -.. raw:: html - - - -0.563652 - -.. raw:: html - - - -0.894725 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -849060.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -850133.568 - -.. raw:: html - - - -850133.568 - -.. raw:: html - - - -846 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -13090231864 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -7.635155 - -.. raw:: html - - - -10.124997 - -.. raw:: html - -
- -2017-06-24 23:59:00+00:00 - -.. raw:: html - - - -0.507936 - -.. raw:: html - - - -7.105628 - -.. raw:: html - - - --0.016304 - -.. raw:: html - - - -9.431173 - -.. raw:: html - - - -0.564463 - -.. raw:: html - - - -0.895061 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -796107.276 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -849060.000 - -.. raw:: html - - - -849060.000 - -.. raw:: html - - - -847 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -34088563732 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -7.105628 - -.. raw:: html - - - -9.431173 - -.. raw:: html - -
- -2017-06-25 23:59:00+00:00 - -.. raw:: html - - - -0.507675 - -.. raw:: html - - - -7.036714 - -.. raw:: html - - - --0.016515 - -.. raw:: html - - - -9.340880 - -.. raw:: html - - - -0.564168 - -.. raw:: html - - - -0.895069 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -789215.898 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -796107.276 - -.. raw:: html - - - -796107.276 - -.. raw:: html - - - -848 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -41560204433 - -.. raw:: html - - - -0.0215 - -.. raw:: html - - - -7.036714 - -.. raw:: html - - - -9.340880 - -.. raw:: html - -
- -2017-06-26 23:59:00+00:00 - -.. raw:: html - - - -0.507780 - -.. raw:: html - - - -6.761571 - -.. raw:: html - - - --0.017485 - -.. raw:: html - - - -8.980368 - -.. raw:: html - - - -0.564221 - -.. raw:: html - - - -0.895175 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -761701.584 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -789215.898 - -.. raw:: html - - - -789215.898 - -.. raw:: html - - - -849 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0214 - -.. raw:: html - - - -73840480752 - -.. raw:: html - - - -0.0214 - -.. raw:: html - - - -6.761571 - -.. raw:: html - - - -8.980368 - -.. raw:: html - -
- -2017-06-27 23:59:00+00:00 - -.. raw:: html - - - -0.508048 - -.. raw:: html - - - -7.126355 - -.. raw:: html - - - --0.016390 - -.. raw:: html - - - -9.458331 - -.. raw:: html - - - -0.564409 - -.. raw:: html - - - -0.895349 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -798180.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -761701.584 - -.. raw:: html - - - -761701.584 - -.. raw:: html - - - -850 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -62426319778 - -.. raw:: html - - - -0.0221 - -.. raw:: html - - - -7.126355 - -.. raw:: html - - - -9.458331 - -.. raw:: html - -
- -2017-06-28 23:59:00+00:00 - -.. raw:: html - - - -0.507750 - -.. raw:: html - - - -7.135895 - -.. raw:: html - - - --0.016340 - -.. raw:: html - - - -9.470831 - -.. raw:: html - - - -0.564078 - -.. raw:: html - - - -0.895349 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -799134.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -798180.000 - -.. raw:: html - - - -798180.000 - -.. raw:: html - - - -851 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0222 - -.. raw:: html - - - -39676839183 - -.. raw:: html - - - -0.0222 - -.. raw:: html - - - -7.135895 - -.. raw:: html - - - -9.470831 - -.. raw:: html - -
- -.. raw:: html - -

- -851 rows × 45 columns - -.. raw:: html - -

- -.. raw:: html - -
- -Also, instead of defining an output file we are accessing it via the “_" -variable that will be created in the name space and contain the -performance DataFrame. - -.. code:: python - - _.head() - -.. raw:: html - -
- -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - - - -.. raw:: html - -
- -.. raw:: html - - - -algo_volatility - -.. raw:: html - - - -algorithm_period_return - -.. raw:: html - - - -alpha - -.. raw:: html - - - -benchmark_period_return - -.. raw:: html - - - -benchmark_volatility - -.. raw:: html - - - -beta - -.. raw:: html - - - -capital_used - -.. raw:: html - - - -cash - -.. raw:: html - - - -ending_cash - -.. raw:: html - - - -ending_exposure - -.. raw:: html - - - -… - -.. raw:: html - - - -starting_cash - -.. raw:: html - - - -starting_exposure - -.. raw:: html - - - -starting_value - -.. raw:: html - - - -trading_days - -.. raw:: html - - - -transactions - -.. raw:: html - - - -treasury_period_return - -.. raw:: html - - - -volume - -.. raw:: html - - - -treasury - -.. raw:: html - - - -algorithm - -.. raw:: html - - - -benchmark - -.. raw:: html - -
- -2015-03-01 23:59:00+00:00 - -.. raw:: html - - - -NaN - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -NaN - -.. raw:: html - - - -0.045833 - -.. raw:: html - - - -NaN - -.. raw:: html - - - -NaN - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -100000.000000 - -.. raw:: html - - - -100000.000000 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -1 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0200 - -.. raw:: html - - - -317 - -.. raw:: html - - - -0.0200 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -0.045833 - -.. raw:: html - -
- -2015-03-02 23:59:00+00:00 - -.. raw:: html - - - -0.000278 - -.. raw:: html - - - --0.000025 - -.. raw:: html - - - -0.011045 - -.. raw:: html - - - -0.120833 - -.. raw:: html - - - -0.290503 - -.. raw:: html - - - --0.000956 - -.. raw:: html - - - --85544.474955 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -85542.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -0.000 - -.. raw:: html - - - -2 - -.. raw:: html - - - -[{u’commission’: None, u’amount’: 318, u’sid’:… - -.. raw:: html - - - -0.0208 - -.. raw:: html - - - -98063 - -.. raw:: html - - - -0.0208 - -.. raw:: html - - - --0.000025 - -.. raw:: html - - - -0.120833 - -.. raw:: html - -
- -2015-03-03 23:59:00+00:00 - -.. raw:: html - - - -0.051796 - -.. raw:: html - - - --0.005688 - -.. raw:: html - - - --1.197544 - -.. raw:: html - - - -0.113416 - -.. raw:: html - - - -0.633538 - -.. raw:: html - - - -0.077239 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -84975.642 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -85542.000 - -.. raw:: html - - - -85542.000 - -.. raw:: html - - - -3 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - -442983 - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - --0.005688 - -.. raw:: html - - - -0.113416 - -.. raw:: html - -
- -2015-03-04 23:59:00+00:00 - -.. raw:: html - - - -0.342118 - -.. raw:: html - - - -0.034955 - -.. raw:: html - - - -0.401861 - -.. raw:: html - - - -0.166666 - -.. raw:: html - - - -0.524400 - -.. raw:: html - - - -0.181468 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -89040.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -84975.642 - -.. raw:: html - - - -84975.642 - -.. raw:: html - - - -4 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - -245889 - -.. raw:: html - - - -0.0212 - -.. raw:: html - - - -0.034955 - -.. raw:: html - - - -0.166666 - -.. raw:: html - -
- -2015-03-05 23:59:00+00:00 - -.. raw:: html - - - -0.637226 - -.. raw:: html - - - --0.038185 - -.. raw:: html - - - --3.914003 - -.. raw:: html - - - -0.070834 - -.. raw:: html - - - -0.976896 - -.. raw:: html - - - -0.550520 - -.. raw:: html - - - -0.000000 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -14455.525045 - -.. raw:: html - - - -81726.000 - -.. raw:: html - - - -… - -.. raw:: html - - - -100000.0 - -.. raw:: html - - - -89040.000 - -.. raw:: html - - - -89040.000 - -.. raw:: html - - - -5 - -.. raw:: html - - - -[] - -.. raw:: html - - - -0.0211 - -.. raw:: html - - - -117440 - -.. raw:: html - - - -0.0211 - -.. raw:: html - - - --0.038185 - -.. raw:: html - - - -0.070834 - -.. raw:: html - -
- -.. raw:: html - -

- -5 rows × 45 columns - -.. raw:: html - -

- -.. raw:: html - -
- - - -Next steps -~~~~~~~~~~ - -We hope that this tutorial gave you a little insight into the -architecture, API, and features of Catalyst. For next steps, check -out some of the other :doc:`example algorithms`. - -Feel free to ask questions on the ``#catalyst_dev`` channel of our -`Discord group `__ and report -problems on our `GitHub issue tracker `__. diff --git a/_sources/bundles.rst.txt b/_sources/bundles.rst.txt deleted file mode 100644 index 6fd8c1fb..00000000 --- a/_sources/bundles.rst.txt +++ /dev/null @@ -1,354 +0,0 @@ -.. _data-bundles: - -Data Bundles ------------- - -A data bundle is a collection of pricing data, adjustment data, and an asset -database. Bundles allow us to preload all of the data we will need to run -backtests and store the data for future runs. - -.. _bundles-command: - -Discovering Available Bundles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Zipline comes with a few bundles by default as well as the ability to register -new bundles. To see which bundles we have have available, we may run the -``bundles`` command, for example: - -.. code-block:: bash - - $ zipline bundles - my-custom-bundle 2016-05-05 20:35:19.809398 - my-custom-bundle 2016-05-05 20:34:53.654082 - my-custom-bundle 2016-05-05 20:34:48.401767 - quandl - quantopian-quandl 2016-05-05 20:06:40.894956 - -The output here shows that there are 3 bundles available: - -- ``my-custom-bundle`` (added by the user) -- ``quandl`` (provided by zipline) -- ``quantopian-quandl`` (provided by zipline) - -The dates and times next to the name show the times when the data for this -bundle was ingested. We have run three different ingestions for -``my-custom-bundle``. We have never ingested any data for the ``quandl`` bundle -so it just shows ```` instead. Finally, there is only one -ingestion for ``quantopian-quandl``. - -.. _ingesting-data: - -Ingesting Data -~~~~~~~~~~~~~~ - -The first step to using a data bundle is to ingest the data. The ingestion -process will invoke some custom bundle command and then write the data to a -standard location that zipline can find. By default the location where ingested -data will be written is ``$ZIPLINE_ROOT/data/`` where by default -``ZIPLINE_ROOT=~/.zipline``. The ingestion step may take some time as it could -involve downloading and processing a lot of data. This can be run with: - -.. code-block:: bash - - $ zipline ingest [-b ] - - -where ```` is the name of the bundle to ingest, defaulting to -:ref:`quantopian-quandl `. - -Old Data -~~~~~~~~ - -When the ``ingest`` command is used it will write the new data to a subdirectory -of ``$ZIPLINE_ROOT/data/`` which is named with the current date. This -makes it possible to look at older data or even run backtests with the older -copies. Running a backtest with an old ingestion makes it easier to reproduce -backtest results later. - -One drawback of saving all of the data by default is that the data directory -may grow quite large even if you do not want to use the data. As shown earlier, -we can list all of the ingestions with the :ref:`bundles command -`. To solve the problem of leaking old data there is another -command: ``clean``, which will clear data bundles based on some time -constraints. - -For example: - -.. code-block:: bash - - # clean everything older than - $ zipline clean [-b ] --before - - # clean everything newer than - $ zipline clean [-b ] --after - - # keep everything in the range of [before, after] and delete the rest - $ zipline clean [-b ] --before --after - - # clean all but the last runs - $ zipline clean [-b ] --keep-last - - -Running Backtests with Data Bundles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Now that the data has been ingested we can use it to run backtests with the -``run`` command. The bundle to use can be specified with the ``--bundle`` option -like: - -.. code-block:: bash - - $ zipline run --bundle --algofile algo.py ... - - -We may also specify the date to use to look up the bundle data with the -``--bundle-date`` option. Setting the ``--bundle-date`` will cause run to use -the most recent bundle ingestion that is less than or equal to the -``bundle-date``. This is how we can run backtests with older data. The reason -that ``-bundle-date`` uses a less than or equal to relationship is that we can -specify the date that we ran an old backtest and get the same data that would -have been available to us on that date. The ``bundle-date`` defaults to the -current day to use the most recent data. - -Default Data Bundles -~~~~~~~~~~~~~~~~~~~~ - -.. _quandl-data-bundle: - -Quandl WIKI Bundle -`````````````````` - -By default zipline comes with the ``quandl`` data bundle which uses quandl's -`WIKI dataset `_. The quandl data bundle -includes daily pricing data, splits, cash dividends, and asset metadata. To -ingest the ``quandl`` data bundle we recommend creating an account on quandl.com -to get an API key to be able to make more API requests per day. Once we have an -API key we may run: - -.. code-block:: bash - - $ QUANDL_API_KEY= zipline ingest -b quandl - -though we may still run ``ingest`` as an anonymous quandl user (with no API -key). We may also set the ``QUANDL_DOWNLOAD_ATTEMPTS`` environment variable to -an integer which is the number of attempts that should be made to download data -from quandls servers. By default ``QUANDL_DOWNLOAD_ATTEMPTS`` will be 5, meaning -that we will retry each attempt 5 times. - -.. note:: - - ``QUANDL_DOWNLOAD_ATTEMPTS`` is not the total number of allowed failures, - just the number of allowed failures per request. The quandl loader will make - one request per 100 equities for the metadata followed by one request per - equity. - - -.. _quantopian-quandl-mirror: - -Quantopian Quandl WIKI Mirror -''''''''''''''''''''''''''''' - -Quantopian provides a mirror of the quandl WIKI dataset with the data in the -formats that zipline expects. This is available under the name: -``quantopian-quandl`` and is the default bundle for zipline. - -Yahoo Bundle Factories -`````````````````````` - -Zipline also ships with a factory function for creating a data bundle out of a -set of tickers from yahoo: :func:`~zipline.data.bundles.yahoo_equities`. -:func:`~zipline.data.bundles.yahoo_equities` makes it easy to pre-download and -cache the data for a set of equities from yahoo. The yahoo bundles include daily -pricing data along with splits, cash dividends, and inferred asset metadata. To -create a bundle from a set of equities, add the following to your -``~/.zipline/extensions.py`` file: - -.. code-block:: python - - from zipline.data.bundles import register, yahoo_equities - - # these are the tickers you would like data for - equities = { - 'AAPL', - 'MSFT', - 'GOOG', - } - register( - 'my-yahoo-equities-bundle', # name this whatever you like - yahoo_equities(equities), - ) - - -This may now be used like: - -.. code-block:: bash - - $ zipline ingest -b my-yahoo-equities-bundle - $ zipline run -f algo.py --bundle my-yahoo-equities-bundle - - -More than one yahoo equities bundle may be registered as long as they use -different names. - -Writing a New Bundle -~~~~~~~~~~~~~~~~~~~~ - -Data bundles exist to make it easy to use different data sources with -zipline. To add a new bundle, one must implement an ``ingest`` function. - -The ``ingest`` function is responsible for loading the data into memory and -passing it to a set of writer objects provided by zipline to convert the data to -zipline's internal format. The ingest function may work by downloading data from -a remote location like the ``quandl`` bundle or yahoo bundles or it may just -load files that are already on the machine. The function is provided with -writers that will write the data to the correct location transactionally. If an -ingestion fails part way through the bundle will not be written in an incomplete -state. - -The signature of the ingest function should be: - -.. code-block:: python - - ingest(environ, - asset_db_writer, - minute_bar_writer, - daily_bar_writer, - adjustment_writer, - calendar, - start_session, - end_session, - cache, - show_progress, - output_dir) - -``environ`` -``````````` - -``environ`` is a mapping representing the environment variables to use. This is -where any custom arguments needed for the ingestion should be passed, for -example: the ``quandl`` bundle uses the enviornment to pass the API key and the -download retry attempt count. - -``asset_db_writer`` -``````````````````` - -``asset_db_writer`` is an instance of :class:`~zipline.assets.AssetDBWriter`. -This is the writer for the asset metadata which provides the asset lifetimes and -the symbol to asset id (sid) mapping. This may also contain the asset name, -exchange and a few other columns. To write data, invoke -:meth:`~zipline.assets.AssetDBWriter.write` with dataframes for the various -pieces of metadata. More information about the format of the data exists in the -docs for write. - -``minute_bar_writer`` -````````````````````` - -``minute_bar_writer`` is an instance of -:class:`~zipline.data.minute_bars.BcolzMinuteBarWriter`. This writer is used to -convert data to zipline's internal bcolz format to later be read by a -:class:`~zipline.data.minute_bars.BcolzMinuteBarReader`. If minute data is -provided, users should call -:meth:`~zipline.data.minute_bars.BcolzMinuteBarWriter.write` with an iterable of -(sid, dataframe) tuples. The ``show_progress`` argument should also be forwarded -to this method. If the data source does not provide minute level data, then -there is no need to call the write method. It is also acceptable to pass an -empty iterator to :meth:`~zipline.data.minute_bars.BcolzMinuteBarWriter.write` -to signal that there is no minutely data. - -.. note:: - - The data passed to - :meth:`~zipline.data.minute_bars.BcolzMinuteBarWriter.write` may be a lazy - iterator or generator to avoid loading all of the minute data into memory at - a single time. A given sid may also appear multiple times in the data as long - as the dates are strictly increasing. - -``daily_bar_writer`` -```````````````````` - -``daily_bar_writer`` is an instance of -:class:`~zipline.data.us_equity_pricing.BcolzDailyBarWriter`. This writer is -used to convert data into zipline's internal bcolz format to later be read by a -:class:`~zipline.data.us_equity_pricing.BcolzDailyBarReader`. If daily data is -provided, users should call -:meth:`~zipline.data.minute_bars.BcolzDailyBarWriter.write` with an iterable of -(sid dataframe) tuples. The ``show_progress`` argument should also be forwarded -to this method. If the data shource does not provide daily data, then there is -no need to call the write method. It is also acceptable to pass an empty -iterable to :meth:`~zipline.data.minute_bars.BcolzMinuteBarWriter.write` to -signal that there is no daily data. If no daily data is provided but minute data -is provided, a daily rollup will happen to service daily history requests. - -.. note:: - - Like the ``minute_bar_writer``, the data passed to - :meth:`~zipline.data.minute_bars.BcolzMinuteBarWriter.write` may be a lazy - iterable or generator to avoid loading all of the data into memory at once. - Unlike the ``minute_bar_writer``, a sid may only appear once in the data - iterable. - -``adjustment_writer`` -````````````````````` - -``adjustment_writer`` is an instance of -:class:`~zipline.data.us_equity_pricing.SQLiteAdjustmentWriter`. This writer is -used to store splits, mergers, dividends, and stock dividends. The data should -be provided as dataframes and passed to -:meth:`~zipline.data.us_equity_pricing.SQLiteAdjustmentWriter.write`. Each of -these fields are optional, but the writer can accept as much of the data as you -have. - -``calendar`` -```````````` - -``calendar`` is an instance of -:class:`zipline.utils.calendars.TradingCalendar`. The calendar is provided to -help some bundles generate queries for the days needed. - -``start_session`` -````````````````` - -``start_session`` is a :class:`pandas.Timestamp` object indicating the first -day that the bundle should load data for. - -``end_session`` -``````````````` - -``end_session`` is a :class:`pandas.Timestamp` object indicating the last day -that the bundle should load data for. - -``cache`` -````````` - -``cache`` is an instance of :class:`~zipline.utils.cache.dataframe_cache`. This -object is a mapping from strings to dataframes. This object is provided in case -an ingestion crashes part way through. The idea is that the ingest function -should check the cache for raw data, if it doesn't exist in the cache, it should -acquire it and then store it in the cache. Then it can parse and write the -data. The cache will be cleared only after a successful load, this prevents the -ingest function from needing to redownload all the data if there is some bug in -the parsing. If it is very fast to get the data, for example if it is coming -from another local file, then there is no need to use this cache. - -``show_progress`` -````````````````` - -``show_progress`` is a boolean indicating that the user would like to receive -feedback about the ingest function's progress fetching and writing the -data. Some examples for where to show how many files you have downloaded out of -the total needed, or how far into some data conversion the ingest function -is. One tool that may help with implementing ``show_progress`` for a loop is -:class:`~zipline.utils.cli.maybe_show_progress`. This argument should always be -forwarded to ``minute_bar_writer.write`` and ``daily_bar_writer.write``. - - -``output_dir`` -`````````````` - -``output_dir`` is a string representing the file path where all the data will be -written. ``output_dir`` will be some subdirectory of ``$ZIPLINE_ROOT`` and will -contain the time of the start of the current ingestion. This can be used to -directly move resources here if for some reason your ingest function can produce -it's own outputs without the writers. For example, the ``quantopian:quandl`` -bundle uses this to directly untar the bundle into the ``output_dir``. diff --git a/_sources/development-guidelines.rst.txt b/_sources/development-guidelines.rst.txt deleted file mode 100644 index 3adf2a43..00000000 --- a/_sources/development-guidelines.rst.txt +++ /dev/null @@ -1,144 +0,0 @@ -Development Guidelines -====================== -This page is intended for developers of Catalyst, people who want to contribute to the Catalyst codebase or documentation, or people who want to install from source and make local changes to their copy of Catalyst. - -All contributions, bug reports, bug fixes, documentation improvements, enhancements and ideas are welcome. We `track issues `_ on `GitHub `_ and also have a `discord group `_ where you can ask questions. - -Creating a Development Environment ----------------------------------- - -First, you'll need to clone Catalyst by running: - -.. code-block:: bash - - $ git clone git@github.com:enigmampc/catalyst.git - -Then check out to a new branch where you can make your changes: - -.. code-block:: bash - - $ git checkout -b some-short-descriptive-name - -If you don't already have them, you'll need some C library dependencies. You can follow the `install guide `_ to get the appropriate dependencies. - -The following section assumes you already have virtualenvwrapper and pip installed on your system. Suggested installation of Python library dependencies used for development: - -.. code-block:: bash - - $ mkvirtualenv catalyst - $ ./etc/ordered_pip.sh ./etc/requirements.txt - $ pip install -r ./etc/requirements_dev.txt - $ pip install -r ./etc/requirements_blaze.txt - -Finally, you can build the C extensions by running: - -.. code-block:: bash - - $ python setup.py build_ext --inplace - -Development with Docker ------------------------ - -If you want to work with zipline using a `Docker`__ container, you'll need to -build the ``Dockerfile`` in the Zipline root directory, and then build -``Dockerfile-dev``. Instructions for building both containers can be found in -``Dockerfile`` and ``Dockerfile-dev``, respectively. - -__ https://docs.docker.com/get-started/ - -Git Branching Structure ------------------------ - -If you want to contribute to the codebase of Catalyst, familiarize yourself with our branching structure, a fairly standardized one for that matter, that follows what is documented in the following article: `A successful Git branching model `_. To contribute, create your local branch and submit a Pull Request (PR) to the **develop** branch. - -.. image:: https://camo.githubusercontent.com/9bde6fb64a9542a572e0e2017cbb58d9d2c440ac/687474703a2f2f6e7669652e636f6d2f696d672f6769742d6d6f64656c4032782e706e67 - -Contributing to the Docs ------------------------- - -If you'd like to contribute to the documentation on enigmampc.github.io, you can navigate to ``docs/source/`` where each `reStructuredText `_ file is a separate section there. To add a section, create a new file called ``some-descriptive-name.rst`` and add ``some-descriptive-name`` to ``index.rst``. To edit a section, simply open up one of the existing files, make your changes, and save them. - -We use `Sphinx `_ to generate documentation for Catalyst, which you will need to install by running: - -.. code-block:: bash - - $ pip install -r ./etc/requirements_docs.txt - -To build and view the docs locally, run: - -.. code-block:: bash - - # assuming you're in the Catalyst root directory - $ cd docs - $ make html - $ {BROWSER} build/html/index.html - - -There is a `documented issue `_ -with ``sphinx`` and ``docutils`` that causes the error below when trying to build -the docs. - -.. code-block:: text - - Exception occurred: - File "(...)/env-c/lib/python2.7/site-packages/docutils/writers/_html_base.py", line 671, in depart_document - assert not self.context, 'len(context) = %s' % len(self.context) - AssertionError: len(context) = 3 - -If you get this error, you need to downgrade your version of ``docutils`` as -follows, and build the docs again: - -.. code-block:: bash - - $ pip install docutils==0.12 - - -Commit messages ---------------- - -Standard prefixes to start a commit message: - -.. code-block:: text - - BLD: change related to building Catalyst - BUG: bug fix - DEP: deprecate something, or remove a deprecated object - DEV: development tool or utility - DOC: documentation - ENH: enhancement - MAINT: maintenance commit (refactoring, typos, etc) - REV: revert an earlier commit - STY: style fix (whitespace, PEP8, flake8, etc) - TST: addition or modification of tests - REL: related to releasing Catalyst - PERF: performance enhancements - - -Some commit style guidelines: - -Commit lines should be no longer than `72 characters `_. The first line of the commit should include one of the above prefixes. There should be an empty line between the commit subject and the body of the commit. In general, the message should be in the imperative tense. Best practice is to include not only what the change is, but why the change was made. - -**Example:** - -.. code-block:: text - - MAINT: Remove unused calculations of max_leverage, et al. - - In the performance period the max_leverage, max_capital_used, - cumulative_capital_used were calculated but not used. - - At least one of those calculations, max_leverage, was causing a - divide by zero error. - - Instead of papering over that error, the entire calculation was - a bit suspect so removing, with possibility of adding it back in - later with handling the case (or raising appropriate errors) when - the algorithm has little cash on hand. - - -Formatting Docstrings ---------------------- - -When adding or editing docstrings for classes, functions, etc, we use `numpy `_ as the canonical reference. - - diff --git a/_sources/example-algos.rst.txt b/_sources/example-algos.rst.txt deleted file mode 100644 index 0136b899..00000000 --- a/_sources/example-algos.rst.txt +++ /dev/null @@ -1,1077 +0,0 @@ -| - -Example Algorithms -================== - -This section documents a number of example algorithms to complement the -beginner tutorial, and show how other trading algorithms can be implemented -using Catalyst. - -Overview -~~~~~~~~ - -- :ref:`Buy BTC Simple`: The simplest algorithm that introduces - the ``initialize()`` and ``handle_data()`` functions, and is used in the - :doc:`beginner tutorial` to show how to run catalyst - for the first time. - -- :ref:`Buy and Hodl `: A very straightforward *buy and hold* that - makes one single buy at the very beginning. Introduces the notions of - ``cash``, management of outstanding ``orders``, and ``order_target_value`` - to place orders. It also introduces the ``analyze()`` function to visualize - the performance of our strategy using the external library ``matplotlib``. - -- :ref:`Dual Moving Average Crossover`: A classic momentum - strategy used in the second part of the - `beginner tutorial `_ to introduce the - ``data.history()`` function. It makes a heavy use of ``matplotlib`` library - in the ``analyze()`` function to chart the performance of the algorithm. - -- :ref:`Mean Reversion Algorithm `: Another simple momentum - strategy that is used in our - `two-part video tutorial `_ to show how - to get started in backtesting and live trading with Catalyst. - -- :ref:`Simple Universe `: This code provides the 'universe' - of available trading pairs on a given exchange on any given day. You can use - this code to dynamically select which currency pairs you want to trade each - day of your strategy. This example does not make any trades. - -- :ref:`Portfolio Optimization `: Use this code to - execute a portfolio optimization model. This strategy will select the - portfolio with the maximum Sharpe Ratio. The parameters are set to use 180 - days of historical data and rebalance every 30 days. This code was used in - writting the following article: - `Markowitz Portfolio Optimization for Cryptocurrencies `_. - - -.. _buy_btc_simple: - -Buy BTC Simple Algorithm -~~~~~~~~~~~~~~~~~~~~~~~~ - -Source code: `examples/buy_btc_simple.py `_ - -.. code-block:: python - - ''' - Run this example, by executing the following from your terminal: - catalyst ingest-exchange -x bitfinex -f daily -i btc_usdt - catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle - - If you want to run this code using another exchange, make sure that - the asset is available on that exchange. For example, if you were to run - it for exchange Poloniex, you would need to edit the following line: - - context.asset = symbol('btc_usdt') # note 'usdt' instead of 'usd' - - and specify exchange poloniex as follows: - catalyst ingest-exchange -x poloniex -f daily -i btc_usdt - catalyst run -f buy_btc_simple.py -x poloniex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle - - To see which assets are available on each exchange, visit: - https://www.enigma.co/catalyst/status - ''' - - from catalyst.api import order, record, symbol - - def initialize(context): - context.asset = symbol('btc_usd') - - def handle_data(context, data): - order(context.asset, 1) - record(btc = data.current(context.asset, 'price')) - -This simple algorithm does not produce any output nor displays any chart. - - -.. _buy_and_hodl: - -Buy and Hodl Algorithm -~~~~~~~~~~~~~~~~~~~~~~ - -Source code: `examples/buy_and_hodl.py `_ - -First ingest the historical pricing data needed to run this algorithm: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -f daily -i btc_usd - -Then, you can run the code below with the following command: - -.. code-block:: bash - - catalyst run -f buy_and_hodl.py --start 2015-3-1 --end 2017-10-31 --capital-base 100000 -x bitfinex -c btc -o bah.pickle - -or using the same parameters specified in the run_algorithm() function at the -end of the file: - -.. code-block:: bash - - python buy_and_hodl.py - - -This command will run the trading algorithm in the specified time range and -plot the resulting performance using the matplotlib library. You can choose any -date interval with the ``--start`` and ``--end`` parameters, but bear in mind -that 2015-3-1 is the earliest date that Catalyst supports (if you choose an -earlier date, you'll get an error), and the most recent date you can choose is -one day prior to the current date. - - -.. code-block:: python - - #!/usr/bin/env python - # - # Copyright 2017 Enigma MPC, Inc. - # Copyright 2015 Quantopian, Inc. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - import pandas as pd - import matplotlib.pyplot as plt - - from catalyst import run_algorithm - from catalyst.api import (order_target_value, symbol, record, - cancel_order, get_open_orders, ) - - - def initialize(context): - context.ASSET_NAME = 'btc_usd' - context.TARGET_HODL_RATIO = 0.8 - context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO - - context.is_buying = True - context.asset = symbol(context.ASSET_NAME) - - context.i = 0 - - - def handle_data(context, data): - context.i += 1 - - starting_cash = context.portfolio.starting_cash - target_hodl_value = context.TARGET_HODL_RATIO * starting_cash - reserve_value = context.RESERVE_RATIO * starting_cash - - # Cancel any outstanding orders - orders = get_open_orders(context.asset) or [] - for order in orders: - cancel_order(order) - - # Stop buying after passing the reserve threshold - cash = context.portfolio.cash - if cash <= reserve_value: - context.is_buying = False - - # Retrieve current asset price from pricing data - price = data.current(context.asset, 'price') - - # Check if still buying and could (approximately) afford another purchase - if context.is_buying and cash > price: - print('buying') - # Place order to make position in asset equal to target_hodl_value - order_target_value( - context.asset, - target_hodl_value, - limit_price=price * 1.1, - ) - - record( - price=price, - volume=data.current(context.asset, 'volume'), - cash=cash, - starting_cash=context.portfolio.starting_cash, - leverage=context.account.leverage, - ) - - - def analyze(context=None, results=None): - - # Plot the portfolio and asset data. - ax1 = plt.subplot(611) - results[['portfolio_value']].plot(ax=ax1) - ax1.set_ylabel('Portfolio Value (USD)') - - ax2 = plt.subplot(612, sharex=ax1) - ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME)) - results[['price']].plot(ax=ax2) - - trans = results.ix[[t != [] for t in results.transactions]] - buys = trans.ix[ - [t[0]['amount'] > 0 for t in trans.transactions] - ] - ax2.scatter( - buys.index.to_pydatetime(), - results.price[buys.index], - marker='^', - s=100, - c='g', - label='' - ) - - ax3 = plt.subplot(613, sharex=ax1) - results[['leverage', 'alpha', 'beta']].plot(ax=ax3) - ax3.set_ylabel('Leverage ') - - ax4 = plt.subplot(614, sharex=ax1) - results[['starting_cash', 'cash']].plot(ax=ax4) - ax4.set_ylabel('Cash (USD)') - - results[[ - 'treasury', - 'algorithm', - 'benchmark', - ]] = results[[ - 'treasury_period_return', - 'algorithm_period_return', - 'benchmark_period_return', - ]] - - ax5 = plt.subplot(615, sharex=ax1) - results[[ - 'treasury', - 'algorithm', - 'benchmark', - ]].plot(ax=ax5) - ax5.set_ylabel('Percent Change') - - ax6 = plt.subplot(616, sharex=ax1) - results[['volume']].plot(ax=ax6) - ax6.set_ylabel('Volume (mCoins/5min)') - - plt.legend(loc=3) - - # Show the plot. - plt.gcf().set_size_inches(18, 8) - plt.show() - - - if __name__ == '__main__': - run_algorithm( - capital_base=10000, - data_frequency='daily', - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - algo_namespace='buy_and_hodl', - base_currency='usd', - start=pd.to_datetime('2015-03-01', utc=True), - end=pd.to_datetime('2017-10-31', utc=True), - ) - -.. image:: https://s3.amazonaws.com/enigmaco-docs/github.io/example_buy_and_hodl.png - -.. _dual_moving_average: - -Dual Moving Average Crossover -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Source Code: `examples/dual_moving_average.py `_ - -This strategy is covered in detail in the last part of -`this tutorial `_. - -.. code-block:: python - - import numpy as np - import pandas as pd - from logbook import Logger - import matplotlib.pyplot as plt - - from catalyst import run_algorithm - from catalyst.api import (order, record, symbol, order_target_percent, - get_open_orders) - from catalyst.exchange.stats_utils import extract_transactions - - NAMESPACE = 'dual_moving_average' - log = Logger(NAMESPACE) - - def initialize(context): - context.i = 0 - context.asset = symbol('ltc_usd') - context.base_price = None - - - def handle_data(context, data): - # define the windows for the moving averages - short_window = 50 - long_window = 200 - - # Skip as many bars as long_window to properly compute the average - context.i += 1 - if context.i < long_window: - return - - # Compute moving averages calling data.history() for each - # moving average with the appropriate parameters. We choose to use - # minute bars for this simulation -> freq="1m" - # Returns a pandas dataframe. - short_mavg = data.history(context.asset, 'price', - bar_count=short_window, frequency="1m").mean() - long_mavg = data.history(context.asset, 'price', - bar_count=long_window, frequency="1m").mean() - - # Let's keep the price of our asset in a more handy variable - price = data.current(context.asset, 'price') - - # If base_price is not set, we use the current value. This is the - # price at the first bar which we reference to calculate price_change. - if context.base_price is None: - context.base_price = price - price_change = (price - context.base_price) / context.base_price - - # Save values for later inspection - record(price=price, - cash=context.portfolio.cash, - price_change=price_change, - short_mavg=short_mavg, - long_mavg=long_mavg) - - # Since we are using limit orders, some orders may not execute immediately - # we wait until all orders are executed before considering more trades. - orders = get_open_orders(context.asset) - if len(orders) > 0: - return - - # Exit if we cannot trade - if not data.can_trade(context.asset): - return - - # We check what's our position on our portfolio and trade accordingly - pos_amount = context.portfolio.positions[context.asset].amount - - # Trading logic - if short_mavg > long_mavg and pos_amount == 0: - # we buy 100% of our portfolio for this asset - order_target_percent(context.asset, 1) - elif short_mavg < long_mavg and pos_amount > 0: - # we sell all our positions for this asset - order_target_percent(context.asset, 0) - - - def analyze(context, perf): - - # Get the base_currency that was passed as a parameter to the simulation - base_currency = context.exchanges.values()[0].base_currency.upper() - - # First chart: Plot portfolio value using base_currency - ax1 = plt.subplot(411) - perf.loc[:, ['portfolio_value']].plot(ax=ax1) - ax1.legend_.remove() - ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency)) - start, end = ax1.get_ylim() - ax1.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - - # Second chart: Plot asset price, moving averages and buys/sells - ax2 = plt.subplot(412, sharex=ax1) - perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price') - ax2.legend_.remove() - ax2.set_ylabel('{asset}\n({base})'.format( - asset = context.asset.symbol, - base = base_currency - )) - start, end = ax2.get_ylim() - ax2.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - - transaction_df = extract_transactions(perf) - if not transaction_df.empty: - buy_df = transaction_df[transaction_df['amount'] > 0] - sell_df = transaction_df[transaction_df['amount'] < 0] - ax2.scatter( - buy_df.index.to_pydatetime(), - perf.loc[buy_df.index, 'price'], - marker='^', - s=100, - c='green', - label='' - ) - ax2.scatter( - sell_df.index.to_pydatetime(), - perf.loc[sell_df.index, 'price'], - marker='v', - s=100, - c='red', - label='' - ) - - # Third chart: Compare percentage change between our portfolio - # and the price of the asset - ax3 = plt.subplot(413, sharex=ax1) - perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3) - ax3.legend_.remove() - ax3.set_ylabel('Percent Change') - start, end = ax3.get_ylim() - ax3.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - - # Fourth chart: Plot our cash - ax4 = plt.subplot(414, sharex=ax1) - perf.cash.plot(ax=ax4) - ax4.set_ylabel('Cash\n({})'.format(base_currency)) - start, end = ax4.get_ylim() - ax4.yaxis.set_ticks(np.arange(0, end, end/5)) - - plt.show() - - - if __name__ == '__main__': - run_algorithm( - capital_base=1000, - data_frequency='minute', - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - algo_namespace=NAMESPACE, - base_currency='usd', - start=pd.to_datetime('2017-9-22', utc=True), - end=pd.to_datetime('2017-9-23', utc=True), - ) - -.. image:: https://s3.amazonaws.com/enigmaco-docs/github.io/tutorial_dual_moving_average.png - - -.. _mean_reversion: - -Mean Reversion Algorithm -~~~~~~~~~~~~~~~~~~~~~~~~ - -Source code: `examples/mean_reversion_simple.py `_ - -This algorithm is based on a simple momentum strategy. When the cryptoasset goes -up quickly, we're going to buy; when it goes down quickly, we're going to sell. -Hopefully, we'll ride the waves. - -We are choosing to backtest this trading algorithm with the ``neo_usd`` currency -pairon the ``Bitfinex`` exchange. Thus, first ingest the historical pricing data -that we need, with minute resolution: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -f minute -i neo_usd - -To run this algorithm, we are opting for the Python interpreter, instead of the -command line (CLI). All of the parameters for the simulation are specified in -lines 218-245, so in order to run the algorithm we just type: - -.. code-block:: bash - - python mean_reversion_simple.py - -.. code-block:: python - - import os - import tempfile - import time - - import numpy as np - import pandas as pd - import talib - from logbook import Logger - - from catalyst import run_algorithm - from catalyst.api import symbol, record, order_target_percent, get_open_orders - from catalyst.exchange.stats_utils import extract_transactions - # We give a name to the algorithm which Catalyst will use to persist its state. - # In this example, Catalyst will create the `.catalyst/data/live_algos` - # directory. If we stop and start the algorithm, Catalyst will resume its - # state using the files included in the folder. - from catalyst.utils.paths import ensure_directory - - NAMESPACE = 'mean_reversion_simple' - log = Logger(NAMESPACE) - - - # To run an algorithm in Catalyst, you need two functions: initialize and - # handle_data. - - def initialize(context): - # This initialize function sets any data or variables that you'll use in - # your algorithm. For instance, you'll want to define the trading pair (or - # trading pairs) you want to backtest. You'll also want to define any - # parameters or values you're going to use. - - # In our example, we're looking at Neo in USD. - context.neo_eth = symbol('neo_usd') - context.base_price = None - context.current_day = None - - context.RSI_OVERSOLD = 30 - context.RSI_OVERBOUGHT = 80 - context.CANDLE_SIZE = '15T' - - context.start_time = time.time() - - - def handle_data(context, data): - # This handle_data function is where the real work is done. Our data is - # minute-level tick data, and each minute is called a frame. This function - # runs on each frame of the data. - - # We flag the first period of each day. - # Since cryptocurrencies trade 24/7 the `before_trading_starts` handle - # would only execute once. This method works with minute and daily - # frequencies. - today = data.current_dt.floor('1D') - if today != context.current_day: - context.traded_today = False - context.current_day = today - - # We're computing the volume-weighted-average-price of the security - # defined above, in the context.neo_eth variable. For this example, we're - # using three bars on the 15 min bars. - - # The frequency attribute determine the bar size. We use this convention - # for the frequency alias: - # http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases - prices = data.history( - context.neo_eth, - fields='close', - bar_count=50, - frequency=context.CANDLE_SIZE - ) - - # Ta-lib calculates various technical indicator based on price and - # volume arrays. - - # In this example, we are comp - rsi = talib.RSI(prices.values, timeperiod=14) - - # We need a variable for the current price of the security to compare to - # the average. Since we are requesting two fields, data.current() - # returns a DataFrame with - current = data.current(context.neo_eth, fields=['close', 'volume']) - price = current['close'] - - # If base_price is not set, we use the current value. This is the - # price at the first bar which we reference to calculate price_change. - if context.base_price is None: - context.base_price = price - - price_change = (price - context.base_price) / context.base_price - cash = context.portfolio.cash - - # Now that we've collected all current data for this frame, we use - # the record() method to save it. This data will be available as - # a parameter of the analyze() function for further analysis. - record( - price=price, - volume=current['volume'], - price_change=price_change, - rsi=rsi[-1], - cash=cash - ) - - # We are trying to avoid over-trading by limiting our trades to - # one per day. - if context.traded_today: - return - - # Since we are using limit orders, some orders may not execute immediately - # we wait until all orders are executed before considering more trades. - orders = get_open_orders(context.neo_eth) - if len(orders) > 0: - return - - # Exit if we cannot trade - if not data.can_trade(context.neo_eth): - return - - # Another powerful built-in feature of the Catalyst backtester is the - # portfolio object. The portfolio object tracks your positions, cash, - # cost basis of specific holdings, and more. In this line, we calculate - # how long or short our position is at this minute. - pos_amount = context.portfolio.positions[context.neo_eth].amount - - if rsi[-1] <= context.RSI_OVERSOLD and pos_amount == 0: - log.info( - '{}: buying - price: {}, rsi: {}'.format( - data.current_dt, price, rsi[-1] - ) - ) - # Set a style for limit orders, - limit_price = price * 1.005 - order_target_percent( - context.neo_eth, 1, limit_price=limit_price - ) - context.traded_today = True - - elif rsi[-1] >= context.RSI_OVERBOUGHT and pos_amount > 0: - log.info( - '{}: selling - price: {}, rsi: {}'.format( - data.current_dt, price, rsi[-1] - ) - ) - limit_price = price * 0.995 - order_target_percent( - context.neo_eth, 0, limit_price=limit_price - ) - context.traded_today = True - - - def analyze(context=None, perf=None): - end = time.time() - log.info('elapsed time: {}'.format(end - context.start_time)) - - import matplotlib.pyplot as plt - # The base currency of the algo exchange - base_currency = context.exchanges.values()[0].base_currency.upper() - - # Plot the portfolio value over time. - ax1 = plt.subplot(611) - perf.loc[:, 'portfolio_value'].plot(ax=ax1) - ax1.set_ylabel('Portfolio\nValue\n({})'.format(base_currency)) - - # Plot the price increase or decrease over time. - ax2 = plt.subplot(612, sharex=ax1) - perf.loc[:, 'price'].plot(ax=ax2, label='Price') - - ax2.set_ylabel('{asset}\n({base})'.format( - asset=context.neo_eth.symbol, base=base_currency - )) - - transaction_df = extract_transactions(perf) - if not transaction_df.empty: - buy_df = transaction_df[transaction_df['amount'] > 0] - sell_df = transaction_df[transaction_df['amount'] < 0] - ax2.scatter( - buy_df.index.to_pydatetime(), - perf.loc[buy_df.index.floor('1 min'), 'price'], - marker='^', - s=100, - c='green', - label='' - ) - ax2.scatter( - sell_df.index.to_pydatetime(), - perf.loc[sell_df.index.floor('1 min'), 'price'], - marker='v', - s=100, - c='red', - label='' - ) - - ax4 = plt.subplot(613, sharex=ax1) - perf.loc[:, 'cash'].plot( - ax=ax4, label='Base Currency ({})'.format(base_currency) - ) - ax4.set_ylabel('Cash\n({})'.format(base_currency)) - - perf['algorithm'] = perf.loc[:, 'algorithm_period_return'] - - ax5 = plt.subplot(614, sharex=ax1) - perf.loc[:, ['algorithm', 'price_change']].plot(ax=ax5) - ax5.set_ylabel('Percent\nChange') - - ax6 = plt.subplot(615, sharex=ax1) - perf.loc[:, 'rsi'].plot(ax=ax6, label='RSI') - ax6.set_ylabel('RSI') - ax6.axhline(context.RSI_OVERBOUGHT, color='darkgoldenrod') - ax6.axhline(context.RSI_OVERSOLD, color='darkgoldenrod') - - if not transaction_df.empty: - ax6.scatter( - buy_df.index.to_pydatetime(), - perf.loc[buy_df.index.floor('1 min'), 'rsi'], - marker='^', - s=100, - c='green', - label='' - ) - ax6.scatter( - sell_df.index.to_pydatetime(), - perf.loc[sell_df.index.floor('1 min'), 'rsi'], - marker='v', - s=100, - c='red', - label='' - ) - plt.legend(loc=3) - start, end = ax6.get_ylim() - ax6.yaxis.set_ticks(np.arange(0, end, end/5)) - - # Show the plot. - plt.gcf().set_size_inches(18, 8) - plt.show() - pass - - - if __name__ == '__main__': - # The execution mode: backtest or live - MODE = 'backtest' - - if MODE == 'backtest': - folder = os.path.join( - tempfile.gettempdir(), 'catalyst', NAMESPACE - ) - ensure_directory(folder) - - timestr = time.strftime('%Y%m%d-%H%M%S') - out = os.path.join(folder, '{}.p'.format(timestr)) - # catalyst run -f catalyst/examples/mean_reversion_simple.py -x bitfinex -s 2017-10-1 -e 2017-11-10 -c usdt -n mean-reversion --data-frequency minute --capital-base 10000 - run_algorithm( - capital_base=10000, - data_frequency='minute', - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - algo_namespace=NAMESPACE, - base_currency='usd', - start=pd.to_datetime('2017-10-01', utc=True), - end=pd.to_datetime('2017-11-10', utc=True), - output=out - ) - log.info('saved perf stats: {}'.format(out)) - - elif MODE == 'live': - run_algorithm( - capital_base=0.5, - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bittrex', - live=True, - algo_namespace=NAMESPACE, - base_currency='usd', - live_graph=False - ) - -.. image:: https://s3.amazonaws.com/enigmaco-docs/github.io/example_mean_reversion_simple.png - -Notice the difference in performance between the charts above and those seen on -`this video tutorial `_ at -minute 8:10. The buy and sell orders are triggered at the same exact times, but -the differences result from a more realistic slippage model -implemented after the video was recorded, which executes the orders at slighlty -different prices, but resulting in significant changes in performance of our -strategy. - -.. _simple_universe: - -Simple Universe -~~~~~~~~~~~~~~~ - -Source code: `examples/simple_universe.py `_ - -This example aims to provide an easy way for users to learn how to -collect data from any given exchange and select a subset of the available -currency pairs for trading. You simply need to specify the exchange and -the market (base_currency) that you want to focus on. You will then see -how to create a universe of assets, and filter it based the market you -desire. - -The example prints out the closing price of all the pairs for a given -market in a given exchange every 30 minutes. The example also contains -the OHLCV data with minute-resolution for the past seven days which -could be used to create indicators. Use this code as the backbone to -create your own trading strategy. - -The lookback_date variable is used to ensure data for a coin existed on -the lookback period specified. - -To run, execute the following two commands in a terminal (inside catalyst -environment). The first one retrieves all the pricing data needed for this -script to run (only needs to be run once), and the second one executes this -script with the parameters specified in the run_algorithm() call at the end -of the file: - -.. code-block:: bash - - catalyst ingest-exchange -x bitfinex -f minute - -.. code-block:: bash - - python simple_universe.py - -Credits: This code was originally submitted by `Abner Ayala-Acevedo -`_. Thank you! - -.. code-block:: python - - from datetime import timedelta - - import numpy as np - import pandas as pd - - from catalyst import run_algorithm - from catalyst.exchange.utils.exchange_utils import get_exchange_symbols - from catalyst.api import (symbols, ) - - - def initialize(context): - context.i = -1 # minute counter - context.exchange = context.exchanges.values()[0].name.lower() - context.base_currency = context.exchanges.values()[0].base_currency.lower() - - - def handle_data(context, data): - context.i += 1 - lookback_days = 7 # 7 days - - # current date & time in each iteration formatted into a string - now = data.current_dt - date, time = now.strftime('%Y-%m-%d %H:%M:%S').split(' ') - lookback_date = now - timedelta(days=lookback_days) - # keep only the date as a string, discard the time - lookback_date = lookback_date.strftime('%Y-%m-%d %H:%M:%S').split(' ')[0] - - one_day_in_minutes = 1440 # 60 * 24 assumes data_frequency='minute' - # update universe everyday at midnight - if not context.i % one_day_in_minutes: - context.universe = universe(context, lookback_date, date) - - # get data every 30 minutes - minutes = 30 - # get lookback_days of history data: that is 'lookback' number of bins - lookback = one_day_in_minutes / minutes * lookback_days - if not context.i % minutes and context.universe: - # we iterate for every pair in the current universe - for coin in context.coins: - pair = str(coin.symbol) - - # Get 30 minute interval OHLCV data. This is the standard data - # required for candlestick or indicators/signals. Return Pandas - # DataFrames. 30T means 30-minute re-sampling of one minute data. - # Adjust it to your desired time interval as needed. - opened = fill(data.history(coin, 'open', - bar_count=lookback, frequency='30T')).values - high = fill(data.history(coin, 'high', - bar_count=lookback, frequency='30T')).values - low = fill(data.history(coin, 'low', - bar_count=lookback, frequency='30T')).values - close = fill(data.history(coin, 'price', - bar_count=lookback, frequency='30T')).values - volume = fill(data.history(coin, 'volume', - bar_count=lookback, frequency='30T')).values - - # close[-1] is the last value in the set, which is the equivalent - # to current price (as in the most recent value) - # displays the minute price for each pair every 30 minutes - print('{now}: {pair} -\tO:{o},\tH:{h},\tL:{c},\tC{c},\tV:{v}'.format( - now=now, - pair=pair, - o=opened[-1], - h=high[-1], - l=low[-1], - c=close[-1], - v=volume[-1], - )) - - # ------------------------------------------------------------- - # --------------- Insert Your Strategy Here ------------------- - # ------------------------------------------------------------- - - - def analyze(context=None, results=None): - pass - - - # Get the universe for a given exchange and a given base_currency market - # Example: Poloniex BTC Market - def universe(context, lookback_date, current_date): - # get all the pairs for the given exchange - json_symbols = get_exchange_symbols(context.exchange) - # convert into a DataFrame for easier processing - df = pd.DataFrame.from_dict(json_symbols).transpose().astype(str) - df['base_currency'] = df.apply(lambda row: row.symbol.split('_')[1],axis=1) - df['market_currency'] = df.apply(lambda row: row.symbol.split('_')[0],axis=1) - - # Filter all the pairs to get only the ones for a given base_currency - df = df[df['base_currency'] == context.base_currency] - - # Filter all the pairs to ensure that pair existed in the current date range - df = df[df.start_date < lookback_date] - df = df[df.end_daily >= current_date] - context.coins = symbols(*df.symbol) # convert all the pairs to symbols - - return df.symbol.tolist() - - - # Replace all NA, NAN or infinite values with its nearest value - def fill(series): - if isinstance(series, pd.Series): - return series.replace([np.inf, -np.inf], np.nan).ffill().bfill() - elif isinstance(series, np.ndarray): - return pd.Series(series).replace( - [np.inf, -np.inf], np.nan - ).ffill().bfill().values - else: - return series - - - if __name__ == '__main__': - start_date = pd.to_datetime('2017-11-10', utc=True) - end_date = pd.to_datetime('2017-11-13', utc=True) - - performance = run_algorithm(start=start_date, end=end_date, - capital_base=100.0, # amount of base_currency - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - data_frequency='minute', - base_currency='btc', - live=False, - live_graph=False, - algo_namespace='simple_universe') - - - -.. _portfolio_optimization: - -Portfolio Optimization -~~~~~~~~~~~~~~~~~~~~~~ - -Use this code to execute a portfolio optimization model. This strategy will -select the portfolio with the maximum Sharpe Ratio. The parameters are set to -use 180 days of historical data and rebalance every 30 days. This code was used -in writting the following article: -`Markowitz Portfolio Optimization for Cryptocurrencies `_. - -.. code-block:: python - - ''' - You can run this code using the Python interpreter: - - $ python portfolio_optimization.py - ''' - - from __future__ import division - import os - import pytz - import numpy as np - import pandas as pd - from scipy.optimize import minimize - import matplotlib.pyplot as plt - from datetime import datetime - - from catalyst.api import record, symbol, symbols, order_target_percent - from catalyst.utils.run_algo import run_algorithm - - np.set_printoptions(threshold='nan', suppress=True) - - - def initialize(context): - # Portfolio assets list - context.assets = symbols('btc_usdt', 'eth_usdt', 'ltc_usdt', 'dash_usdt', - 'xmr_usdt') - context.nassets = len(context.assets) - # Set the time window that will be used to compute expected return - # and asset correlations - context.window = 180 - # Set the number of days between each portfolio rebalancing - context.rebalance_period = 30 - context.i = 0 - - - def handle_data(context, data): - # Only rebalance at the beggining of the algorithm execution and - # every multiple of the rebalance period - if context.i == 0 or context.i%context.rebalance_period == 0: - n = context.window - prices = data.history(context.assets, fields='price', - bar_count=n+1, frequency='1d') - pr = np.asmatrix(prices) - t_prices = prices.iloc[1:n+1] - t_val = t_prices.values - tminus_prices = prices.iloc[0:n] - tminus_val = tminus_prices.values - # Compute daily returns (r) - r = np.asmatrix(t_val/tminus_val-1) - # Compute the expected returns of each asset with the average - # daily return for the selected time window - m = np.asmatrix(np.mean(r, axis=0)) - # ### - stds = np.std(r, axis=0) - # Compute excess returns matrix (xr) - xr = r - m - # Matrix algebra to get variance-covariance matrix - cov_m = np.dot(np.transpose(xr),xr)/n - # Compute asset correlation matrix (informative only) - corr_m = cov_m/np.dot(np.transpose(stds),stds) - - # Define portfolio optimization parameters - n_portfolios = 50000 - results_array = np.zeros((3+context.nassets,n_portfolios)) - for p in xrange(n_portfolios): - weights = np.random.random(context.nassets) - weights /= np.sum(weights) - w = np.asmatrix(weights) - p_r = np.sum(np.dot(w,np.transpose(m)))*365 - p_std = np.sqrt(np.dot(np.dot(w,cov_m),np.transpose(w)))*np.sqrt(365) - - #store results in results array - results_array[0,p] = p_r - results_array[1,p] = p_std - #store Sharpe Ratio (return / volatility) - risk free rate element - #excluded for simplicity - results_array[2,p] = results_array[0,p] / results_array[1,p] - i = 0 - for iw in weights: - results_array[3+i,p] = weights[i] - i += 1 - - #convert results array to Pandas DataFrame - results_frame = pd.DataFrame(np.transpose(results_array), - columns=['r','stdev','sharpe']+context.assets) - #locate position of portfolio with highest Sharpe Ratio - max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()] - #locate positon of portfolio with minimum standard deviation - min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()] - - #order optimal weights for each asset - for asset in context.assets: - if data.can_trade(asset): - order_target_percent(asset, max_sharpe_port[asset]) - - #create scatter plot coloured by Sharpe Ratio - plt.scatter(results_frame.stdev,results_frame.r,c=results_frame.sharpe,cmap='RdYlGn') - plt.xlabel('Volatility') - plt.ylabel('Returns') - plt.colorbar() - #plot red star to highlight position of portfolio with highest Sharpe Ratio - plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker='o',color='b',s=200) - #plot green star to highlight position of minimum variance portfolio - plt.show() - print(max_sharpe_port) - record(pr=pr,r=r, m=m, stds=stds ,max_sharpe_port=max_sharpe_port, corr_m=corr_m) - context.i += 1 - - - def analyze(context=None, results=None): - # Form DataFrame with selected data - data = results[['pr','r','m','stds','max_sharpe_port','corr_m','portfolio_value']] - - # Save results in CSV file - filename = os.path.splitext(os.path.basename(__file__))[0] - data.to_csv(filename + '.csv') - - - # Bitcoin data is available from 2015-3-2. Dates vary for other tokens. - start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc) - end = datetime(2017, 8, 16, 0, 0, 0, 0, pytz.utc) - results = run_algorithm(initialize=initialize, - handle_data=handle_data, - analyze=analyze, - start=start, - end=end, - exchange_name='poloniex', - capital_base=100000, ) - -.. image:: https://cdn-images-1.medium.com/max/1600/0*EjjiKZHlYF3sn7yQ. - :align: center - - - diff --git a/_sources/features.rst.txt b/_sources/features.rst.txt deleted file mode 100644 index 79b02583..00000000 --- a/_sources/features.rst.txt +++ /dev/null @@ -1,122 +0,0 @@ -Features -======== - -This page describes the features that Catalyst provides in the current version, -and what is planned for future releases. - -Current Functionality -~~~~~~~~~~~~~~~~~~~~~ - -* Backtesting and live-trading modes to run your trading algorithms, with a - seamless transition between the two. -* Paper trading simulates order in live-trading mode. -* Support for 3 exchanges: Bitfinex, Bittrex and Poloniex in both modes - (backtesting and live-trading). Historical data for backtesting is provided - with daily resolution for all three exchanges, and minute resolution for - Bitfinex and Poloniex. No minute-resolution data is currently available for - Bittrex. Refer to - `Catalyst Market Coverage `_ for - details. -* Interface with over 90 exchanges available in live and paper trading modes. -* Granular commission models which closely simulates each exchange fee - structure in backtesting and paper trading. -* Standardized naming convention for all asset pairs trading on any exchange in - the form ``{market_currency}_{base_currency}``. See - :ref:`naming`. -* Output of performance statistics based on Pandas DataFrames to integrate - nicely into the existing PyData ecosystem. -* Support for accessing multiple exchanges per algorithm, which opens the door - to cross-exchange arbitrage opportunities. -* Support for running multiple algorithms on the same exchange independently of - one another. Catalyst performance tracker stores just enough data to allow - algorithms to run independently while still sharing critical data through - exchanges. -* Benchmark defaults to Bitcoin price (btc_usdt in Poloniex exchange) for the - purpose of comparing performance across trading algorithms. A custom benchmark - can be specified through ``set_benchmark()`` (but see - `issue #86 `_). -* Support for MacOS, Linux and Windows installations. -* Support for Python2 and Python3. - -For additional details on the functionality added on recent releases, see the -:doc:`Release Notes`. - -Upcoming features -~~~~~~~~~~~~~~~~~ - -* Additional datasets beyond pricing data (Q1 2018) -* API documentation (Q1 2018) -* Support for decentralized exchanges (Q1 2018) -* Support for data ingestion of community-contributed data sets (Q1 2018) -* Pipeline support (Q1 2018) -* Web UI (Q2 2018) - - - .. _naming: - -Naming Convention -~~~~~~~~~~~~~~~~~ - -Catalyst introduces a standardized naming convention for all asset pairs -trading on any exchange in the following form: - - - **{market_currency}_{base_currency}** - -Where {market_currency} is the asset to be traded using {base_currency} as -the reference, both written in lowercase and separated with an underscore. - -This standardization is needed to overcome the lack of consistency in the -naming of assets across different exchanges, and making it easier to the user -to refer to the asset pairs that you want to trade. - -Catalyst maintains a `Market Coverage Overview `_ -where you can check the mapping between Catalyst naming pairs and that of each -exchange. Catalyst will always expect in all its functions that you will refer to -the asset pairs by using the Catalyst naming convention. - -If at any point, you input the wrong name for an asset pair, you will get an error -of that pair not found in the given exchange, and a list of pairs available on that exchange: - -.. code-block:: bash - - $ catalyst ingest-exchange -x poloniex -i btc_usd - -.. parsed-literal:: - - Ingesting exchange bundle poloniex... - Error traceback: /Volumes/Data/Users/victoris/Desktop/Enigma/user-install/catalyst-dev/catalyst/exchange/exchange.py (line 175) - SymbolNotFoundOnExchange: Symbol btc_usd not found on exchange Poloniex. - Choose from: ['rep_usdt', 'gno_btc', 'xvc_btc', 'pink_btc', 'sys_btc', - 'emc2_btc', 'rads_btc', 'note_btc', 'maid_btc', 'bch_btc', 'gnt_btc', - 'bcn_btc', 'rep_btc', 'bcy_btc', 'cvc_btc', 'nxt_xmr', 'zec_usdt', - 'fct_btc', 'gas_btc', 'pot_btc', 'eth_usdt', 'btc_usdt', 'lbc_btc', - 'dcr_btc', 'etc_usdt', 'omg_eth', 'amp_btc', 'xpm_btc', 'nxt_btc', - 'vtc_btc', 'steem_eth', 'blk_xmr', 'pasc_btc', 'zec_xmr', 'grc_btc', - 'nxc_btc', 'btcd_btc', 'ltc_btc', 'dash_btc', 'naut_btc', 'zec_eth', - 'zec_btc', 'burst_btc', 'zrx_eth', 'bela_btc', 'steem_btc', 'etc_btc', - 'eth_btc', 'huc_btc', 'strat_btc', 'lsk_btc', 'exp_btc', 'clam_btc', - 'rep_eth', 'dash_xmr', 'cvc_eth', 'bch_usdt', 'zrx_btc', 'dash_usdt', - 'blk_btc', 'xrp_btc', 'nxt_usdt', 'neos_btc', 'omg_btc', 'bts_btc', - 'doge_btc', 'gnt_eth', 'sbd_btc', 'gno_eth', 'xcp_btc', 'ltc_usdt', - 'btm_btc', 'xmr_usdt', 'lsk_eth', 'omni_btc', 'nav_btc', 'fldc_btc', - 'ppc_btc', 'xbc_btc', 'dgb_btc', 'sc_btc', 'btcd_xmr', 'vrc_btc', - 'ric_btc', 'str_btc', 'maid_xmr', 'xmr_btc', 'sjcx_btc', 'via_btc', - 'xem_btc', 'nmc_btc', 'etc_eth', 'ltc_xmr', 'ardr_btc', 'gas_eth', - 'flo_btc', 'xrp_usdt', 'game_btc', 'bch_eth', 'bcn_xmr', 'str_usdt'] - -In the example above, exchange Poloniex does not use USD, but uses instead the -USDT cryptocurrency asset that is issued on the Bitcoin blockchain via the Omni -Layer Protocol. Each USDT unit is backed by a U.S Dollar held in the reserves of -Tether Limited. USDT can be transferred, stored, and spent, just like bitcoins -or any other cryptocurrency. Given its 1:1 mapping to the USD, is a viable alternative. - -.. code-block:: bash - - $ catalyst ingest-exchange -x poloniex -i btc_usdt - -.. parsed-literal:: - - Ingesting exchange bundle poloniex... - [====================================] Fetching poloniex daily candles: : 100% - diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt deleted file mode 100644 index 5681e3b6..00000000 --- a/_sources/index.rst.txt +++ /dev/null @@ -1,25 +0,0 @@ -.. include:: ../../README.rst - -| -| - -Table of Contents ------------------ - -.. toctree:: - :maxdepth: 1 - - install - beginner-tutorial - live-trading - features - example-algos - utilities - videos - resources - development-guidelines - releases -.. bundles -.. appendix -.. release-process - diff --git a/_sources/install.rst.txt b/_sources/install.rst.txt deleted file mode 100644 index 7459f97a..00000000 --- a/_sources/install.rst.txt +++ /dev/null @@ -1,545 +0,0 @@ -Install -======= - -To get started with Catalyst, you will need to install it in your computer. -Like any other piece of software, Catalyst has a number of dependencies -(other software on which it depends to run) that you will need to install, as -well. We recommend using a software named ``Conda`` that will manage all -these dependencies for you, and set up the environment needed to get you up -and running as easily as possible. This is the recommended installation method -for Windows, MacOS and Linux. See :ref:`Installing with Conda `. - -What conda does is create a pre-configured environment, and inside that -environment install Catalyst using ``pip``, Python's package manager. Thus, -as an alternative installation method for MacOS and Linux, you can install -Catalyst directly with ``pip`` (we recommend in combination with a virtual -environemnt). See :ref:`Installing with pip `. - -Alternatively you can install Catalyst using ``pipenv`` which is a mix of pip -and virtualenv. See :ref:`Installing with pipenv `. - -Regardless of the method, each operating system (OS), has its own -prerequisites, make sure to review the corresponding sections for your system: -:ref:`Linux `, :ref:`MacOS ` and :ref:`Windows `. - -.. _conda: - -Installing with ``conda`` -------------------------- - -The preferred method to install Catalyst is via the ``conda`` package manager, -which comes as part of Continuum Analytics' `Anaconda -`_ distribution. - -The primary advantage of using Conda over ``pip`` is that conda natively -understands the complex binary dependencies of packages like ``numpy`` and -``scipy``. This means that ``conda`` can install Catalyst and its -dependencies without requiring the use of a second tool to acquire Catalyst's -non-Python dependencies. - - For Windows, you will first need to install the *Microsoft Visual C++ - Compiler for Python 2.7*. Follow the instructions on the :ref:`Windows - ` section and come back here. - -For instructions on how to install ``conda``, see the `Conda Installation -Documentation `_. Alternatively, -you can install MiniConda, which is a smaller footprint (fewer packages and -smaller size) than its big brother Anaconda, but it still contains all the -main packages needed. To install MiniConda, you can follow these steps: - -1. Download `MiniConda `_. Select Python 2.7 - for your Operating System. -2. Install MiniConda. See the `Installation Instructions - `_ if you need help. -3. Ensure the correct installation by running ``conda list`` in a Terminal - window, which should print the list of packages installed with Conda. - - For Windows, if you accepted the default installation options, you didn't - check an option to add Conda to the PATH, so trying to run ``conda`` from - a regular ``Command Prompt`` will result in the following error: ``'conda' - is no recognized as an internal or external command, operatble program or - batch file``. That's to be expected. You will nee to launch an ``Anaconda - Prompt`` that was added at installation time to your list of programs - available from the Start menu. - -Once either Conda or MiniConda has been set up you can install Catalyst: - -1. Download the file `python2.7-environment.yml - `_. - - To download, simply click on the 'Raw' button and save the file locally - to a folder you can remember. Make sure that the file gets saved with the - ``.yml`` extension, and nothing like a ``.txt`` file or anything else. - -2. Open a Terminal window and enter [``cd/dir``] into the directory where you - saved the above ``python2.7-environment.yml`` file. - -3. Install using this file. This step can take about 5-10 minutes to install. - - .. code-block:: bash - - conda env create -f python2.7-environment.yml - -4. Activate the environment (which you need to do every time you start a new - session to run Catalyst): - - **Linux or MacOS:** - - .. code-block:: bash - - source activate catalyst - - **Windows:** - - .. code-block:: bash - - activate catalyst - -5. Verify that Catalyst is install correctly: - - .. code-block:: bash - - catalyst --version - - which should display the current version. - -Congratulations! You now have Catalyst installed. - -Troubleshooting ``conda`` Install -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If the command ``conda env create -f python2.7-environment.yml`` in step 3 -above failed for any reason, you can try setting up the environment manually -with the following steps: - -1. If the above installation failed, and you have a partially set up catalyst - environment, remove it first. If you are starting from scratch, proceed to - step #2: - - .. code-block:: bash - - conda env remove --name catalyst - -2. Create the environment: - - .. code-block:: bash - - conda create --name catalyst python=2.7 scipy zlib - -3. Activate the environment: - - **Linux or MacOS:** - - .. code-block:: bash - - source activate catalyst - - **Windows:** - - .. code-block:: bash - - activate catalyst - -4. Install the Catalyst inside the environment: - - .. code-block:: bash - - pip install enigma-catalyst matplotlib - -5. Verify that Catalyst is installed correctly: - - .. code-block:: bash - - catalyst --version - - which should display the current version. - -Congratulations! You now have Catalyst properly installed. - -.. _pip: - -Installing with ``pip`` ------------------------ - -Installing Catalyst via ``pip`` is slightly more involved than the average -Python package. - -There are two reasons for the additional complexity: - -1. Catalyst ships several C extensions that require access to the CPython C - API. In order to build the C extensions, ``pip`` needs access to the - CPython header files for your Python installation. - -2. Catalyst depends on `numpy `_, the core library for - numerical array computing in Python. Numpy depends on having the `LAPACK - `_ linear algebra routines available. - -Because LAPACK and the CPython headers are non-Python dependencies, the -correctway to install them varies from platform to platform. If you'd rather -use a single tool to install Python and non-Python dependencies, or if you're -already using `Anaconda `_ as your Python -distribution, refer to the :ref:`Installing with Conda ` section. - -If you use Python for anything other than Catalyst, we **strongly** recommend -that you install in a `virtualenv -`_. The `Hitchhiker's Guide to -Python`_ provides an `excellent tutorial on virtualenv -`_. Here's a -summarized version: - -.. code-block:: bash - - $ pip install virtualenv - $ virtualenv catalyst-venv - $ source ./catalyst-venv/bin/activate - -Once you've installed the necessary additional dependencies for your system -(:ref:`Linux`, :ref:`MacOS` or :ref:`Windows`) **and have activated your virtualenv**, you should be able to simply run - -.. code-block:: bash - - $ pip install enigma-catalyst matplotlib - -Note that in the command above we install two different packages. The second -one, ``matplotlib`` is a visualization library. While it's not strictly -required to run catalyst simulations or live trading, it comes in very handy -to visualize the performance of your algorithms, and for this reason we -recommend you install it, as well. - - -Troubleshooting ``pip`` Install -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Issue**: - Package enigma-catalyst cannot be found - -**Solution**: - Make sure you have the most up-to-date version of pip installed, by running: - - .. code-block:: bash - - $ pip install --upgrade pip - - On Windows, the recommended command is: - - .. code-block:: bash - - $ python -m pip install --upgrade pip - ----- - -**Issue**: - Package enigma-catalyst cannot still be found, even after upgrading pip - (see above), with an error similar to: - - .. code-block:: bash - - Downloading/unpacking enigma-catalyst - Could not find a version that satisfies the requirement enigma-catalyst - (from versions: 0.1.dev9, 0.2.dev2, 0.1.dev4, 0.1.dev5, 0.1.dev3, - 0.2.dev1, 0.1.dev8, 0.1.dev6) - Cleaning up... - No distributions matching the version for enigma-catalyst - -**Solution**: - In some systems (this error has been reported in Ubuntu), pip is configured - to only find stable versions by default. Since Catalyst is in alpha - version, pip cannot find a matching version that satisfies the installation - requirements. The solution is to include the `--pre` flag to include - pre-release and development versions: - - .. code-block:: bash - - $ pip install --pre enigma-catalyst - ----- - -**Issue**: - Package enigma-catalyst fails to install because of outdated setuptools - -**Solution**: - Upgrade to the most up-to-date setuptools package by running: - - .. code-block:: bash - - $ pip install --upgrade pip setuptools - ----- - -**Issue**: - Missing required packages - -**Solution**: - Download `requirements.txt - `_ - (click on the *Raw* button and Right click -> Save As...) and use it to - install all the required dependencies by running: - - .. code-block:: bash - - $ pip install -r requirements.txt - ----- - -**Issue**: - Installation fails with error: - ``fatal error: Python.h: No such file or directory`` - -**Solution**: - Some systems (this issue has been reported in Ubuntu) require `python-dev` - for the proper build and installation of package dependencies. The solution - is to install python-dev, which is independent of the virtual environment. - In Ubuntu, you would need to run: - - .. code-block:: bash - - $ sudo apt-get install python-dev - -.. _pipenv: - -Installing with ``pipenv`` --------------------------- - -Installing Catalyst via ``pipenv`` is perhaps easier that installing it via -``pip`` itself but you need to install ``pipenv`` first via ``pip``. - -.. code-block:: bash - - $ pip install pipenv - -Once ``pipenv`` is installed you can proceed by creating a project folder and -installing Catalyst on that project automagically as follows: - -.. code-block:: bash - - $ mkdir project - $ cd project - $ pipenv --two - $ pipenv install enigma-catalyst matplotlib - -Until now the workflow compared to ``pip`` is almost identical, the difference -is that you don't need to load manually any virtualenv however you need to use -the `pipenv run` prefix to run the `catalyst` command as follows: - -.. code-block:: bash - - $ pipenv run catalyst --version - -If you want to know more about ``pipenv`` go to the `pipenv github repo`_ - -.. _`pipenv github repo`: https://github.com/pypa/pipenv - -.. _linux: - -GNU/Linux Requirements ----------------------- - -On `Debian-derived`_ Linux distributions, you can acquire all the necessary -binary dependencies from ``apt`` by running: - -.. code-block:: bash - - $ sudo apt-get install libatlas-base-dev python-dev gfortran pkg-config libfreetype6-dev - -On recent `RHEL-derived`_ derived Linux distributions (e.g. Fedora), the -following should be sufficient to acquire the necessary additional -dependencies: - -.. code-block:: bash - - $ sudo dnf install atlas-devel gcc-c++ gcc-gfortran libgfortran python-devel redhat-rep-config - -On `Arch Linux`_, you can acquire the additional dependencies via ``pacman``: - -.. code-block:: bash - - $ pacman -S lapack gcc gcc-fortran pkg-config - -.. Commenting it out until Catalyst fully supports Python 3.X -.. -.. There are also AUR packages available for installing `Python 3.4 -.. `_ (Arch's default python is now -.. 3.5, but Catalyst only currently supports 3.4), and `ta-lib -.. `_, an optional Catalyst dependency. -.. Python 2 is also installable via: - -.. - -.. $ pacman -S python2 - -Amazon Linux AMI Notes -~~~~~~~~~~~~~~~~~~~~~~ - -The packages ``pip`` and ``setuptools`` that come shipped by default are very -outdated. Thus, you first need to run: - -.. code-block:: bash - - $ pip install --upgrade pip setuptools - -The default installation is also missing the C and C++ compilers, which you -install by: - -.. code-block:: bash - - $ sudo yum install gcc gcc-c++ - -Then you should follow the regular installation instructions outlined at the -beginning of this page. - - -.. _MacOS: - -MacOS Requirements ------------------- - -The version of Python shipped with MacOS by default is generally out of date, -and has a number of quirks because it's used directly by the operating system. -For these reasons, many developers choose to install and use a separate Python -installation. The `Hitchhiker's Guide to Python`_ provides an excellent guide -to `Installing Python on MacOS `_, -which explains how to install Python with the `Homebrew`_ manager. - -Assuming you've installed Python with Homebrew, you'll also likely need the -following brew packages: - -.. code-block:: bash - - $ brew install freetype pkg-config gcc openssl - -MacOS + virtualenv/conda + matplotlib -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The first time that you try to run an algorithm that loads the ``matplotlib`` -library, you may get the following error: - -.. code-block:: text - - RuntimeError: Python is not installed as a framework. The Mac OS X backend - will not be able to function correctly if Python is not installed as a - framework. See the Python documentation for more information on installing - Python as a framework on Mac OS X. Please either reinstall Python as a - framework, or try one of the other backends. If you are using (Ana)Conda - please install python.app and replace the use of 'python' with 'pythonw'. - See 'Working with Matplotlib on OSX' in the Matplotlib FAQ for more - information. - -This is a ``matplotlib``-specific error, that will go away once you run the -following command: - -.. code-block:: bash - - $ echo "backend: TkAgg" > ~/.matplotlib/matplotlibrc - -in order to override the default ``MacOS`` backend for your system, which -may not be accessible from inside the virtual or conda environment. This will -allow Catalyst to open matplotlib charts from within a virtual environment, -which is useful for displaying the performance of your backtests. To learn more -about matplotlib backends, please refer to the -`matplotlib backend documentation `_. - -.. _windows: - -Windows Requirements --------------------- - -In Windows, you will first need to install the `Microsoft Visual C++ Compiler -for Python 2.7 -`_. This -package contains the compiler and the set of system headers necessary for -producing binary wheels for Python 2.7 packages. If it's not already in your -system, download it and install it before proceeding to the next step. - -Once you have the above compiler installed, the easiest and best supported way -to install Catalyst in Windows is to use :ref:`Conda `. If you didn't -any problems installing the compiler, jump to the :ref:`Conda ` section, -otherwise keep on reading to troubleshoot the C++ compiler installtion. - -Some problems we have encountered installing the **Visual C++ Compiler** -mentioned above are as follows: - -- **The system administrator has set policies to prevent this installation**. - - In some systems, there is a default *Windows Software Restriction* policy - that prevents the installation of some software packages like this one. - You'll have to change the Registry to circumvent this: - - - Click ``Start``, and search for ``regedit`` and launch the - ``Registry Editor`` - - Navigate to the following folder: - ``HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer`` - - If the last folder does not exist, create it by right-clicking on the - parent folder and choosing -> ``New`` -> ``Key`` and typing ``Installer`` - - If there is an entry for ``DisableMSI``, set the Value data to 0. - - If there is no such entry, click on the ``Edit`` menu -> ``New`` -> - ``DWORD (32-bit) Value`` and enter ``DisableMSI`` as the Name (and by - default you get 0 as the Value Data) - -| - -- **The installer has encountered an unexpected error installing this package. - This may indicate a problem with this package. The error code is 2503.** - - We have observed this when trying to install a package without enough - administrator permissions. Even when you are logged in as an Administrator, - you have to explictily install this package with administrator privileges: - - - Click ``Start`` and find ``CMD`` or ``Command Prompt`` - - Right click on it and choose ``Run as administrator`` - - ``cd`` into the folder where you downloaded ``VCForPython27.msi`` - - Run ``msiexec /i VCForPython27.msi`` - -Updating Catalyst ------------------ - -Catalyst is currently in alpha and in under very active development. We release -new minor versions every few days in response to the thorough battle testing -that our user community puts Catalyst in. As a result, you should expect to -update Catalyst frequently. Once installed, Catalyst can easily be updated as a -``pip`` package regardless of the environemnt used for installation. Make sure -you activate your environment first as you did in your first install, and then -execute: - -.. code-block:: bash - - $ pip uninstall enigma-catalyst - $ pip install enigma-catalyst - -Alternatively, you could update Catalyst issuing the following command: - -.. code-block:: bash - - $ pip install -U enigma-catalyst - -but this command will also upgrade all the Catalyst dependencies to the latest -versions available, and may have unexpected side effects if a newer version of a -dependency inadvertently breaks some functionality that Catalyst relies on. -Thus, the first method is the recommended one. - -Getting Help ------------- - -If after following the instructions above, and going through the -*Troubleshooting* sections, you still experience problems installing Catalyst, -you can seek additional help through the following channels: - -- Join our `Discord community `_, and head over - the #catalyst_dev channel where many other users (as well as the project - developers) hang out, and can assist you with your particular issue. The - more descriptive and the more information you can provide, the easiest will - be for others to help you out. - -- Report the problem you are experiencing on our - `GitHub repository `_ - following the guidelines provided therein. Before you do so, take a moment - to browse through all `previous reported issues - `_ - in the likely case that someone else experienced that same issue before, - and you get a hint on how to solve it. - - -.. _`Debian-derived`: https://www.debian.org/misc/children-distros -.. _`RHEL-derived`: https://en.wikipedia.org/wiki/Red_Hat_Enterprise_Linux_derivatives -.. _`Arch Linux` : https://www.archlinux.org/ -.. _`Hitchhiker's Guide to Python` : http://docs.python-guide.org/en/latest/ -.. _`Homebrew` : http://brew.sh diff --git a/_sources/live-trading.rst.txt b/_sources/live-trading.rst.txt deleted file mode 100644 index d503b7eb..00000000 --- a/_sources/live-trading.rst.txt +++ /dev/null @@ -1,179 +0,0 @@ -Live Trading -============ -This document explains how to get started with live trading. - -Supported Exchanges -^^^^^^^^^^^^^^^^^^^ - -Since version 0.4, Catalyst integrated with `CCXT `_, -a cryptocurrency trading library with support for more than 90 exchanges. The -range of CCXT and Catalyst support for each of those exchanges varies greatly. -The most supported exchanges are as follows: - -The exchanges available for backtesting are fully supported in live mode: - -- Bitfinex, id = ``bitfinex`` -- Bittrex, id = ``bittrex`` -- Poloniex, id = ``poloniex`` - -Additionally, we have successfully tested the following exchanges: - -- Binance, id = ``binance`` -- Bitmex, id = ``bitmex`` -- GDAX, id = ``gdax`` - -As Catalyst is currently in Alpha and in under active development, you are -encouraged to throughly test any exchange in *paper trading* mode before trading -*live* with it. - -Paper Trading vs Live Trading modes -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Catalyst currently supports three different modes in which you can execute your -trading algorithm. The first is backtesting, which is covered extensively in the -tutorial, and uses historical data to run your algorithm. There is no -interaction with the exchange in backtesting mode, and this is the first mode -that you should test any new algorithm. - -Once you are confident with the simulations that you have obtained with your -algorithm in backtesting, you may switch to live trading, where you have two -different modes: -* *Paper Trading*: The simulated algorithm runs in real time, and fetches -pricing data in real time from the exchange, but the orders never reach the -exchange, and are instead kept within Catalyst and simulated. No real currency -is bought or sold. Think of it as a `backtesting happening in real time`. -* *Live Trading*: This is the proper live trading mode in which an algorithm -runs in real time, fetching pricing data from live exchanges and placing orders -against the exchange. Real currency is transacted on the exchange driven by the -algorithm. - -These three modes are controlled by the following variables: - -+---------------+-------------------------+ -| Mode | Parameters | -+ +-------+-----------------+ -| | live | simulate_orders | -+---------------+-------+-----------------+ -| backtesting | False | True (default) | -+---------------+-------+-----------------+ -| paper trading | True | True | -+---------------+-------+-----------------+ -| live trading | True | False | -+---------------+-------+-----------------+ - - -Authentication -^^^^^^^^^^^^^^ -Most exchanges require token key/secret combination for authentication. By -convention, Catalyst uses an ``auth.json`` file to hold this data. - -This example illustrates the convention using the *Bitfinex* exchange. -Here is how to generate key and secret values for the Bitfinex exchange: -https://docs.bitfinex.com/v1/docs/api-access. Most exchanges follow -a similar process. - -The auth.json file: - -.. code-block:: json - - { - "name": "bitfinex", - "key": "my-key", - "secret": "my-secret" - } - - -The file goes here: ``~/.catalyst/data/exchanges/bitfinex/auth.json`` - -Note that the `bitfinex` part in the directory above corresponds to the id of the Bitfinex -exchange as defined in the "Supported Exchanges" section above. -Attempting to run an algorithm where the targeted exchange is missing -its ``auth.json`` file will create the directory structure and create an empty -auth.json file, but will result in an error. - -Currency Symbols -^^^^^^^^^^^^^^^^ -Catalyst introduces a universal convention to reference -trading pairs and individual currencies. This -is required to ensure that the ``symbol()`` api predictably -returns the correct asset regardless of the targeted exchange. - -Exchanges tend to use their own convention to represent currencies -(e.g. XBT and BTC both represent Bitcoin on different exchanges). -Trading pairs are also inconsistent. For example, Bitfinex -puts the market currency before the base currency without a -separator, Bittrex puts the base currency first and uses a dash -seperator. - -Here is the Catalyst convention: - -*[Market Currency]_[Base Currency]* all lowercase. - -Currency symbols (e.g. btc, eth, ltc) follow the Bittrex convention. - -Here are some examples: - -.. code:: python - - # With Bitfinex - bitcoin_usd_asset = symbol('btc_usd') - ethereum_bitcoin_asset = symbol('eth_btc') - - # With Bittrex - ethereum_bitcoin_asset = symbol('eth_btc') - neo_ethereum_asset = symbol('neo_eth) - -Note that the trading pairs are always referenced in the same manner. -However, not all trading pairs are available on all exchanges. An -error will occur if the specified trading pair is not trading -on the exchange. To check which currency pairs are available on each -of the supported exchanges, see -`Catalyst Market Coverage `_. - -Trading an Algorithm -^^^^^^^^^^^^^^^^^^^^ -There is no special convention to follow when writing an -algorithm for live trading. The same algorithm should work in -backtest and live execution mode without modification. - -What differs are the arguments provided to the catalyst client or -`run_algorithm()` interface. Here is the same example in both interfaces: - -.. code-block:: bash - - catalyst live -f my_algo_code -x bitfinex -c btc -n my_algo_name - -.. code-block:: python - - run_algorithm( - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='bitfinex', - live=True, - algo_namespace='my_algo_name', - base_currency='btc' - ) - - -Here is the breakdown of the new arguments: - -- ``live``: Boolean flag which enables live trading. It defaults to ``False``. -- ``capital_base``: The amount of base_currency assigned to the strategy. - It has to be lower or equal to the amount of base currency available for - trading on the exchange. For illustration, order_target_percent(asset, 1) - will order the capital_base amount specified here of the specified asset. -- ``exchange_name``: The name of the targeted exchange. See the - `CCXT Supported Exchanges `_ - for the full list. -- ``algo_namespace``: A arbitrary label assigned to your algorithm for - data storage purposes. -- ``base_currency``: The base currency used to calculate the - statistics of your algorithm. Currently, the base currency of all - trading pairs of your algorithm must match this value. -- ``simulate_orders``: Enables the paper trading mode, in which orders are - simulated in Catalyst instead of processed on the exchange. It defaults to - ``True``. - -Here is a complete algorithm for reference: -`Buy Low and Sell High `_ diff --git a/_sources/release-process.rst.txt b/_sources/release-process.rst.txt deleted file mode 100644 index 02e9f419..00000000 --- a/_sources/release-process.rst.txt +++ /dev/null @@ -1,263 +0,0 @@ -Release Process ---------------- - -.. include:: dev-doc-message.txt - - -Updating the Release Notes -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When we are ready to ship a new release of zipline, edit the :doc:`releases` -page. We will have been maintaining a whatsnew file while working on the release -with the new version. First, find that file in: -``docs/source/whatsnew/.txt``. It will be the highest version number. -Edit the release date field to be today's date in the format: - -:: - - , - - -for example, November 6, 2015. -Remove the active development warning from the whatsnew, since it will no -longer be pending release. -Update the title of the release from "Development" to "Release x.x.x" and -update the underline of the title to match the title's width. - -If you are renaming the release at this point, you'll need to git mv the file -and also update releases.rst to reference the renamed file. - -To build and view the docs locally, run: - -.. code-block:: bash - - $ cd docs - $ make html - $ {BROWSER} build/html/index.html - -Updating the Python stub files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -PyCharm and other linters and type checkers can use `Python stub files -`__ for type hinting. For -example, we generate stub files for the :mod:`~zipline.api` namespace, since that -namespace is populated at import time by decorators on TradingAlgorithm -methods. Those functions are therefore hidden from static analysis tools, but -we can generate static files to make them available. Under **Python 3**, run -the following to generate any stub files: - -.. code-block:: bash - - $ python etc/gen_type_stubs.py - -.. note:: - - In order to make stub consumers aware of the classes referred to in the - stub, the stub file should import those classes. However, since - ``... import *`` and ``... import ... as ...`` in a stub file will export - those imports, we import the names explicitly. For the stub for - ``zipline.api``, this is done in a header string in the - ``gen_type_stubs.py`` script mentioned above. If new classes are added as - parameters or return types of ``zipline.api`` functions, then new imports - should be added to that header. - -Updating the ``__version__`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -We use `versioneer `__ to -manage the ``__version__`` and ``setup.py`` version. This means that we pull -this information from our version control's tags to ensure that they stay in -sync and to have very fine grained version strings for development installs. - -To upgrade the version use the git tag command like: - -.. code-block:: bash - - $ git tag .. - $ git push && git push --tags - - -This will push the the code and the tag information. - -Next, click the "Draft a new release" button on the `zipline releases page -`__. For the new release, -choose the tag you just pushed, and publish the release. - -Uploading PyPI packages -~~~~~~~~~~~~~~~~~~~~~~~ - -``sdist`` -^^^^^^^^^ - -To build the ``sdist`` (source distribution) run: - -.. code-block:: bash - - $ python setup.py sdist - - -from the zipline root. This will create a gzipped tarball that includes all the -python, cython, and miscellaneous files needed to install zipline. To test that -the source dist worked correctly, ``cd`` into an empty directory, create a new -virtualenv and then run: - - -.. code-block:: bash - - $ pip install /dist/zipline-...tar.gz - $ python -c 'import zipline;print(zipline.__version__)' - -This should print the version we are expecting to release. - -.. note:: - - It is very important to both ``cd`` into a clean directory and make a clean - virtualenv. Changing directories ensures that we have included all the needed - files in the manifest. Using a clean virtualenv ensures that we have listed - all the required packages. - -Now that we have tested the package locally, it should be tested using the test -PyPI server. - -Edit your ``~/.pypirc`` file to look like: - -:: - - [distutils] - index-servers = - pypi - pypitest - - [pypi] - username: - password: - - [pypitest] - repository: https://testpypi.python.org/pypi - username: - password: - -after that, run: - -.. code-block:: bash - - $ python setup.py sdist upload -r pypitest - - -.. note:: - - If the package version has been taken: locally update your setup.py to - override the version with a new number. Do not use the next version, just - append a ``.`` section to the current version. PyPI prevents the same - package version from appearing twice, so we need to work around this when - debugging packaging problems on the test server. - - .. warning:: - - Do not commit the temporary version change. - - -This will upload zipline to the pypi test server. To test installing from pypi, -create a new virtualenv, ``cd`` into a clean directory and then run: - -.. code-block:: bash - - $ pip install --extra-index-url https://testpypi.python.org/pypi zipline - $ python -c 'import zipline;print(zipline.__version__)' - - -This should pull the package you just uploaded and then print the version -number. - -Now that we have tested locally and on PyPI test, it is time to upload to PyPI: - -.. code-block:: bash - - $ python setup.py sdist upload - -``bdist`` -^^^^^^^^^ - -Because zipline now supports multiple versions of numpy, we're not building -binary wheels, since they are not tagged with the version of numpy with which -they were compiled. - -Documentation -~~~~~~~~~~~~~ - -To update `zipline.io `__, checkout the -latest master and run: - -.. code-block:: python - - python /docs/deploy.py - -This will build the documentation, checkout a fresh copy of the ``gh-pages`` -git branch, and copy the built docs into the zipline root. - -.. note:: - - The docs should always be built with **Python 3**. Many of our api functions - are wrapped by preprocessing functions which accept \*args and \**kwargs. In - Python 3, sphinx will respect the ``__wrapped__`` attribute and display the - correct arguments. - -Now, using our browser of choice, view the ``index.html`` page and verify that -the docs look correct. - -Once we are happy, push the updated docs to the GitHub ``gh-pages`` branch. - -.. code-block:: bash - - $ git add . - $ git commit -m "DOC: update zipline.io" - $ git push origin gh-pages - -`zipline.io `__ will update in a few moments. - -Uploading conda packages -~~~~~~~~~~~~~~~~~~~~~~~~ - -Travis and AppVeyor build zipline conda packages for us. Once they have built -and uploaded to anaconda.org the packages (and their dependencies) for the -release commit to master, we should move those packages from the "ci" label to -the "main" label. You can do this from the anaconda.org web interface. This -is also a good time to remove all the old "ci" packages from anaconda. - -Travis and AppVeyor only build and upload linux-64 and win-64 packages. We'll -need to build and upload osx-64 packages manually on an OSX machine. - -To build the conda packages for zipline locally, run: - -.. code-block:: bash - - $ python etc/conda_build_matrix.py - -If all of the builds succeed, then this will not print anything and exit with -``EXIT_SUCCESS``. If there are build issues, we must address them and decide -what to do. - -Once all of the builds in the matrix pass, we can upload them to anaconda with: - -.. code-block:: bash - - $ python etc/conda_build_matrix.py --upload - -If you would like to test this command by uploading to a different user, this -may be specified with the ``--user`` flag. - -Next Commit -~~~~~~~~~~~ - -Push a new commit post-release that adds the whatsnew for the next release, -which should be titled according to a micro version increment. If that next -release turns out to be a major/minor version increment, the file can be -renamed when that's decided. You can use ``docs/source/whatsnew/skeleton.txt`` -as a template for the new file. - -Include the whatsnew file in ``docs/source/releases.rst``. New releases should -appear at the top. The syntax for this is: - -:: - - .. include:: whatsnew/.txt diff --git a/_sources/releases.rst.txt b/_sources/releases.rst.txt deleted file mode 100644 index 7c5dca1d..00000000 --- a/_sources/releases.rst.txt +++ /dev/null @@ -1,390 +0,0 @@ -============= -Release Notes -============= - -Version 0.5.2 -^^^^^^^^^^^^^ -**Release Date**: 2018-02-08 - -Bug Fixes -~~~~~~~~~ -- Fixed an issue with live candle values :issue:`216` and :issue:`199` - -Version 0.5.1 -^^^^^^^^^^^^^ -**Release Date**: 2018-02-07 - -Bug Fixes -~~~~~~~~~ -- Fixed an issue with orders that stay open :issue:`211` -- Fixed Jupyter issues :issue:`179` -- Fetching multiple tickers in one call to minimize rate limit risks :issue:`174` -- Improved live state presentation :issue:`171` - - -Build -~~~~~ -- Introducing the Enigma Marketplace - -Version 0.4.7 -^^^^^^^^^^^^^ -**Release Date**: 2018-01-19 - -Bug Fixes -~~~~~~~~~ -- Fixing issue :issue:`137` impacting the CLI - -Build -~~~~~ -- Implemented authentication aliases (:issue:`60`) - -Version 0.4.6 -^^^^^^^^^^^^^ -**Release Date**: 2018-01-18 - -Bug Fixes -~~~~~~~~~ -- Fixed some Python3 issues -- Reading the trade log to get executed order prices on exchanges like Binance (:issue:`151`) -- Fixed issue with market order executing price (:issue:`150` and :issue:`111`) -- Implemented standardized symbol mapping (:issue:`157`) -- Improved error handling for unsupported timeframes (:issue:`159`) -- Using Bitfinex instead of Poloniex to fetch btc_usdt benchmark (:issue:`161`) - - -Build -~~~~~ -- Added a `context.state` dict to keep arbitrary state values between runs -- Added ability to stop live algo at specified end date - -Version 0.4.5 -^^^^^^^^^^^^^ -**Release Date**: 2018-01-12 - -Bug Fixes -~~~~~~~~~ -- Improved order execution for exchanges supporting trade lists (:issue:`151`) -- Fixed an issue where requesting history of multiple assets repeats values -- Raising an error for order amounts smaller than exchange lots -- Handling multiple req errors with tickers more gracefully (:issue:`160`) - -Version 0.4.4 -^^^^^^^^^^^^^ -**Release Date**: 2018-01-09 - -Bug Fixes -~~~~~~~~~ -- Removed redundant capital_base validation (:issue:`142`) -- Fixed portfolio update issue with restored state (:issue:`111`) -- Skipping cash validation where there are open orders (:issue:`144`) - -Version 0.4.3 -^^^^^^^^^^^^^ -**Release Date**: 2018-01-05 - -Bug Fixes -~~~~~~~~~ -- Fixed CLI issue (:issue:`137`) -- Upgraded CCXT - -Version 0.4.2 -^^^^^^^^^^^^^ -**Release Date**: 2018-01-03 - -Bug Fixes -~~~~~~~~~ -- Fixed cash synchronization issue (:issue:`133`) -- Fixed positions synchronization issue (:issue:`132`) -- Patched empyrical to resolve a np.log1p issue (:issue:`126`) -- Fixed a paper trading issue (:issue:`124`) -- Fixed a commission issue (:issue:`104`) -- Fixed a poloniex specific issue in live trading (:issue:`103`) - -Build -~~~~~ -- Caching CCXT market info to limit round-trips (:issue:`99`) -- Tentative support for Pipeline (:issue:`96`) - -Version 0.4.0 -^^^^^^^^^^^^^ -**Release Date**: 2017-12-12 - -Bug Fixes -~~~~~~~~~ - -- Changed Poloniex interface (should solve :issue:`95` and :issue:`94`) -- Solved issue with overriding commission and slippage (:issue:`87`) -- Fixed inefficiency with Bittrex current prices (:issue:`76`) - -Build -~~~~~ -- Integrated with CCXT -- Added paper trading capability (`simulate_orders=True` param in live mode) -- More granular commissions (:issue:`82`) -- Added market orders in live mode (:issue:`81`) - -Version 0.3.10 -~~~~~~~~~~~~~~ -**Release Date**: 2017-11-28 - -Bug Fixes -~~~~~~~~~ - -- Fixed issue with fetching assets with daily frequency - -Version 0.3.9 -^^^^^^^^^^^^^ -**Release Date**: 2017-11-28 - -Bug Fixes -~~~~~~~~~ - -- Fixed sortino warning issues (:issue:`77`) -- Adjusted computation of last candle of data.history (:issue:`71`) - -Build -~~~~~ -- Added capital_base parameter to live mode to limit cash (:issue:`79`) -- Added support for csv ingestion (:issue:`65`) -- Improved cash display in running stats (:issue:`80`) - - -Version 0.3.8 -^^^^^^^^^^^^^ -**Release Date**: 2017-11-14 - -Bug Fixes -~~~~~~~~~ - -- Fixed a warning filter issue introduced with the latest release - -Version 0.3.7 -^^^^^^^^^^^^^ -**Release Date**: 2017-11-14 - -Bug Fixes -~~~~~~~~~ - -- Fixed an SSL cert issue (:issue:`64`) -- Fixed cumulative stats warnings (:issue:`63`) -- Disabled auto-ingestion because of unresolved caching issues (:issue:`47`) -- Standardized live-trading stats (:issue:`61`) - -Build -~~~~~ - -- Added a mean-reversion sample algo -- Added minutely stats in the analyze() function (:issue:`62`) -- Added specificity to some error messages - -Version 0.3.6 -^^^^^^^^^^^^^ -**Release Date**: 2017-11-4 - -Bug Fixes -~~~~~~~~~ - -- Fixed an issue with single bar data.history() (:issue:`55`) - -Version 0.3.5 -^^^^^^^^^^^^^ -**Release Date**: 2017-11-4 - -Bug Fixes -~~~~~~~~~ - -- Added workaround for: KeyError: Timestamp error (:issue:`53`) - -Version 0.3.4 -^^^^^^^^^^^^^ -**Release Date**: 2017-11-2 - -Bug Fixes -~~~~~~~~~ - -- Fixed issue with auto-ingestion of minute data (:issue:`47`) -- Fixed issue with sell orders in backtesting -- Fixed data frequency issues with data.history() in backtesting -- Fixed an issue with can_trade() -- Reduced the commission and slippage values to account for lower volume - transactions - -Build -~~~~~ - -- Added more unit tests - -Documentation -~~~~~~~~~~~~~ - -- Improved installation notes for Windows C++ compiler and Conda -- Addition of - `Jupyter Notebook guide `_ -- Addition of - `Live Trading page `_ -- Addition of - `Videos page `_ -- Addition of - `Resources page `_ -- Addition of `Development Guidelines - `_ -- Addition of - `Release Notes `_ -- Updated code docstrings - - -Version 0.3.3 -^^^^^^^^^^^^^ -**Release Date**: 2017-10-26 - -Bug Fixes -~~~~~~~~~ - -- Fix missing -x in ingest-exchange -- Fix issue with daily chunks end date (data bundles) -- Fix issue in the prepare_chunk logic (data bundles) - -Build -~~~~~ - -- Added data validation unit tests - - -Version 0.3.2 -^^^^^^^^^^^^^ -**Release Date**: 2017-10-25 - -Bug Fixes -~~~~~~~~~ - -- Fix to work with empty data bundles -- Fix Windows path of ``$HOME/.catalyst`` folder -- Fix ``etc/python2.7-environment.yml`` for Windows Conda install -- Fix hash method to create sid numbers compatible across platforms -- Fix an issue with asset date in chunks - -Build -~~~~~ - -- Python3 adjustments -- Added method to clean bundle folders, and remove symbols.json -- Implemented and improved unit tests - - -Version 0.3.1 -^^^^^^^^^^^^^ -**Release Date**: 2017-10-22 - -Bug Fixes -~~~~~~~~~ - -- Fixed OS-dependent path issue in data bundle -- Changed handling of empty ``auth.json``, instead of throwing an error for - missing file -- Updated ``etc/python2.7-environment.yml`` to work with Catalyst version 0.3 -- Updated ``catalyst/examples/buy_and_hodl.py`` and - ``catalyst/examples/buy_low_sell_high.py`` to work with Catalyst version 0.3 - - -Version 0.3 -^^^^^^^^^^^ -**Release Date**: 2017-10-20 - -- Standardized live and backtesting syntax -- Added a repository for historical data -- Added supported for multiple exchanges per algorithm -- Added a standardized dictionary of symbols for each exchange -- Added auto-ingestion of bundle data while backtesting -- Bug fixes - - -Version 0.2.dev5 -^^^^^^^^^^^^^^^^ -**Release Date**: 2017-10-03 - -- Fixes bug in data.history function that was formatting 'volume' data as - integers, now they are returned as floats with up to 9 decimals of precision. - Data bundles redone. - -Version 0.2.dev4 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-09-20 - -- Fixes bug in the pricing resolution of 1-minute data, now set to 8 decimal - places. Pricing resolution of daily data remains set to 9 decimal places. -- The current data bundle takes 340MB compressed for download, and 460MB - uncompressed on disk for Catalyst to use. - -Version 0.2.dev3 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-09-20 - -- 1-minute resolution OHLCV data bundle for backtesting from Poloniex exchange -- Implementation of trading of fractional crypto assets (i.e. 0.01 BTC) -- Minimum trade size of a coin can be configured on a per-coin basis, defaults - to 0.00000001 in backtesting (most exchanges set the minimum trade to larger - amounts, which will impact live trading) -- Increased pricing resolution from 3 to 9 decimal places -- The current data bundle takes 40MB compressed for download, and 99MB - uncompressed on disk for Catalyst to use. - -Version 0.2.dev2 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-09-07 - -- Fix path issue - -Version 0.2.dev1 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-09-03 - -- Implementation of live trading: - - - Comprehensive trading functionality against exchanges Bitfinex and Bittrex. - - Support for all trading pairs available on each exchange. - - Multiple algorithms can trade simultaneously against a single exchange - using the same account. - - Each algorithm has a persisted state (i.e. algorithm can be stopped and - restarted preserving the state without data loss) that tracks all open - orders, executed transactions and portfolio positions. - -- Minute by minute portfolio performance metrics. - - - Daily summary performance statistics compatible with pyfolio, a Python - library for performance and risk analysis of financial portfolios - -Version 0.1.dev9 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-08-28 - -- Retrieval of crypto benchmark from bundle, instead of hitting Poloniex - exchange directly -- Change of bundle storage provider from Dropbox to AWS -- Fix issue with 1/1000 scaling issue of prices in bundle - -Version 0.1.dev8 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-08-18 - -- Fixes issue in the creation of bundles (:issue:`27`) - - -Version 0.1.dev7 -^^^^^^^^^^^^^^^^ -- Fixes issues in empty benchmark (:issue:`16`) -- Fixes issue of normalizing timestamps before comparison (:issue:`24`) -- Generic data bundles -- CLI UI improvements - -Version 0.1.dev6 -^^^^^^^^^^^^^^^^ - -**Release Date**: 2017-07-13 - -- Initial public release diff --git a/_sources/resources.rst.txt b/_sources/resources.rst.txt deleted file mode 100644 index eb1580a5..00000000 --- a/_sources/resources.rst.txt +++ /dev/null @@ -1,26 +0,0 @@ -Resources -========= - -- `Catalyst Whitepaper `_ - - -Related 3rd Party APIs -^^^^^^^^^^^^^^^^^^^^^^ - -- `Zipline `_ is a Pythonic Algorithmic - Trading Library, and the project Catalyst forked off in the spring of 2017. -- `Quantopian `_ provides a platform for - freelance quantitative analysts develop, test, and use trading algorithms to - buy and sell securities. They aim to create a crowd-sourced hedge fund by - fostering their community of freelance traders. Quantopian's backtesting and - live-trading engine is powered by *Zipline*. -- `Pandas `_ is a Python - library providing high-performance, easy-to-use data structures and data - analysis tools. Catalyst relies heavily on pandas, and many API functions - return data as Pandas dataframes. -- `Numpy `_ is the fundamental - package for scientific computing with Python. Some of the data computation - that your algorithms will need, will be optimized leveraging Numpy. -- `Matplotlib `_ is a Python 2D - plotting library that many of examples rely on to plot the performance of - trading algorithms diff --git a/_sources/unit-tests.rst.txt b/_sources/unit-tests.rst.txt deleted file mode 100644 index 1da822f1..00000000 --- a/_sources/unit-tests.rst.txt +++ /dev/null @@ -1,88 +0,0 @@ -========== -Unit Tests -========== - -Exchanges -~~~~~~~~~ - -Markets -------- -Sample: - All markets in 3 random exchanges -Test: - Fetch all TradingPair instances -Assert: - No error - -Current Ticker ------------------- -Sample: - 3 random markets in each of the 3 random exchanges -Test: - Fetch current price and volume -Assert: - Not null and no error - -Historical Price Data ---------------------- -Sample: - - 3 random markets for each of the 3 random exchanges supporting historical data - - For each market, randomly select one supported frequency -Test: - Fetch historical data for each market using the selected frequency -Assert: - - No error and not blank - - Date of each candle is consistent with the Catalyst desired pattern, - - All candle start at fix intervals - - Last candle partial and forward looking from the end date - -Authentication and Orders -------------------------- -Sample: - 1 random market for each of 3 random authenticated exchanges -Test: - - Create one limit order randomly buying or selling at least 10% out from the current price - - Retrieve the open order from the exchange - - Cancel the open order -Assert: - No error - - -Bundles -~~~~~~~ - -Validate Bundle Data --------------------- -Sample: - - 3 random market in bundles for exchanges supporting historical data - - For each market, randomly selected data range available in the exchange historical data -Test: - - Clean the target exchange bundle - - Ingest the selected market data for the selected data range - - Retrieve the bundle data into a dataframe - - Retrieve the equivalent OHLCV data from the exchange into a dataframe -Assert: - Matching data for the bundle and exchange - - -Algo Stats ----------- -Sample: - - 2 sample algorithms with built-in stats calculator - - 2 KPIs both calculated by each algo and by Catalyst -Test: - - Run each algorithm - - Compare the results of the two methods or calculating stats -Assert: - - Matching stats - -CSV Ingestion -------------- -Sample: - 3 random CSV files containing price data -Test: - - Ingest each CSV files - - Validate with the exchange like in the 'Validate Bundle Data' test -Assert: - Matching data between the bundle and the exchange - diff --git a/_sources/utilities.rst.txt b/_sources/utilities.rst.txt deleted file mode 100644 index 8c89aa52..00000000 --- a/_sources/utilities.rst.txt +++ /dev/null @@ -1,149 +0,0 @@ -Utilities -========= - -This section covers a variety of utilites that provide complimentary -functionality to your trading algorithms. These are code snippets that you can -add to any algorithm to add the desired functionality. - -If you are looking for example trading algorithms, see the corresponding section. - -Output to CSV file -~~~~~~~~~~~~~~~~~~ - -Add this script to the analyze method to create and save a CSV file with the -results from the trading algorithm. This file will include the default -parameters of the results DataFrame plus any recorded variables and will be -saved in the same location where your trading algorithm is saved. The exact -script that you need to use depends on the interface that you are using to run -your trading algorithm, which could be the CLI or a Python Interpreter. - -1. Script to use with CLI: - - .. code-block:: python - - def analyze(context=None, results=None): - import sys - import os - from os.path import basename - - # Save results in CSV file - filename = os.path.splitext(basename(sys.argv[3]))[0] - results.to_csv(filename + '.csv') - -2. Script to use with Python Interpreter: - - .. code-block:: python - - def analyze(context=None, results=None): - import os - from os.path import basename - - # Save results in CSV file - filename = os.path.splitext(os.path.basename(__file__))[0] - results.to_csv(filename + '.csv') - -Extracting market data -~~~~~~~~~~~~~~~~~~~~~~ - -Use this script to save the price and volume data of one cryptoasset in a CSV -file, which will be saved in the same location and with the same name as your -Python file. To get custom data, simply modify the asset's symbol and the dates. -Run this script directly from your development environment: python scriptname.py, -where the contents of 'scriptname.py' are as follows. Two different version are -provided as an example for daily- and minute-resolution data respectively: - -Simpler case for daily data - -.. code-block:: python - - import os - import pytz - from datetime import datetime - - from catalyst.api import record, symbol, symbols - from catalyst.utils.run_algo import run_algorithm - - def initialize(context): - # Portfolio assets list - context.asset = symbol('btc_usdt') # Bitcoin on Poloniex - - def handle_data(context, data): - # Variables to record for a given asset: price and volume - price = data.current(context.asset, 'price') - volume = data.current(context.asset, 'volume') - record(price=price, volume=volume) - - def analyze(context=None, results=None): - - # Generate DataFrame with Price and Volume only - data = results[['price','volume']] - - # Save results in CSV file - filename = os.path.splitext(os.path.basename(__file__))[0] - data.to_csv(filename + '.csv') - - ''' Bitcoin data is available on Poloniex since 2015-3-1. - Dates vary for other tokens. In the example below, we choose the - full month of July of 2017. - ''' - start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc) - end = datetime(2017, 7, 31, 0, 0, 0, 0, pytz.utc) - results = run_algorithm(initialize=initialize, - handle_data=handle_data, - analyze=analyze, - start=start, - end=end, - exchange_name='poloniex', - capital_base=10000, - base_currency = 'usdt') - -More versatile case for minute data - -.. code-block:: python - - import os - import csv - import pytz - from datetime import datetime - - from catalyst.api import record, symbol, symbols - from catalyst.utils.run_algo import run_algorithm - - - def initialize(context): - # Portfolio assets list - context.asset = symbol('btc_usdt') # Bitcoin on Poloniex - - # Creates a .CSV file with the same name as this script to store results - context.csvfile = open(os.path.splitext( - os.path.basename(__file__))[0]+'.csv', 'w+') - context.csvwriter = csv.writer(context.csvfile) - - def handle_data(context, data): - # Variables to record for a given asset: price and volume - # Other options include 'open', 'high', 'open', 'close' - # Please note that 'price' equals 'close' - date = context.blotter.current_dt # current time in each iteration - price = data.current(context.asset, 'price') - volume = data.current(context.asset, 'volume') - - # Writes one line to CSV on each iteration with the chosen variables - context.csvwriter.writerow([date,price,volume]) - - def analyze(context=None, results=None): - # Close open file properly at the end - context.csvfile.close() - - - # Bitcoin data is available from 2015-3-2. Dates vary for other tokens. - start = datetime(2017, 7, 30, 0, 0, 0, 0, pytz.utc) - end = datetime(2017, 7, 31, 0, 0, 0, 0, pytz.utc) - results = run_algorithm(initialize=initialize, - handle_data=handle_data, - analyze=analyze, - start=start, - end=end, - exchange_name='poloniex', - data_frequency='minute', - base_currency ='usdt', - capital_base=10000 ) \ No newline at end of file diff --git a/_sources/videos.rst.txt b/_sources/videos.rst.txt deleted file mode 100644 index 0beb291b..00000000 --- a/_sources/videos.rst.txt +++ /dev/null @@ -1,63 +0,0 @@ -Videos -====== - - -Installation: MacOS -------------------- - -.. raw:: html - - - -| -| - -Installation: Windows ---------------------- - -Where things go smoothly: - -.. raw:: html - - - -| - -Where things don't: - -.. raw:: html - - - -| -| - -Backtesting a Strategy ----------------------- - -This is the first video of a two-part series on using Catalyst for algorithmic -trading. This video implements a simple momentum strategy based on -`mean reversion `_: when the cryptoasset -goes up quickly, we’re going to buy; when it goes down quickly, we’re going to -sell. Hopefully, we’ll ride the waves. - -.. raw:: html - - - -| -| - -Live Trading a Strategy ------------------------ - -This is the second part of the two-part series on using Catalyst for algorithmic -trading. Having backtested `our strategy `_ -in the previous video, we now take it to trade live against the Bittrex exchange. - -.. raw:: html - - - -| -| diff --git a/_static/basic.css b/_static/basic.css index 607b5f55..9fa77d88 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -52,8 +52,6 @@ div.sphinxsidebar { width: 230px; margin-left: -100%; font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; } div.sphinxsidebar ul { @@ -85,6 +83,10 @@ div.sphinxsidebar #searchbox input[type="text"] { width: 170px; } +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + img { border: 0; max-width: 100%; @@ -122,8 +124,6 @@ ul.keywordmatches li.goodmatch a { table.contentstable { width: 90%; - margin-left: auto; - margin-right: auto; } table.contentstable p.biglink { @@ -151,14 +151,9 @@ table.indextable td { vertical-align: top; } -table.indextable ul { +table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; - list-style-type: none; -} - -table.indextable > tbody > tr > td > ul { - padding-left: 0em; } table.indextable tr.pcap { @@ -190,22 +185,8 @@ div.genindex-jumpbox { padding: 0.4em; } -/* -- domain module index --------------------------------------------------- */ - -table.modindextable td { - padding: 2px; - border-collapse: collapse; -} - /* -- general body styles --------------------------------------------------- */ -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - a.headerlink { visibility: hidden; } @@ -231,6 +212,10 @@ div.body td { text-align: left; } +.field-list ul { + padding-left: 1em; +} + .first { margin-top: 0 !important; } @@ -332,11 +317,6 @@ table.docutils { border-collapse: collapse; } -table.align-center { - margin-left: auto; - margin-right: auto; -} - table caption span.caption-number { font-style: italic; } @@ -352,6 +332,10 @@ table.docutils td, table.docutils th { border-bottom: 1px solid #aaa; } +table.field-list td, table.field-list th { + border: 0 !important; +} + table.footnote td, table.footnote th { border: 0 !important; } @@ -388,27 +372,6 @@ div.figure p.caption span.caption-number { div.figure p.caption span.caption-text { } -/* -- field list styles ----------------------------------------------------- */ - -table.field-list td, table.field-list th { - border: 0 !important; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} /* -- other body styles ----------------------------------------------------- */ @@ -450,19 +413,24 @@ dd { margin-left: 30px; } -dt:target, span.highlighted { +dt:target, .highlighted { background-color: #fbe54e; } -rect.highlighted { - fill: #fbe54e; -} - dl.glossary dt { font-weight: bold; font-size: 1.1em; } +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + .optional { font-size: 1.3em; } @@ -521,13 +489,6 @@ pre { overflow-y: hidden; /* fixes display issues on Chrome browsers */ } -span.pre { - -moz-hyphens: none; - -ms-hyphens: none; - -webkit-hyphens: none; - hyphens: none; -} - td.linenos pre { padding: 5px 0px; border: 0; @@ -619,16 +580,6 @@ span.eqno { float: right; } -span.eqno a.headerlink { - position: relative; - left: 0px; - z-index: 1; -} - -div.math:hover a.headerlink { - visibility: visible; -} - /* -- printout stylesheet --------------------------------------------------- */ @media print { diff --git a/_static/comment-bright.png b/_static/comment-bright.png index 15e27edb..551517b8 100644 Binary files a/_static/comment-bright.png and b/_static/comment-bright.png differ diff --git a/_static/comment-close.png b/_static/comment-close.png index 4d91bcf5..09b54be4 100644 Binary files a/_static/comment-close.png and b/_static/comment-close.png differ diff --git a/_static/comment.png b/_static/comment.png index dfbc0cbd..92feb52b 100644 Binary files a/_static/comment.png and b/_static/comment.png differ diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css index 6362912b..7e17fb14 100644 --- a/_static/css/badge_only.css +++ b/_static/css/badge_only.css @@ -1,2 +1,2 @@ -.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} +.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}} /*# sourceMappingURL=badge_only.css.map */ diff --git a/_static/css/theme.css b/_static/css/theme.css index c1631d84..57b98fe6 100644 --- a/_static/css/theme.css +++ b/_static/css/theme.css @@ -1,5 +1,5 @@ -*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,.rst-content .toctree-wrapper p.caption,h3{orphans:3;widows:3}h2,.rst-content .toctree-wrapper p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! - * Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome +*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,.rst-content tt,.rst-content code,kbd,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol,dl{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0;white-space:normal}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*width:13px;*height:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:0.2em 0;background:#ccc;color:#000;padding:0.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none !important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{html,body,section{background:none !important}*{box-shadow:none !important;text-shadow:none !important;filter:none !important;-ms-filter:none !important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,.rst-content p.caption,h3{orphans:3;widows:3}h2,.rst-content p.caption,h3{page-break-after:avoid}}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo,.btn,input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"],select,textarea,.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a,.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a,.wy-nav-top a{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.6.3");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff2?v=4.6.3") format("woff2"),url("../fonts/fontawesome-webfont.woff?v=4.6.3") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.6.3") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.wy-menu-vertical li span.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-left.toctree-expand,.wy-menu-vertical li.current>a span.fa-pull-left.toctree-expand,.rst-content .fa-pull-left.admonition-title,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content dl dt .fa-pull-left.headerlink,.rst-content p.caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.rst-content code.download span.fa-pull-left:first-child,.fa-pull-left.icon{margin-right:.3em}.fa.fa-pull-right,.wy-menu-vertical li span.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a span.fa-pull-right.toctree-expand,.wy-menu-vertical li.current>a span.fa-pull-right.toctree-expand,.rst-content .fa-pull-right.admonition-title,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content dl dt .fa-pull-right.headerlink,.rst-content p.caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.rst-content code.download span.fa-pull-right:first-child,.fa-pull-right.icon{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-hotel:before,.fa-bed:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-yc:before,.fa-y-combinator:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-tv:before,.fa-television:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:""}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-signing:before,.fa-sign-language:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 .3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:.34375em .625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content .toctree-wrapper p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content .toctree-wrapper p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs li code,.wy-breadcrumbs li .rst-content tt,.rst-content .wy-breadcrumbs li tt{padding:5px;border:none;background:none}.wy-breadcrumbs li code.literal,.wy-breadcrumbs li .rst-content tt.literal,.rst-content .wy-breadcrumbs li tt.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980B9;text-align:center;padding:.809em;display:block;color:#fcfcfc;margin-bottom:.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:normal;color:rgba(255,255,255,0.3)}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}footer span.commit code,footer span.commit .rst-content tt,.rst-content footer span.commit tt{padding:0px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:1em;background:none;border:none;color:#999}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:before,.rst-breadcrumbs-buttons:after{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-side-scroll{width:auto}.wy-side-nav-search{width:auto}.wy-menu.wy-menu-vertical{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content img{max-width:100%;height:auto !important}.rst-content .highlight>pre{line-height:normal}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure p.caption{font-style:italic}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content .toctree-wrapper p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content .toctree-wrapper p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content .toctree-wrapper p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.docutils.citation tt,.rst-content table.docutils.citation code,.rst-content table.docutils.footnote tt,.rst-content table.docutils.footnote code{color:#555}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000;padding:2px 5px}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal{color:#E74C3C}.rst-content tt.xref,a .rst-content tt,.rst-content tt.xref,.rst-content code.xref,a .rst-content tt,a .rst-content code{font-weight:bold;color:#404040}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:#555}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-weight:normal;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child,.rst-content code.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),local("Inconsolata-Regular"),url(../fonts/Inconsolata-Regular.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} + */@font-face{font-family:'FontAwesome';src:url("../fonts/fontawesome-webfont.eot?v=4.2.0");src:url("../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff?v=4.2.0") format("woff"),url("../fonts/fontawesome-webfont.ttf?v=4.2.0") format("truetype"),url("../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular") format("svg");font-weight:normal;font-style:normal}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:0.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:0.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:solid 0.08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.wy-menu-vertical li span.pull-left.toctree-expand,.wy-menu-vertical li.on a span.pull-left.toctree-expand,.wy-menu-vertical li.current>a span.pull-left.toctree-expand,.rst-content .pull-left.admonition-title,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content p.caption .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content dl dt .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.rst-content code.download span.pull-left:first-child,.pull-left.icon{margin-right:.3em}.fa.pull-right,.wy-menu-vertical li span.pull-right.toctree-expand,.wy-menu-vertical li.on a span.pull-right.toctree-expand,.wy-menu-vertical li.current>a span.pull-right.toctree-expand,.rst-content .pull-right.admonition-title,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content p.caption .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content dl dt .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.rst-content code.download span.pull-right:first-child,.pull-right.icon{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-remove:before,.fa-close:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-gear:before,.fa-cog:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-rotate-right:before,.fa-repeat:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.rst-content .admonition-title:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-warning:before,.fa-exclamation-triangle:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-gears:before,.fa-cogs:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-save:before,.fa-floppy-o:before{content:""}.fa-square:before{content:""}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.wy-dropdown .caret:before,.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-unsorted:before,.fa-sort:before{content:""}.fa-sort-down:before,.fa-sort-desc:before{content:""}.fa-sort-up:before,.fa-sort-asc:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-legal:before,.fa-gavel:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-flash:before,.fa-bolt:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-paste:before,.fa-clipboard:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-unlink:before,.fa-chain-broken:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:""}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:""}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:""}.fa-euro:before,.fa-eur:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-rupee:before,.fa-inr:before{content:""}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:""}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:""}.fa-won:before,.fa-krw:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-turkish-lira:before,.fa-try:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li span.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-institution:before,.fa-bank:before,.fa-university:before{content:""}.fa-mortar-board:before,.fa-graduation-cap:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:""}.fa-file-zip-o:before,.fa-file-archive-o:before{content:""}.fa-file-sound-o:before,.fa-file-audio-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before{content:""}.fa-ge:before,.fa-empire:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-send:before,.fa-paper-plane:before{content:""}.fa-send-o:before,.fa-paper-plane-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:""}.fa-meanpath:before{content:""}.fa,.wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,.rst-content .admonition-title,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content tt.download span:first-child,.rst-content code.download span:first-child,.icon,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context{font-family:inherit}.fa:before,.wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li.on a span.toctree-expand:before,.wy-menu-vertical li.current>a span.toctree-expand:before,.rst-content .admonition-title:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content dl dt .headerlink:before,.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before,.icon:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before{font-family:"FontAwesome";display:inline-block;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa,a .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li a span.toctree-expand,.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand,a .rst-content .admonition-title,.rst-content a .admonition-title,a .rst-content h1 .headerlink,.rst-content h1 a .headerlink,a .rst-content h2 .headerlink,.rst-content h2 a .headerlink,a .rst-content p.caption .headerlink,.rst-content p.caption a .headerlink,a .rst-content h3 .headerlink,.rst-content h3 a .headerlink,a .rst-content h4 .headerlink,.rst-content h4 a .headerlink,a .rst-content h5 .headerlink,.rst-content h5 a .headerlink,a .rst-content h6 .headerlink,.rst-content h6 a .headerlink,a .rst-content dl dt .headerlink,.rst-content dl dt a .headerlink,a .rst-content tt.download span:first-child,.rst-content tt.download a span:first-child,a .rst-content code.download span:first-child,.rst-content code.download a span:first-child,a .icon{display:inline-block;text-decoration:inherit}.btn .fa,.btn .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .btn span.toctree-expand,.btn .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .btn span.toctree-expand,.btn .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .btn span.toctree-expand,.btn .rst-content .admonition-title,.rst-content .btn .admonition-title,.btn .rst-content h1 .headerlink,.rst-content h1 .btn .headerlink,.btn .rst-content h2 .headerlink,.rst-content h2 .btn .headerlink,.btn .rst-content p.caption .headerlink,.rst-content p.caption .btn .headerlink,.btn .rst-content h3 .headerlink,.rst-content h3 .btn .headerlink,.btn .rst-content h4 .headerlink,.rst-content h4 .btn .headerlink,.btn .rst-content h5 .headerlink,.rst-content h5 .btn .headerlink,.btn .rst-content h6 .headerlink,.rst-content h6 .btn .headerlink,.btn .rst-content dl dt .headerlink,.rst-content dl dt .btn .headerlink,.btn .rst-content tt.download span:first-child,.rst-content tt.download .btn span:first-child,.btn .rst-content code.download span:first-child,.rst-content code.download .btn span:first-child,.btn .icon,.nav .fa,.nav .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .nav span.toctree-expand,.nav .wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.on a .nav span.toctree-expand,.nav .wy-menu-vertical li.current>a span.toctree-expand,.wy-menu-vertical li.current>a .nav span.toctree-expand,.nav .rst-content .admonition-title,.rst-content .nav .admonition-title,.nav .rst-content h1 .headerlink,.rst-content h1 .nav .headerlink,.nav .rst-content h2 .headerlink,.rst-content h2 .nav .headerlink,.nav .rst-content p.caption .headerlink,.rst-content p.caption .nav .headerlink,.nav .rst-content h3 .headerlink,.rst-content h3 .nav .headerlink,.nav .rst-content h4 .headerlink,.rst-content h4 .nav .headerlink,.nav .rst-content h5 .headerlink,.rst-content h5 .nav .headerlink,.nav .rst-content h6 .headerlink,.rst-content h6 .nav .headerlink,.nav .rst-content dl dt .headerlink,.rst-content dl dt .nav .headerlink,.nav .rst-content tt.download span:first-child,.rst-content tt.download .nav span:first-child,.nav .rst-content code.download span:first-child,.rst-content code.download .nav span:first-child,.nav .icon{display:inline}.btn .fa.fa-large,.btn .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .btn span.fa-large.toctree-expand,.btn .rst-content .fa-large.admonition-title,.rst-content .btn .fa-large.admonition-title,.btn .rst-content h1 .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.btn .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .btn .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.btn .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .btn .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .btn span.fa-large:first-child,.btn .rst-content code.download span.fa-large:first-child,.rst-content code.download .btn span.fa-large:first-child,.btn .fa-large.icon,.nav .fa.fa-large,.nav .wy-menu-vertical li span.fa-large.toctree-expand,.wy-menu-vertical li .nav span.fa-large.toctree-expand,.nav .rst-content .fa-large.admonition-title,.rst-content .nav .fa-large.admonition-title,.nav .rst-content h1 .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.nav .rst-content p.caption .fa-large.headerlink,.rst-content p.caption .nav .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.nav .rst-content dl dt .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.nav .rst-content code.download span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.nav .fa-large.icon{line-height:0.9em}.btn .fa.fa-spin,.btn .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .btn span.fa-spin.toctree-expand,.btn .rst-content .fa-spin.admonition-title,.rst-content .btn .fa-spin.admonition-title,.btn .rst-content h1 .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.btn .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .btn .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.btn .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .btn .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .btn span.fa-spin:first-child,.btn .rst-content code.download span.fa-spin:first-child,.rst-content code.download .btn span.fa-spin:first-child,.btn .fa-spin.icon,.nav .fa.fa-spin,.nav .wy-menu-vertical li span.fa-spin.toctree-expand,.wy-menu-vertical li .nav span.fa-spin.toctree-expand,.nav .rst-content .fa-spin.admonition-title,.rst-content .nav .fa-spin.admonition-title,.nav .rst-content h1 .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.nav .rst-content p.caption .fa-spin.headerlink,.rst-content p.caption .nav .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.nav .rst-content dl dt .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.nav .rst-content code.download span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.nav .fa-spin.icon{display:inline-block}.btn.fa:before,.wy-menu-vertical li span.btn.toctree-expand:before,.rst-content .btn.admonition-title:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content p.caption .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content dl dt .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.rst-content code.download span.btn:first-child:before,.btn.icon:before{opacity:0.5;-webkit-transition:opacity 0.05s ease-in;-moz-transition:opacity 0.05s ease-in;transition:opacity 0.05s ease-in}.btn.fa:hover:before,.wy-menu-vertical li span.btn.toctree-expand:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content p.caption .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.rst-content code.download span.btn:first-child:hover:before,.btn.icon:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .wy-menu-vertical li span.toctree-expand:before,.wy-menu-vertical li .btn-mini span.toctree-expand:before,.btn-mini .rst-content .admonition-title:before,.rst-content .btn-mini .admonition-title:before,.btn-mini .rst-content h1 .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.btn-mini .rst-content p.caption .headerlink:before,.rst-content p.caption .btn-mini .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.btn-mini .rst-content dl dt .headerlink:before,.rst-content dl dt .btn-mini .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.rst-content tt.download .btn-mini span:first-child:before,.btn-mini .rst-content code.download span:first-child:before,.rst-content code.download .btn-mini span:first-child:before,.btn-mini .icon:before{font-size:14px;vertical-align:-15%}.wy-alert,.rst-content .note,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .warning,.rst-content .seealso,.rst-content .admonition-todo{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.wy-alert-title,.rst-content .admonition-title{color:#fff;font-weight:bold;display:block;color:#fff;background:#6ab0de;margin:-12px;padding:6px 12px;margin-bottom:12px}.wy-alert.wy-alert-danger,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.admonition-todo{background:#fdf3f2}.wy-alert.wy-alert-danger .wy-alert-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .danger .wy-alert-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .danger .admonition-title,.rst-content .error .admonition-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title{background:#f29f97}.wy-alert.wy-alert-warning,.rst-content .wy-alert-warning.note,.rst-content .attention,.rst-content .caution,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.tip,.rst-content .warning,.rst-content .wy-alert-warning.seealso,.rst-content .admonition-todo{background:#ffedcc}.wy-alert.wy-alert-warning .wy-alert-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .attention .wy-alert-title,.rst-content .caution .wy-alert-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .admonition-todo .wy-alert-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .attention .admonition-title,.rst-content .caution .admonition-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .warning .admonition-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .admonition-todo .admonition-title{background:#f0b37e}.wy-alert.wy-alert-info,.rst-content .note,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.rst-content .seealso,.rst-content .wy-alert-info.admonition-todo{background:#e7f2fa}.wy-alert.wy-alert-info .wy-alert-title,.rst-content .note .wy-alert-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.rst-content .note .admonition-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .seealso .admonition-title,.rst-content .wy-alert-info.admonition-todo .admonition-title{background:#6ab0de}.wy-alert.wy-alert-success,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.warning,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.admonition-todo{background:#dbfaf4}.wy-alert.wy-alert-success .wy-alert-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .hint .wy-alert-title,.rst-content .important .wy-alert-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .hint .admonition-title,.rst-content .important .admonition-title,.rst-content .tip .admonition-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.admonition-todo .admonition-title{background:#1abc9c}.wy-alert.wy-alert-neutral,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.admonition-todo{background:#f3f6f6}.wy-alert.wy-alert-neutral .wy-alert-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .admonition-title{color:#404040;background:#e1e4e5}.wy-alert.wy-alert-neutral a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.admonition-todo a{color:#2980B9}.wy-alert p:last-child,.rst-content .note p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.rst-content .seealso p:last-child,.rst-content .admonition-todo p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0px;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,0.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all 0.3s ease-in;-moz-transition:all 0.3s ease-in;transition:all 0.3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27AE60}.wy-tray-container li.wy-tray-item-info{background:#2980B9}.wy-tray-container li.wy-tray-item-warning{background:#E67E22}.wy-tray-container li.wy-tray-item-danger{background:#E74C3C}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width: 768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px 12px;color:#fff;border:1px solid rgba(0,0,0,0.1);background-color:#27AE60;text-decoration:none;font-weight:normal;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:0px 1px 2px -1px rgba(255,255,255,0.5) inset,0px -2px 0px 0px rgba(0,0,0,0.1) inset;outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all 0.1s linear;-moz-transition:all 0.1s linear;transition:all 0.1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:0px -1px 0px 0px rgba(0,0,0,0.05) inset,0px 2px 0px 0px rgba(0,0,0,0.1) inset;padding:8px 12px 6px 12px}.btn:visited{color:#fff}.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn-disabled:hover,.btn-disabled:focus,.btn-disabled:active{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:0.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980B9 !important}.btn-info:hover{background-color:#2e8ece !important}.btn-neutral{background-color:#f3f6f6 !important;color:#404040 !important}.btn-neutral:hover{background-color:#e5ebeb !important;color:#404040}.btn-neutral:visited{color:#404040 !important}.btn-success{background-color:#27AE60 !important}.btn-success:hover{background-color:#295 !important}.btn-danger{background-color:#E74C3C !important}.btn-danger:hover{background-color:#ea6153 !important}.btn-warning{background-color:#E67E22 !important}.btn-warning:hover{background-color:#e98b39 !important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f !important}.btn-link{background-color:transparent !important;color:#2980B9;box-shadow:none;border-color:transparent !important}.btn-link:hover{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:active{background-color:transparent !important;color:#409ad5 !important;box-shadow:none}.btn-link:visited{color:#9B59B6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:before,.wy-btn-group:after{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:solid 1px #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,0.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980B9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:solid 1px #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type="search"]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980B9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned input,.wy-form-aligned textarea,.wy-form-aligned select,.wy-form-aligned .wy-help-inline,.wy-form-aligned label{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{border:0;margin:0;padding:0}legend{display:block;width:100%;border:0;padding:0;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label{display:block;margin:0 0 0.3125em 0;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;*zoom:1;max-width:68em;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group:before,.wy-control-group:after{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#E74C3C}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full input[type="text"],.wy-control-group .wy-form-full input[type="password"],.wy-control-group .wy-form-full input[type="email"],.wy-control-group .wy-form-full input[type="url"],.wy-control-group .wy-form-full input[type="date"],.wy-control-group .wy-form-full input[type="month"],.wy-control-group .wy-form-full input[type="time"],.wy-control-group .wy-form-full input[type="datetime"],.wy-control-group .wy-form-full input[type="datetime-local"],.wy-control-group .wy-form-full input[type="week"],.wy-control-group .wy-form-full input[type="number"],.wy-control-group .wy-form-full input[type="search"],.wy-control-group .wy-form-full input[type="tel"],.wy-control-group .wy-form-full input[type="color"],.wy-control-group .wy-form-halves input[type="text"],.wy-control-group .wy-form-halves input[type="password"],.wy-control-group .wy-form-halves input[type="email"],.wy-control-group .wy-form-halves input[type="url"],.wy-control-group .wy-form-halves input[type="date"],.wy-control-group .wy-form-halves input[type="month"],.wy-control-group .wy-form-halves input[type="time"],.wy-control-group .wy-form-halves input[type="datetime"],.wy-control-group .wy-form-halves input[type="datetime-local"],.wy-control-group .wy-form-halves input[type="week"],.wy-control-group .wy-form-halves input[type="number"],.wy-control-group .wy-form-halves input[type="search"],.wy-control-group .wy-form-halves input[type="tel"],.wy-control-group .wy-form-halves input[type="color"],.wy-control-group .wy-form-thirds input[type="text"],.wy-control-group .wy-form-thirds input[type="password"],.wy-control-group .wy-form-thirds input[type="email"],.wy-control-group .wy-form-thirds input[type="url"],.wy-control-group .wy-form-thirds input[type="date"],.wy-control-group .wy-form-thirds input[type="month"],.wy-control-group .wy-form-thirds input[type="time"],.wy-control-group .wy-form-thirds input[type="datetime"],.wy-control-group .wy-form-thirds input[type="datetime-local"],.wy-control-group .wy-form-thirds input[type="week"],.wy-control-group .wy-form-thirds input[type="number"],.wy-control-group .wy-form-thirds input[type="search"],.wy-control-group .wy-form-thirds input[type="tel"],.wy-control-group .wy-form-thirds input[type="color"]{width:100%}.wy-control-group .wy-form-full{float:left;display:block;margin-right:2.35765%;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child{margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(2n+1){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child{margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control{margin:6px 0 0 0;font-size:90%}.wy-control-no-input{display:inline-block;margin:6px 0 0 0;font-size:90%}.wy-control-group.fluid-input input[type="text"],.wy-control-group.fluid-input input[type="password"],.wy-control-group.fluid-input input[type="email"],.wy-control-group.fluid-input input[type="url"],.wy-control-group.fluid-input input[type="date"],.wy-control-group.fluid-input input[type="month"],.wy-control-group.fluid-input input[type="time"],.wy-control-group.fluid-input input[type="datetime"],.wy-control-group.fluid-input input[type="datetime-local"],.wy-control-group.fluid-input input[type="week"],.wy-control-group.fluid-input input[type="number"],.wy-control-group.fluid-input input[type="search"],.wy-control-group.fluid-input input[type="tel"],.wy-control-group.fluid-input input[type="color"]{width:100%}.wy-form-message-inline{display:inline-block;padding-left:0.3em;color:#666;vertical-align:middle;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:0.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;*overflow:visible}input[type="text"],input[type="password"],input[type="email"],input[type="url"],input[type="date"],input[type="month"],input[type="time"],input[type="datetime"],input[type="datetime-local"],input[type="week"],input[type="number"],input[type="search"],input[type="tel"],input[type="color"]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}input[type="datetime-local"]{padding:0.34375em 0.625em}input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;margin-right:0.3125em;*height:13px;*width:13px}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input[type="text"]:focus,input[type="password"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus{outline:0;outline:thin dotted \9;border-color:#333}input.no-focus:focus{border-color:#ccc !important}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:1px auto #129FEA}input[type="text"][disabled],input[type="password"][disabled],input[type="email"][disabled],input[type="url"][disabled],input[type="date"][disabled],input[type="month"][disabled],input[type="time"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="week"][disabled],input[type="number"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="color"][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#E74C3C;border:1px solid #E74C3C}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#E74C3C}input[type="file"]:focus:invalid:focus,input[type="radio"]:focus:invalid:focus,input[type="checkbox"]:focus:invalid:focus{outline-color:#E74C3C}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif}select,textarea{padding:0.5em 0.625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border 0.3s linear;-moz-transition:border 0.3s linear;transition:border 0.3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type="radio"][disabled],input[type="checkbox"][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:solid 1px #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{width:36px;height:12px;margin:12px 0;position:relative;border-radius:4px;background:#ccc;cursor:pointer;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:before{position:absolute;content:"";display:block;width:18px;height:18px;border-radius:4px;background:#999;left:-3px;top:-3px;-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.wy-switch:after{content:"false";position:absolute;left:48px;display:block;font-size:12px;color:#ccc}.wy-switch.active{background:#1e8449}.wy-switch.active:before{left:24px;background:#27AE60}.wy-switch.active:after{content:"true"}.wy-switch.disabled,.wy-switch.active.disabled{cursor:not-allowed}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#E74C3C}.wy-control-group.wy-control-group-error input[type="text"],.wy-control-group.wy-control-group-error input[type="password"],.wy-control-group.wy-control-group-error input[type="email"],.wy-control-group.wy-control-group-error input[type="url"],.wy-control-group.wy-control-group-error input[type="date"],.wy-control-group.wy-control-group-error input[type="month"],.wy-control-group.wy-control-group-error input[type="time"],.wy-control-group.wy-control-group-error input[type="datetime"],.wy-control-group.wy-control-group-error input[type="datetime-local"],.wy-control-group.wy-control-group-error input[type="week"],.wy-control-group.wy-control-group-error input[type="number"],.wy-control-group.wy-control-group-error input[type="search"],.wy-control-group.wy-control-group-error input[type="tel"],.wy-control-group.wy-control-group-error input[type="color"]{border:solid 1px #E74C3C}.wy-control-group.wy-control-group-error textarea{border:solid 1px #E74C3C}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:0.5em 0.625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27AE60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#E74C3C}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#E67E22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980B9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width: 480px){.wy-form button[type="submit"]{margin:0.7em 0 0}.wy-form input[type="text"],.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0.3em;display:block}.wy-form label{margin-bottom:0.3em;display:block}.wy-form input[type="password"],.wy-form input[type="email"],.wy-form input[type="url"],.wy-form input[type="date"],.wy-form input[type="month"],.wy-form input[type="time"],.wy-form input[type="datetime"],.wy-form input[type="datetime-local"],.wy-form input[type="week"],.wy-form input[type="number"],.wy-form input[type="search"],.wy-form input[type="tel"],.wy-form input[type="color"]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:0.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0 0}.wy-form .wy-help-inline,.wy-form-message-inline,.wy-form-message{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width: 768px){.tablet-hide{display:none}}@media screen and (max-width: 480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.wy-table,.rst-content table.docutils,.rst-content table.field-list{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.wy-table caption,.rst-content table.docutils caption,.rst-content table.field-list caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td,.wy-table th,.rst-content table.docutils th,.rst-content table.field-list th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.wy-table td:first-child,.rst-content table.docutils td:first-child,.rst-content table.field-list td:first-child,.wy-table th:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list th:first-child{border-left-width:0}.wy-table thead,.rst-content table.docutils thead,.rst-content table.field-list thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.wy-table thead th,.rst-content table.docutils thead th,.rst-content table.field-list thead th{font-weight:bold;border-bottom:solid 2px #e1e4e5}.wy-table td,.rst-content table.docutils td,.rst-content table.field-list td{background-color:transparent;vertical-align:middle}.wy-table td p,.rst-content table.docutils td p,.rst-content table.field-list td p{line-height:18px}.wy-table td p:last-child,.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child{margin-bottom:0}.wy-table .wy-table-cell-min,.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min{width:1%;padding-right:0}.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox],.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:gray;font-size:90%}.wy-table-tertiary{color:gray;font-size:80%}.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td,.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td{background-color:#f3f6f6}.wy-table-backed{background-color:#f3f6f6}.wy-table-bordered-all,.rst-content table.docutils{border:1px solid #e1e4e5}.wy-table-bordered-all td,.rst-content table.docutils td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.wy-table-bordered-all tbody>tr:last-child td,.rst-content table.docutils tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px 0;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0 !important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980B9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9B59B6}html{height:100%;overflow-x:hidden}body{font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;font-weight:normal;color:#404040;min-height:100%;overflow-x:hidden;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#E67E22 !important}a.wy-text-warning:hover{color:#eb9950 !important}.wy-text-info{color:#2980B9 !important}a.wy-text-info:hover{color:#409ad5 !important}.wy-text-success{color:#27AE60 !important}a.wy-text-success:hover{color:#36d278 !important}.wy-text-danger{color:#E74C3C !important}a.wy-text-danger:hover{color:#ed7669 !important}.wy-text-neutral{color:#404040 !important}a.wy-text-neutral:hover{color:#595959 !important}h1,h2,.rst-content p.caption,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif}p{line-height:24px;margin:0;font-size:16px;margin-bottom:24px}h1{font-size:175%}h2,.rst-content p.caption{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}code,.rst-content tt,.rst-content code{white-space:nowrap;max-width:100%;background:#fff;border:solid 1px #e1e4e5;font-size:75%;padding:0 5px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;color:#E74C3C;overflow-x:auto}code.code-large,.rst-content tt.code-large{font-size:90%}.wy-plain-list-disc,.rst-content .section ul,.rst-content .toctree-wrapper ul,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.wy-plain-list-disc li,.rst-content .section ul li,.rst-content .toctree-wrapper ul li,article ul li{list-style:disc;margin-left:24px}.wy-plain-list-disc li p:last-child,.rst-content .section ul li p:last-child,.rst-content .toctree-wrapper ul li p:last-child,article ul li p:last-child{margin-bottom:0}.wy-plain-list-disc li ul,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li ul,article ul li ul{margin-bottom:0}.wy-plain-list-disc li li,.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,article ul li li{list-style:circle}.wy-plain-list-disc li li li,.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,article ul li li li{list-style:square}.wy-plain-list-disc li ol li,.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,article ul li ol li{list-style:decimal}.wy-plain-list-decimal,.rst-content .section ol,.rst-content ol.arabic,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.wy-plain-list-decimal li,.rst-content .section ol li,.rst-content ol.arabic li,article ol li{list-style:decimal;margin-left:24px}.wy-plain-list-decimal li p:last-child,.rst-content .section ol li p:last-child,.rst-content ol.arabic li p:last-child,article ol li p:last-child{margin-bottom:0}.wy-plain-list-decimal li ul,.rst-content .section ol li ul,.rst-content ol.arabic li ul,article ol li ul{margin-bottom:0}.wy-plain-list-decimal li ul li,.rst-content .section ol li ul li,.rst-content ol.arabic li ul li,article ol li ul li{list-style:disc}.codeblock-example{border:1px solid #e1e4e5;border-bottom:none;padding:24px;padding-top:48px;font-weight:500;background:#fff;position:relative}.codeblock-example:after{content:"Example";position:absolute;top:0px;left:0px;background:#9B59B6;color:#fff;padding:6px 12px}.codeblock-example.prettyprint-example-only{border:1px solid #e1e4e5;margin-bottom:24px}.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight']{border:1px solid #e1e4e5;padding:0px;overflow-x:auto;background:#fff;margin:1px 0 24px 0}.codeblock div[class^='highlight'],pre.literal-block div[class^='highlight'],.rst-content .literal-block div[class^='highlight'],div[class^='highlight'] div[class^='highlight']{border:none;background:none;margin:0}div[class^='highlight'] td.code{width:100%}.linenodiv pre{border-right:solid 1px #e6e9ea;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;color:#d9d9d9}div[class^='highlight'] pre{white-space:pre;margin:0;padding:12px 12px;font-family:Consolas,"Andale Mono WT","Andale Mono","Lucida Console","Lucida Sans Typewriter","DejaVu Sans Mono","Bitstream Vera Sans Mono","Liberation Mono","Nimbus Mono L",Monaco,"Courier New",Courier,monospace;font-size:12px;line-height:1.5;display:block;overflow:auto;color:#404040}@media print{.codeblock,pre.literal-block,.rst-content .literal-block,.rst-content pre.literal-block,div[class^='highlight'],div[class^='highlight'] pre{white-space:pre-wrap}}.hll{background-color:#ffc;margin:0 -12px;padding:0 12px;display:block}.c{color:#998;font-style:italic}.err{color:#a61717;background-color:#e3d2d2}.k{font-weight:bold}.o{font-weight:bold}.cm{color:#998;font-style:italic}.cp{color:#999;font-weight:bold}.c1{color:#998;font-style:italic}.cs{color:#999;font-weight:bold;font-style:italic}.gd{color:#000;background-color:#fdd}.gd .x{color:#000;background-color:#faa}.ge{font-style:italic}.gr{color:#a00}.gh{color:#999}.gi{color:#000;background-color:#dfd}.gi .x{color:#000;background-color:#afa}.go{color:#888}.gp{color:#555}.gs{font-weight:bold}.gu{color:purple;font-weight:bold}.gt{color:#a00}.kc{font-weight:bold}.kd{font-weight:bold}.kn{font-weight:bold}.kp{font-weight:bold}.kr{font-weight:bold}.kt{color:#458;font-weight:bold}.m{color:#099}.s{color:#d14}.n{color:#333}.na{color:teal}.nb{color:#0086b3}.nc{color:#458;font-weight:bold}.no{color:teal}.ni{color:purple}.ne{color:#900;font-weight:bold}.nf{color:#900;font-weight:bold}.nn{color:#555}.nt{color:navy}.nv{color:teal}.ow{font-weight:bold}.w{color:#bbb}.mf{color:#099}.mh{color:#099}.mi{color:#099}.mo{color:#099}.sb{color:#d14}.sc{color:#d14}.sd{color:#d14}.s2{color:#d14}.se{color:#d14}.sh{color:#d14}.si{color:#d14}.sx{color:#d14}.sr{color:#009926}.s1{color:#d14}.ss{color:#990073}.bp{color:#999}.vc{color:teal}.vg{color:teal}.vi{color:teal}.il{color:#099}.gc{color:#999;background-color:#EAF2F5}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width: 480px){.wy-breadcrumbs-extra{display:none}.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:before,.wy-menu-horiz:after{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz ul,.wy-menu-horiz li{display:inline-block}.wy-menu-horiz li:hover{background:rgba(255,255,255,0.1)}.wy-menu-horiz li.divide-left{border-left:solid 1px #404040}.wy-menu-horiz li.divide-right{border-right:solid 1px #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical header,.wy-menu-vertical p.caption{height:32px;display:inline-block;line-height:32px;padding:0 1.618em;margin-bottom:0;display:block;font-weight:bold;text-transform:uppercase;font-size:80%;color:#555;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:solid 1px #404040}.wy-menu-vertical li.divide-bottom{border-bottom:solid 1px #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:gray;border-right:solid 1px #c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.wy-menu-vertical li code,.wy-menu-vertical li .rst-content tt,.rst-content .wy-menu-vertical li tt{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li span.toctree-expand{display:block;float:left;margin-left:-1.2em;font-size:0.8em;line-height:1.6em;color:#4d4d4d}.wy-menu-vertical li.on a,.wy-menu-vertical li.current>a{color:#404040;padding:0.4045em 1.618em;font-weight:bold;position:relative;background:#fcfcfc;border:none;border-bottom:solid 1px #c9c9c9;border-top:solid 1px #c9c9c9;padding-left:1.618em -4px}.wy-menu-vertical li.on a:hover,.wy-menu-vertical li.current>a:hover{background:#fcfcfc}.wy-menu-vertical li.on a:hover span.toctree-expand,.wy-menu-vertical li.current>a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.on a span.toctree-expand,.wy-menu-vertical li.current>a span.toctree-expand{display:block;font-size:0.8em;line-height:1.6em;color:#333}.wy-menu-vertical li.toctree-l1.current li.toctree-l2>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>ul{display:none}.wy-menu-vertical li.toctree-l1.current li.toctree-l2.current>ul,.wy-menu-vertical li.toctree-l2.current li.toctree-l3.current>ul{display:block}.wy-menu-vertical li.toctree-l2.current>a{background:#c9c9c9;padding:0.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{display:block;background:#c9c9c9;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l2 span.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3{font-size:0.9em}.wy-menu-vertical li.toctree-l3.current>a{background:#bdbdbd;padding:0.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{display:block;background:#bdbdbd;padding:0.4045em 5.663em;border-top:none;border-bottom:none}.wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand{color:gray}.wy-menu-vertical li.toctree-l3 span.toctree-expand{color:#969696}.wy-menu-vertical li.toctree-l4{font-size:0.9em}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical .local-toc li ul{display:block}.wy-menu-vertical li ul li a{margin-bottom:0;color:#b3b3b3;font-weight:normal}.wy-menu-vertical a{display:inline-block;line-height:18px;padding:0.4045em 1.618em;display:block;position:relative;font-size:90%;color:#b3b3b3}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover span.toctree-expand{color:#b3b3b3}.wy-menu-vertical a:active{background-color:#2980B9;cursor:pointer;color:#fff}.wy-menu-vertical a:active span.toctree-expand{color:#fff}.wy-side-nav-search{z-index:200;background-color:#2980B9;text-align:center;padding:0.809em;display:block;color:#fcfcfc;margin-bottom:0.809em}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto 0.809em auto;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-side-nav-search>a,.wy-side-nav-search .wy-dropdown>a{color:#fcfcfc;font-size:100%;font-weight:bold;display:inline-block;padding:4px 6px;margin-bottom:0.809em}.wy-side-nav-search>a:hover,.wy-side-nav-search .wy-dropdown>a:hover{background:rgba(255,255,255,0.1)}.wy-side-nav-search>a img.logo,.wy-side-nav-search .wy-dropdown>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search>a.icon img.logo,.wy-side-nav-search .wy-dropdown>a.icon img.logo{margin-top:0.85em}.wy-nav .wy-menu-vertical header{color:#2980B9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980B9;color:#fff}[data-menu-wrap]{-webkit-transition:all 0.2s ease-in;-moz-transition:all 0.2s ease-in;transition:all 0.2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:left repeat-y #fcfcfc;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxOERBMTRGRDBFMUUxMUUzODUwMkJCOThDMEVFNURFMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxOERBMTRGRTBFMUUxMUUzODUwMkJCOThDMEVFNURFMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4REExNEZCMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjE4REExNEZDMEUxRTExRTM4NTAyQkI5OEMwRUU1REUwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+EwrlwAAAAA5JREFUeNpiMDU0BAgwAAE2AJgB9BnaAAAAAElFTkSuQmCC);background-size:300px 1px}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:scroll;min-height:100%;background:#343131;z-index:200}.wy-nav-top{display:none;background:#2980B9;color:#fff;padding:0.4045em 0.809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:before,.wy-nav-top:after{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:bold}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980B9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,0.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:#999}footer p{margin-bottom:12px}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:before,.rst-footer-buttons:after{display:table;content:""}.rst-footer-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:solid 1px #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:solid 1px #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:gray;font-size:90%}@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width: 1400px){.wy-nav-content-wrap{background:rgba(0,0,0,0.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,footer,.wy-nav-side{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content p.caption .headerlink,.rst-content p.caption .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}.rst-content img{max-width:100%;height:auto !important}.rst-content div.figure{margin-bottom:24px}.rst-content div.figure.align-center{text-align:center}.rst-content .section>img,.rst-content .section>a>img{margin-bottom:24px}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content .note .last,.rst-content .attention .last,.rst-content .caution .last,.rst-content .danger .last,.rst-content .error .last,.rst-content .hint .last,.rst-content .important .last,.rst-content .tip .last,.rst-content .warning .last,.rst-content .seealso .last,.rst-content .admonition-todo .last{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,0.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent !important;border-color:rgba(0,0,0,0.1) !important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha li{list-style:upper-alpha}.rst-content .section ol p,.rst-content .section ul p{margin-bottom:12px}.rst-content .line-block{margin-left:24px}.rst-content .topic-title{font-weight:bold;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0px 0px 24px 24px}.rst-content .align-left{float:left;margin:0px 24px 24px 0px}.rst-content .align-center{margin:auto;display:block}.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content p.caption .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content dl dt .headerlink,.rst-content p.caption .headerlink{display:none;visibility:hidden;font-size:14px}.rst-content h1 .headerlink:after,.rst-content h2 .headerlink:after,.rst-content p.caption .headerlink:after,.rst-content h3 .headerlink:after,.rst-content h4 .headerlink:after,.rst-content h5 .headerlink:after,.rst-content h6 .headerlink:after,.rst-content dl dt .headerlink:after,.rst-content p.caption .headerlink:after{visibility:visible;content:"";font-family:FontAwesome;display:inline-block}.rst-content h1:hover .headerlink,.rst-content h2:hover .headerlink,.rst-content p.caption:hover .headerlink,.rst-content h3:hover .headerlink,.rst-content h4:hover .headerlink,.rst-content h5:hover .headerlink,.rst-content h6:hover .headerlink,.rst-content dl dt:hover .headerlink,.rst-content p.caption:hover .headerlink{display:inline-block}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:solid 1px #e1e4e5}.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}.rst-content .sidebar .last{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:super;font-size:90%}.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:#999}.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}.rst-content table.docutils.citation td.label,.rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}.rst-content table.field-list{border:none}.rst-content table.field-list td{border:none;padding-top:5px}.rst-content table.field-list td>strong{display:inline-block;margin-top:3px}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left;padding-left:0}.rst-content tt,.rst-content tt,.rst-content code{color:#000}.rst-content tt big,.rst-content tt em,.rst-content tt big,.rst-content code big,.rst-content tt em,.rst-content code em{font-size:100% !important;line-height:normal}.rst-content tt .xref,a .rst-content tt,.rst-content tt .xref,.rst-content code .xref,a .rst-content tt,a .rst-content code{font-weight:bold}.rst-content a tt,.rst-content a tt,.rst-content a code{color:#2980B9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:bold}.rst-content dl p,.rst-content dl table,.rst-content dl ul,.rst-content dl ol{margin-bottom:12px !important}.rst-content dl dd{margin:0 0 12px 24px}.rst-content dl:not(.docutils){margin-bottom:24px}.rst-content dl:not(.docutils) dt{display:inline-block;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980B9;border-top:solid 3px #6ab0de;padding:6px;position:relative}.rst-content dl:not(.docutils) dt:before{color:#6ab0de}.rst-content dl:not(.docutils) dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dl dt{margin-bottom:6px;border:none;border-left:solid 3px #ccc;background:#f0f0f0;color:gray}.rst-content dl:not(.docutils) dl dt .headerlink{color:#404040;font-size:100% !important}.rst-content dl:not(.docutils) dt:first-child{margin-top:0}.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) tt,.rst-content dl:not(.docutils) code{font-weight:bold}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname,.rst-content dl:not(.docutils) tt.descclassname,.rst-content dl:not(.docutils) code.descclassname{background-color:transparent;border:none;padding:0;font-size:100% !important}.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) tt.descname,.rst-content dl:not(.docutils) code.descname{font-weight:bold}.rst-content dl:not(.docutils) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:bold}.rst-content dl:not(.docutils) .property{display:inline-block;padding-right:8px}.rst-content .viewcode-link,.rst-content .viewcode-back{display:inline-block;color:#27AE60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:bold}.rst-content tt.download,.rst-content code.download{background:inherit;padding:inherit;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content tt.download span:first-child:before,.rst-content code.download span:first-child:before{margin-right:4px}@media screen and (max-width: 480px){.rst-content .sidebar{width:100%}}span[id*='MathJax-Span']{color:#404040}.math{text-align:center}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:400;src:local("Inconsolata"),url(../fonts/Inconsolata.ttf) format("truetype")}@font-face{font-family:"Inconsolata";font-style:normal;font-weight:700;src:local("Inconsolata Bold"),local("Inconsolata-Bold"),url(../fonts/Inconsolata-Bold.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:400;src:local("Lato Regular"),local("Lato-Regular"),url(../fonts/Lato-Regular.ttf) format("truetype")}@font-face{font-family:"Lato";font-style:normal;font-weight:700;src:local("Lato Bold"),local("Lato-Bold"),url(../fonts/Lato-Bold.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:400;src:local("Roboto Slab Regular"),local("RobotoSlab-Regular"),url(../fonts/RobotoSlab-Regular.ttf) format("truetype")}@font-face{font-family:"Roboto Slab";font-style:normal;font-weight:700;src:local("Roboto Slab Bold"),local("RobotoSlab-Bold"),url(../fonts/RobotoSlab-Bold.ttf) format("truetype")} /*# sourceMappingURL=theme.css.map */ diff --git a/_static/doctools.js b/_static/doctools.js index 0c15c009..c7bfe760 100644 --- a/_static/doctools.js +++ b/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -45,7 +45,7 @@ jQuery.urlencode = encodeURIComponent; * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { - if (typeof s === 'undefined') + if (typeof s == 'undefined') s = document.location.search; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; @@ -66,53 +66,29 @@ jQuery.getQueryParameters = function(s) { * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { - function highlight(node, addItems) { - if (node.nodeType === 3) { + function highlight(node) { + if (node.nodeType == 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span; - var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); - if (isInSVG) { - span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - } else { - span = document.createElement("span"); - span.className = className; - } + var span = document.createElement("span"); + span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); - if (isInSVG) { - var bbox = span.getBBox(); - var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); - rect.x.baseVal.value = bbox.x; - rect.y.baseVal.value = bbox.y; - rect.width.baseVal.value = bbox.width; - rect.height.baseVal.value = bbox.height; - rect.setAttribute('class', className); - var parentOfText = node.parentNode.parentNode; - addItems.push({ - "parent": node.parentNode, - "target": rect}); - } } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { - highlight(this, addItems); + highlight(this); }); } } - var addItems = []; - var result = this.each(function() { - highlight(this, addItems); + return this.each(function() { + highlight(this); }); - for (var i = 0; i < addItems.length; ++i) { - jQuery(addItems[i].parent).before(addItems[i].target); - } - return result; }; /* @@ -148,28 +124,27 @@ var Documentation = { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); - }, /** * i18n support */ TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated === 'undefined') + if (typeof translated == 'undefined') return string; - return (typeof translated === 'string') ? translated : translated[0]; + return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated === 'undefined') + if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, @@ -204,7 +179,7 @@ var Documentation = { * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 */ fixFirefoxAnchorBug : function() { - if (document.location.hash && $.browser.mozilla) + if (document.location.hash) window.setTimeout(function() { document.location.href += ''; }, 10); @@ -240,7 +215,7 @@ var Documentation = { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) === 'minus.png') + if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); @@ -272,34 +247,11 @@ var Documentation = { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this === '..') + if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - }, - - initOnKeyListeners: function() { - $(document).keyup(function(event) { - var activeElementType = document.activeElement.tagName; - // don't navigate when in search box or textarea - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; - } - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; - } - } - } - }); } }; @@ -308,4 +260,4 @@ _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); -}); \ No newline at end of file +}); diff --git a/_static/down-pressed.png b/_static/down-pressed.png index 5756c8ca..7c30d004 100644 Binary files a/_static/down-pressed.png and b/_static/down-pressed.png differ diff --git a/_static/down.png b/_static/down.png index 1b3bdad2..f48098a4 100644 Binary files a/_static/down.png and b/_static/down.png differ diff --git a/_static/file.png b/_static/file.png index a858a410..254c60bf 100644 Binary files a/_static/file.png and b/_static/file.png differ diff --git a/_static/fonts/Inconsolata-Bold.ttf b/_static/fonts/Inconsolata-Bold.ttf index 809c1f58..360a232d 100644 Binary files a/_static/fonts/Inconsolata-Bold.ttf and b/_static/fonts/Inconsolata-Bold.ttf differ diff --git a/_static/fonts/Inconsolata-Regular.ttf b/_static/fonts/Inconsolata-Regular.ttf deleted file mode 100644 index fc981ce7..00000000 Binary files a/_static/fonts/Inconsolata-Regular.ttf and /dev/null differ diff --git a/_static/fonts/Lato-Bold.ttf b/_static/fonts/Lato-Bold.ttf index 1d23c706..e8b9bf6a 100644 Binary files a/_static/fonts/Lato-Bold.ttf and b/_static/fonts/Lato-Bold.ttf differ diff --git a/_static/fonts/Lato-Regular.ttf b/_static/fonts/Lato-Regular.ttf index 0f3d0f83..7608bc3e 100644 Binary files a/_static/fonts/Lato-Regular.ttf and b/_static/fonts/Lato-Regular.ttf differ diff --git a/_static/fonts/RobotoSlab-Bold.ttf b/_static/fonts/RobotoSlab-Bold.ttf index df5d1df2..e6ed0de5 100644 Binary files a/_static/fonts/RobotoSlab-Bold.ttf and b/_static/fonts/RobotoSlab-Bold.ttf differ diff --git a/_static/fonts/RobotoSlab-Regular.ttf b/_static/fonts/RobotoSlab-Regular.ttf index eb52a790..141d6c08 100644 Binary files a/_static/fonts/RobotoSlab-Regular.ttf and b/_static/fonts/RobotoSlab-Regular.ttf differ diff --git a/_static/fonts/fontawesome-webfont.eot b/_static/fonts/fontawesome-webfont.eot index c7b00d2b..7c79c6a6 100644 Binary files a/_static/fonts/fontawesome-webfont.eot and b/_static/fonts/fontawesome-webfont.eot differ diff --git a/_static/fonts/fontawesome-webfont.svg b/_static/fonts/fontawesome-webfont.svg index 8b66187f..45fdf338 100644 --- a/_static/fonts/fontawesome-webfont.svg +++ b/_static/fonts/fontawesome-webfont.svg @@ -14,11 +14,10 @@ - - + - + @@ -31,7 +30,7 @@ - + @@ -53,7 +52,7 @@ - + @@ -78,11 +77,11 @@ - - - - - + + + + + @@ -110,8 +109,8 @@ - - + + @@ -144,17 +143,17 @@ - - + + - + - + - + @@ -169,7 +168,7 @@ - + @@ -177,14 +176,14 @@ - - + + - + @@ -219,8 +218,8 @@ - - + + @@ -248,10 +247,10 @@ - + - + @@ -275,7 +274,7 @@ - + @@ -346,8 +345,8 @@ - - + + @@ -362,14 +361,14 @@ - - + + - - + + @@ -380,7 +379,7 @@ - + @@ -399,287 +398,17 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/_static/fonts/fontawesome-webfont.ttf b/_static/fonts/fontawesome-webfont.ttf index f221e50a..e89738de 100644 Binary files a/_static/fonts/fontawesome-webfont.ttf and b/_static/fonts/fontawesome-webfont.ttf differ diff --git a/_static/fonts/fontawesome-webfont.woff b/_static/fonts/fontawesome-webfont.woff index 6e7483cf..8c1748aa 100644 Binary files a/_static/fonts/fontawesome-webfont.woff and b/_static/fonts/fontawesome-webfont.woff differ diff --git a/_static/jquery-3.2.1.js b/_static/jquery-3.2.1.js deleted file mode 100644 index d2d8ca47..00000000 --- a/_static/jquery-3.2.1.js +++ /dev/null @@ -1,10253 +0,0 @@ -/*! - * jQuery JavaScript Library v3.2.1 - * https://jquery.com/ - * - * Includes Sizzle.js - * https://sizzlejs.com/ - * - * Copyright JS Foundation and other contributors - * Released under the MIT license - * https://jquery.org/license - * - * Date: 2017-03-20T18:59Z - */ -( function( global, factory ) { - - "use strict"; - - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 -// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode -// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common -// enough that all such attempts are guarded in a try block. -"use strict"; - -var arr = []; - -var document = window.document; - -var getProto = Object.getPrototypeOf; - -var slice = arr.slice; - -var concat = arr.concat; - -var push = arr.push; - -var indexOf = arr.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var fnToString = hasOwn.toString; - -var ObjectFunctionString = fnToString.call( Object ); - -var support = {}; - - - - function DOMEval( code, doc ) { - doc = doc || document; - - var script = doc.createElement( "script" ); - - script.text = code; - doc.head.appendChild( script ).parentNode.removeChild( script ); - } -/* global Symbol */ -// Defining this global in .eslintrc.json would create a danger of using the global -// unguarded in another place, it seems safer to define global only for this module - - - -var - version = "3.2.1", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android <=4.0 only - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([a-z])/g, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - - // Return all the elements in a clean array - if ( num == null ) { - return slice.call( this ); - } - - // Return just the one element from the set - return num < 0 ? this[ num + this.length ] : this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - } ) ); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: arr.sort, - splice: arr.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // Skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { - target = {}; - } - - // Extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - - // Only deal with non-null/undefined values - if ( ( options = arguments[ i ] ) != null ) { - - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = Array.isArray( copy ) ) ) ) { - - if ( copyIsArray ) { - copyIsArray = false; - clone = src && Array.isArray( src ) ? src : []; - - } else { - clone = src && jQuery.isPlainObject( src ) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend( { - - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - isFunction: function( obj ) { - return jQuery.type( obj ) === "function"; - }, - - isWindow: function( obj ) { - return obj != null && obj === obj.window; - }, - - isNumeric: function( obj ) { - - // As of jQuery 3.0, isNumeric is limited to - // strings and numbers (primitives or objects) - // that can be coerced to finite numbers (gh-2662) - var type = jQuery.type( obj ); - return ( type === "number" || type === "string" ) && - - // parseFloat NaNs numeric-cast false positives ("") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - !isNaN( obj - parseFloat( obj ) ); - }, - - isPlainObject: function( obj ) { - var proto, Ctor; - - // Detect obvious negatives - // Use toString instead of jQuery.type to catch host objects - if ( !obj || toString.call( obj ) !== "[object Object]" ) { - return false; - } - - proto = getProto( obj ); - - // Objects with no prototype (e.g., `Object.create( null )`) are plain - if ( !proto ) { - return true; - } - - // Objects with prototype are plain iff they were constructed by a global Object function - Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; - return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; - }, - - isEmptyObject: function( obj ) { - - /* eslint-disable no-unused-vars */ - // See https://github.com/eslint/eslint/issues/6125 - var name; - - for ( name in obj ) { - return false; - } - return true; - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - - // Support: Android <=2.3 only (functionish RegExp) - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - globalEval: function( code ) { - DOMEval( code ); - }, - - // Convert dashed to camelCase; used by the css and data modules - // Support: IE <=9 - 11, Edge 12 - 13 - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - each: function( obj, callback ) { - var length, i = 0; - - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - - return obj; - }, - - // Support: Android <=4.0 only - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArrayLike( Object( arr ) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - return arr == null ? -1 : indexOf.call( arr, elem, i ); - }, - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - for ( ; j < len; j++ ) { - first[ i++ ] = second[ j ]; - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var length, value, - i = 0, - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArrayLike( elems ) ) { - length = elems.length; - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var tmp, args, proxy; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: Date.now, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -} ); - -if ( typeof Symbol === "function" ) { - jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; -} - -// Populate the class2type map -jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), -function( i, name ) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -} ); - -function isArrayLike( obj ) { - - // Support: real iOS 8.2 only (not reproducible in simulator) - // `in` check used to prevent JIT error (gh-2145) - // hasOwn isn't used here due to false negatives - // regarding Nodelist length in IE - var length = !!obj && "length" in obj && obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v2.3.3 - * https://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2016-08-08 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + 1 * new Date(), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // https://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - - // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + identifier + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + identifier + ")" ), - "CLASS": new RegExp( "^\\.(" + identifier + ")" ), - "TAG": new RegExp( "^(" + identifier + "|[*])" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - - // CSS escapes - // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // CSS string/identifier serialization - // https://drafts.csswg.org/cssom/#common-serializing-idioms - rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, - fcssescape = function( ch, asCodePoint ) { - if ( asCodePoint ) { - - // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER - if ( ch === "\0" ) { - return "\uFFFD"; - } - - // Control characters and (dependent upon position) numbers get escaped as code points - return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; - } - - // Other potentially-special ASCII characters get backslash-escaped - return "\\" + ch; - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); - }, - - disabledAncestor = addCombinator( - function( elem ) { - return elem.disabled === true && ("form" in elem || "label" in elem); - }, - { dir: "parentNode", next: "legend" } - ); - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, match, groups, newSelector, - newContext = context && context.ownerDocument, - - // nodeType defaults to 9, since context defaults to document - nodeType = context ? context.nodeType : 9; - - results = results || []; - - // Return early from calls with invalid selector or context - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - - // Try to shortcut find operations (as opposed to filters) in HTML documents - if ( !seed ) { - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - context = context || document; - - if ( documentIsHTML ) { - - // If the selector is sufficiently simple, try using a "get*By*" DOM method - // (excepting DocumentFragment context, where the methods don't exist) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - - // ID selector - if ( (m = match[1]) ) { - - // Document context - if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // Element context - } else { - - // Support: IE, Opera, Webkit - // TODO: identify versions - // getElementById can match elements by name instead of ID - if ( newContext && (elem = newContext.getElementById( m )) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // Type selector - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Class selector - } else if ( (m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // Take advantage of querySelectorAll - if ( support.qsa && - !compilerCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - - if ( nodeType !== 1 ) { - newContext = context; - newSelector = selector; - - // qSA looks outside Element context, which is not what we want - // Thanks to Andrew Dupont for this workaround technique - // Support: IE <=8 - // Exclude object elements - } else if ( context.nodeName.toLowerCase() !== "object" ) { - - // Capture the context ID, setting it first if necessary - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rcssescape, fcssescape ); - } else { - context.setAttribute( "id", (nid = expando) ); - } - - // Prefix every selector in the list - groups = tokenize( selector ); - i = groups.length; - while ( i-- ) { - groups[i] = "#" + nid + " " + toSelector( groups[i] ); - } - newSelector = groups.join( "," ); - - // Expand context for sibling selectors - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {function(string, object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created element and returns a boolean result - */ -function assert( fn ) { - var el = document.createElement("fieldset"); - - try { - return !!fn( el ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( el.parentNode ) { - el.parentNode.removeChild( el ); - } - // release memory in IE - el = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = arr.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - a.sourceIndex - b.sourceIndex; - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for :enabled/:disabled - * @param {Boolean} disabled true for :disabled; false for :enabled - */ -function createDisabledPseudo( disabled ) { - - // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable - return function( elem ) { - - // Only certain elements can match :enabled or :disabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled - // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled - if ( "form" in elem ) { - - // Check for inherited disabledness on relevant non-disabled elements: - // * listed form-associated elements in a disabled fieldset - // https://html.spec.whatwg.org/multipage/forms.html#category-listed - // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled - // * option elements in a disabled optgroup - // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled - // All such elements have a "form" property. - if ( elem.parentNode && elem.disabled === false ) { - - // Option elements defer to a parent optgroup if present - if ( "label" in elem ) { - if ( "label" in elem.parentNode ) { - return elem.parentNode.disabled === disabled; - } else { - return elem.disabled === disabled; - } - } - - // Support: IE 6 - 11 - // Use the isDisabled shortcut property to check for disabled fieldset ancestors - return elem.isDisabled === disabled || - - // Where there is no isDisabled, check manually - /* jshint -W018 */ - elem.isDisabled !== !disabled && - disabledAncestor( elem ) === disabled; - } - - return elem.disabled === disabled; - - // Try to winnow out elements that can't be disabled before trusting the disabled property. - // Some victims get caught in our net (label, legend, menu, track), but it shouldn't - // even exist on them, let alone have a boolean value. - } else if ( "label" in elem ) { - return elem.disabled === disabled; - } - - // Remaining elements are neither :enabled nor :disabled - return false; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, subWindow, - doc = node ? node.ownerDocument || node : preferredDoc; - - // Return early if doc is invalid or already selected - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Update global variables - document = doc; - docElem = document.documentElement; - documentIsHTML = !isXML( document ); - - // Support: IE 9-11, Edge - // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) - if ( preferredDoc !== document && - (subWindow = document.defaultView) && subWindow.top !== subWindow ) { - - // Support: IE 11, Edge - if ( subWindow.addEventListener ) { - subWindow.addEventListener( "unload", unloadHandler, false ); - - // Support: IE 9 - 10 only - } else if ( subWindow.attachEvent ) { - subWindow.attachEvent( "onunload", unloadHandler ); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) - support.attributes = assert(function( el ) { - el.className = "i"; - return !el.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( el ) { - el.appendChild( document.createComment("") ); - return !el.getElementsByTagName("*").length; - }); - - // Support: IE<9 - support.getElementsByClassName = rnative.test( document.getElementsByClassName ); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programmatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( el ) { - docElem.appendChild( el ).id = expando; - return !document.getElementsByName || !document.getElementsByName( expando ).length; - }); - - // ID filter and find - if ( support.getById ) { - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var elem = context.getElementById( id ); - return elem ? [ elem ] : []; - } - }; - } else { - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && - elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - - // Support: IE 6 - 7 only - // getElementById is not reliable as a find shortcut - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { - var node, i, elems, - elem = context.getElementById( id ); - - if ( elem ) { - - // Verify the id attribute - node = elem.getAttributeNode("id"); - if ( node && node.value === id ) { - return [ elem ]; - } - - // Fall back on getElementsByName - elems = context.getElementsByName( id ); - i = 0; - while ( (elem = elems[i++]) ) { - node = elem.getAttributeNode("id"); - if ( node && node.value === id ) { - return [ elem ]; - } - } - } - - return []; - } - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { - return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); - } - } : - - function( tag, context ) { - var elem, - tmp = [], - i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See https://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( el ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // https://bugs.jquery.com/ticket/12359 - docElem.appendChild( el ).innerHTML = "" + - ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( el.querySelectorAll("[msallowcapture^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !el.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ - if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !el.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibling-combinator selector` fails - if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); - } - }); - - assert(function( el ) { - el.innerHTML = "" + - ""; - - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = document.createElement("input"); - input.setAttribute( "type", "hidden" ); - el.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( el.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( el.querySelectorAll(":enabled").length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Support: IE9-11+ - // IE's :disabled selector does not pick up the children of disabled fieldsets - docElem.appendChild( el ).disabled = true; - if ( el.querySelectorAll(":disabled").length !== 2 ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - el.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( el ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( el, "*" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( el, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully self-exclusive - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === document ? -1 : - b === document ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return document; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - !compilerCache[ expr + " " ] && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch (e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.escape = function( sel ) { - return (sel + "").replace( rcssescape, fcssescape ); -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, uniqueCache, outerCache, node, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType, - diff = false; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) { - - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - - // Seek `elem` from a previously-cached index - - // ...in a gzip-friendly way - node = parent; - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex && cache[ 2 ]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - } else { - // Use previously-cached element index if available - if ( useCache ) { - // ...in a gzip-friendly way - node = elem; - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - cache = uniqueCache[ type ] || []; - nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; - diff = nodeIndex; - } - - // xml :nth-child(...) - // or :nth-last-child(...) or :nth(-last)?-of-type(...) - if ( diff === false ) { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? - node.nodeName.toLowerCase() === name : - node.nodeType === 1 ) && - ++diff ) { - - // Cache the index of each encountered element - if ( useCache ) { - outerCache = node[ expando ] || (node[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ node.uniqueID ] || - (outerCache[ node.uniqueID ] = {}); - - uniqueCache[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - // Don't keep the element (issue #299) - input[0] = null; - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - text = text.replace( runescape, funescape ); - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": createDisabledPseudo( false ), - "disabled": createDisabledPseudo( true ), - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - skip = combinator.next, - key = skip || dir, - checkNonElements = base && key === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - return false; - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, uniqueCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - - // Support: IE <9 only - // Defend against cloned attroperties (jQuery gh-1709) - uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); - - if ( skip && skip === elem.nodeName.toLowerCase() ) { - elem = elem[ dir ] || elem; - } else if ( (oldCache = uniqueCache[ key ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - uniqueCache[ key ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - return false; - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context === document || context || outermost; - } - - // Add elements passing elementMatchers directly to results - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - if ( !context && elem.ownerDocument !== document ) { - setDocument( elem ); - xml = !documentIsHTML; - } - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context || document, xml) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // `i` is now the count of elements visited above, and adding it to `matchedCount` - // makes the latter nonnegative. - matchedCount += i; - - // Apply set filters to unmatched elements - // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` - // equals `i`), unless we didn't visit _any_ elements in the above loop because we have - // no element matchers and no seed. - // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that - // case, which will result in a "00" `matchedCount` that differs from `i` but is also - // numerically zero. - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is only one selector in the list and no seed - // (the latter of which guarantees us context) - if ( match.length === 1 ) { - - // Reduce context if the leading compound selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - !context || rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome 14-35+ -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( el ) { - // Should return 1, but returns 4 (following) - return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( el ) { - el.innerHTML = ""; - return el.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( el ) { - el.innerHTML = ""; - el.firstChild.setAttribute( "value", "" ); - return el.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( el ) { - return el.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -return Sizzle; - -})( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; - -// Deprecated -jQuery.expr[ ":" ] = jQuery.expr.pseudos; -jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; -jQuery.escapeSelector = Sizzle.escape; - - - - -var dir = function( elem, dir, until ) { - var matched = [], - truncate = until !== undefined; - - while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { - if ( elem.nodeType === 1 ) { - if ( truncate && jQuery( elem ).is( until ) ) { - break; - } - matched.push( elem ); - } - } - return matched; -}; - - -var siblings = function( n, elem ) { - var matched = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - matched.push( n ); - } - } - - return matched; -}; - - -var rneedsContext = jQuery.expr.match.needsContext; - - - -function nodeName( elem, name ) { - - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - -}; -var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); - - - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - return !!qualifier.call( elem, i, elem ) !== not; - } ); - } - - // Single element - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - } ); - } - - // Arraylike of elements (jQuery, arguments, Array) - if ( typeof qualifier !== "string" ) { - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not; - } ); - } - - // Simple selector that can be filtered directly, removing non-Elements - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - // Complex selector, compare the two sets, removing non-Elements - qualifier = jQuery.filter( qualifier, elements ); - return jQuery.grep( elements, function( elem ) { - return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; - } ); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - if ( elems.length === 1 && elem.nodeType === 1 ) { - return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; - } - - return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - } ) ); -}; - -jQuery.fn.extend( { - find: function( selector ) { - var i, ret, - len = this.length, - self = this; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter( function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - } ) ); - } - - ret = this.pushStack( [] ); - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - return len > 1 ? jQuery.uniqueSort( ret ) : ret; - }, - filter: function( selector ) { - return this.pushStack( winnow( this, selector || [], false ) ); - }, - not: function( selector ) { - return this.pushStack( winnow( this, selector || [], true ) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -} ); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - // Shortcut simple #id case for speed - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - - init = jQuery.fn.init = function( selector, context, root ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Method init() accepts an alternate rootjQuery - // so migrate can support jQuery.sub (gh-2101) - root = root || rootjQuery; - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector[ 0 ] === "<" && - selector[ selector.length - 1 ] === ">" && - selector.length >= 3 ) { - - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && ( match[ 1 ] || !context ) ) { - - // HANDLE: $(html) -> $(array) - if ( match[ 1 ] ) { - context = context instanceof jQuery ? context[ 0 ] : context; - - // Option to run scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[ 1 ], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[ 2 ] ); - - if ( elem ) { - - // Inject the element directly into the jQuery object - this[ 0 ] = elem; - this.length = 1; - } - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || root ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this[ 0 ] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return root.ready !== undefined ? - root.ready( selector ) : - - // Execute immediately if ready is not present - selector( jQuery ); - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - - // Methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.fn.extend( { - has: function( target ) { - var targets = jQuery( target, this ), - l = targets.length; - - return this.filter( function() { - var i = 0; - for ( ; i < l; i++ ) { - if ( jQuery.contains( this, targets[ i ] ) ) { - return true; - } - } - } ); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - targets = typeof selectors !== "string" && jQuery( selectors ); - - // Positional selectors never match, since there's no _selection_ context - if ( !rneedsContext.test( selectors ) ) { - for ( ; i < l; i++ ) { - for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { - - // Always skip document fragments - if ( cur.nodeType < 11 && ( targets ? - targets.index( cur ) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector( cur, selectors ) ) ) { - - matched.push( cur ); - break; - } - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); - }, - - // Determine the position of an element within the set - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; - } - - // Index in selector - if ( typeof elem === "string" ) { - return indexOf.call( jQuery( elem ), this[ 0 ] ); - } - - // Locate the position of the desired element - return indexOf.call( this, - - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[ 0 ] : elem - ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.uniqueSort( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - } -} ); - -function sibling( cur, dir ) { - while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} - return cur; -} - -jQuery.each( { - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return siblings( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return siblings( elem.firstChild ); - }, - contents: function( elem ) { - if ( nodeName( elem, "iframe" ) ) { - return elem.contentDocument; - } - - // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only - // Treat the template element as a regular one in browsers that - // don't support it. - if ( nodeName( elem, "template" ) ) { - elem = elem.content || elem; - } - - return jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var matched = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - matched = jQuery.filter( selector, matched ); - } - - if ( this.length > 1 ) { - - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - jQuery.uniqueSort( matched ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - matched.reverse(); - } - } - - return this.pushStack( matched ); - }; -} ); -var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); - - - -// Convert String-formatted options into Object-formatted ones -function createOptions( options ) { - var object = {}; - jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { - object[ flag ] = true; - } ); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - createOptions( options ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - - // Last fire value for non-forgettable lists - memory, - - // Flag to know if list was already fired - fired, - - // Flag to prevent firing - locked, - - // Actual callback list - list = [], - - // Queue of execution data for repeatable lists - queue = [], - - // Index of currently firing callback (modified by add/remove as needed) - firingIndex = -1, - - // Fire callbacks - fire = function() { - - // Enforce single-firing - locked = locked || options.once; - - // Execute callbacks for all pending executions, - // respecting firingIndex overrides and runtime changes - fired = firing = true; - for ( ; queue.length; firingIndex = -1 ) { - memory = queue.shift(); - while ( ++firingIndex < list.length ) { - - // Run callback and check for early termination - if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && - options.stopOnFalse ) { - - // Jump to end and forget the data so .add doesn't re-fire - firingIndex = list.length; - memory = false; - } - } - } - - // Forget the data if we're done with it - if ( !options.memory ) { - memory = false; - } - - firing = false; - - // Clean up if we're done firing for good - if ( locked ) { - - // Keep an empty list if we have data for future add calls - if ( memory ) { - list = []; - - // Otherwise, this object is spent - } else { - list = ""; - } - } - }, - - // Actual Callbacks object - self = { - - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - - // If we have memory from a past run, we should fire after adding - if ( memory && !firing ) { - firingIndex = list.length - 1; - queue.push( memory ); - } - - ( function add( args ) { - jQuery.each( args, function( _, arg ) { - if ( jQuery.isFunction( arg ) ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { - - // Inspect recursively - add( arg ); - } - } ); - } )( arguments ); - - if ( memory && !firing ) { - fire(); - } - } - return this; - }, - - // Remove a callback from the list - remove: function() { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - - // Handle firing indexes - if ( index <= firingIndex ) { - firingIndex--; - } - } - } ); - return this; - }, - - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? - jQuery.inArray( fn, list ) > -1 : - list.length > 0; - }, - - // Remove all callbacks from the list - empty: function() { - if ( list ) { - list = []; - } - return this; - }, - - // Disable .fire and .add - // Abort any current/pending executions - // Clear all callbacks and values - disable: function() { - locked = queue = []; - list = memory = ""; - return this; - }, - disabled: function() { - return !list; - }, - - // Disable .fire - // Also disable .add unless we have memory (since it would have no effect) - // Abort any pending executions - lock: function() { - locked = queue = []; - if ( !memory && !firing ) { - list = memory = ""; - } - return this; - }, - locked: function() { - return !!locked; - }, - - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( !locked ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - queue.push( args ); - if ( !firing ) { - fire(); - } - } - return this; - }, - - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -function Identity( v ) { - return v; -} -function Thrower( ex ) { - throw ex; -} - -function adoptValue( value, resolve, reject, noValue ) { - var method; - - try { - - // Check for promise aspect first to privilege synchronous behavior - if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { - method.call( value ).done( resolve ).fail( reject ); - - // Other thenables - } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { - method.call( value, resolve, reject ); - - // Other non-thenables - } else { - - // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: - // * false: [ value ].slice( 0 ) => resolve( value ) - // * true: [ value ].slice( 1 ) => resolve() - resolve.apply( undefined, [ value ].slice( noValue ) ); - } - - // For Promises/A+, convert exceptions into rejections - // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in - // Deferred#then to conditionally suppress rejection. - } catch ( value ) { - - // Support: Android 4.0 only - // Strict mode functions invoked without .call/.apply get global-object context - reject.apply( undefined, [ value ] ); - } -} - -jQuery.extend( { - - Deferred: function( func ) { - var tuples = [ - - // action, add listener, callbacks, - // ... .then handlers, argument index, [final state] - [ "notify", "progress", jQuery.Callbacks( "memory" ), - jQuery.Callbacks( "memory" ), 2 ], - [ "resolve", "done", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 0, "resolved" ], - [ "reject", "fail", jQuery.Callbacks( "once memory" ), - jQuery.Callbacks( "once memory" ), 1, "rejected" ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - "catch": function( fn ) { - return promise.then( null, fn ); - }, - - // Keep pipe for back-compat - pipe: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - - return jQuery.Deferred( function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - - // Map tuples (progress, done, fail) to arguments (done, fail, progress) - var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; - - // deferred.progress(function() { bind to newDefer or newDefer.notify }) - // deferred.done(function() { bind to newDefer or newDefer.resolve }) - // deferred.fail(function() { bind to newDefer or newDefer.reject }) - deferred[ tuple[ 1 ] ]( function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .progress( newDefer.notify ) - .done( newDefer.resolve ) - .fail( newDefer.reject ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( - this, - fn ? [ returned ] : arguments - ); - } - } ); - } ); - fns = null; - } ).promise(); - }, - then: function( onFulfilled, onRejected, onProgress ) { - var maxDepth = 0; - function resolve( depth, deferred, handler, special ) { - return function() { - var that = this, - args = arguments, - mightThrow = function() { - var returned, then; - - // Support: Promises/A+ section 2.3.3.3.3 - // https://promisesaplus.com/#point-59 - // Ignore double-resolution attempts - if ( depth < maxDepth ) { - return; - } - - returned = handler.apply( that, args ); - - // Support: Promises/A+ section 2.3.1 - // https://promisesaplus.com/#point-48 - if ( returned === deferred.promise() ) { - throw new TypeError( "Thenable self-resolution" ); - } - - // Support: Promises/A+ sections 2.3.3.1, 3.5 - // https://promisesaplus.com/#point-54 - // https://promisesaplus.com/#point-75 - // Retrieve `then` only once - then = returned && - - // Support: Promises/A+ section 2.3.4 - // https://promisesaplus.com/#point-64 - // Only check objects and functions for thenability - ( typeof returned === "object" || - typeof returned === "function" ) && - returned.then; - - // Handle a returned thenable - if ( jQuery.isFunction( then ) ) { - - // Special processors (notify) just wait for resolution - if ( special ) { - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ) - ); - - // Normal processors (resolve) also hook into progress - } else { - - // ...and disregard older resolution values - maxDepth++; - - then.call( - returned, - resolve( maxDepth, deferred, Identity, special ), - resolve( maxDepth, deferred, Thrower, special ), - resolve( maxDepth, deferred, Identity, - deferred.notifyWith ) - ); - } - - // Handle all other returned values - } else { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Identity ) { - that = undefined; - args = [ returned ]; - } - - // Process the value(s) - // Default process is resolve - ( special || deferred.resolveWith )( that, args ); - } - }, - - // Only normal processors (resolve) catch and reject exceptions - process = special ? - mightThrow : - function() { - try { - mightThrow(); - } catch ( e ) { - - if ( jQuery.Deferred.exceptionHook ) { - jQuery.Deferred.exceptionHook( e, - process.stackTrace ); - } - - // Support: Promises/A+ section 2.3.3.3.4.1 - // https://promisesaplus.com/#point-61 - // Ignore post-resolution exceptions - if ( depth + 1 >= maxDepth ) { - - // Only substitute handlers pass on context - // and multiple values (non-spec behavior) - if ( handler !== Thrower ) { - that = undefined; - args = [ e ]; - } - - deferred.rejectWith( that, args ); - } - } - }; - - // Support: Promises/A+ section 2.3.3.3.1 - // https://promisesaplus.com/#point-57 - // Re-resolve promises immediately to dodge false rejection from - // subsequent errors - if ( depth ) { - process(); - } else { - - // Call an optional hook to record the stack, in case of exception - // since it's otherwise lost when execution goes async - if ( jQuery.Deferred.getStackHook ) { - process.stackTrace = jQuery.Deferred.getStackHook(); - } - window.setTimeout( process ); - } - }; - } - - return jQuery.Deferred( function( newDefer ) { - - // progress_handlers.add( ... ) - tuples[ 0 ][ 3 ].add( - resolve( - 0, - newDefer, - jQuery.isFunction( onProgress ) ? - onProgress : - Identity, - newDefer.notifyWith - ) - ); - - // fulfilled_handlers.add( ... ) - tuples[ 1 ][ 3 ].add( - resolve( - 0, - newDefer, - jQuery.isFunction( onFulfilled ) ? - onFulfilled : - Identity - ) - ); - - // rejected_handlers.add( ... ) - tuples[ 2 ][ 3 ].add( - resolve( - 0, - newDefer, - jQuery.isFunction( onRejected ) ? - onRejected : - Thrower - ) - ); - } ).promise(); - }, - - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 5 ]; - - // promise.progress = list.add - // promise.done = list.add - // promise.fail = list.add - promise[ tuple[ 1 ] ] = list.add; - - // Handle state - if ( stateString ) { - list.add( - function() { - - // state = "resolved" (i.e., fulfilled) - // state = "rejected" - state = stateString; - }, - - // rejected_callbacks.disable - // fulfilled_callbacks.disable - tuples[ 3 - i ][ 2 ].disable, - - // progress_callbacks.lock - tuples[ 0 ][ 2 ].lock - ); - } - - // progress_handlers.fire - // fulfilled_handlers.fire - // rejected_handlers.fire - list.add( tuple[ 3 ].fire ); - - // deferred.notify = function() { deferred.notifyWith(...) } - // deferred.resolve = function() { deferred.resolveWith(...) } - // deferred.reject = function() { deferred.rejectWith(...) } - deferred[ tuple[ 0 ] ] = function() { - deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); - return this; - }; - - // deferred.notifyWith = list.fireWith - // deferred.resolveWith = list.fireWith - // deferred.rejectWith = list.fireWith - deferred[ tuple[ 0 ] + "With" ] = list.fireWith; - } ); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( singleValue ) { - var - - // count of uncompleted subordinates - remaining = arguments.length, - - // count of unprocessed arguments - i = remaining, - - // subordinate fulfillment data - resolveContexts = Array( i ), - resolveValues = slice.call( arguments ), - - // the master Deferred - master = jQuery.Deferred(), - - // subordinate callback factory - updateFunc = function( i ) { - return function( value ) { - resolveContexts[ i ] = this; - resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( !( --remaining ) ) { - master.resolveWith( resolveContexts, resolveValues ); - } - }; - }; - - // Single- and empty arguments are adopted like Promise.resolve - if ( remaining <= 1 ) { - adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, - !remaining ); - - // Use .then() to unwrap secondary thenables (cf. gh-3000) - if ( master.state() === "pending" || - jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { - - return master.then(); - } - } - - // Multiple arguments are aggregated like Promise.all array elements - while ( i-- ) { - adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); - } - - return master.promise(); - } -} ); - - -// These usually indicate a programmer mistake during development, -// warn about them ASAP rather than swallowing them by default. -var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - -jQuery.Deferred.exceptionHook = function( error, stack ) { - - // Support: IE 8 - 9 only - // Console exists when dev tools are open, which can happen at any time - if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { - window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); - } -}; - - - - -jQuery.readyException = function( error ) { - window.setTimeout( function() { - throw error; - } ); -}; - - - - -// The deferred used on DOM ready -var readyList = jQuery.Deferred(); - -jQuery.fn.ready = function( fn ) { - - readyList - .then( fn ) - - // Wrap jQuery.readyException in a function so that the lookup - // happens at the time of error handling instead of callback - // registration. - .catch( function( error ) { - jQuery.readyException( error ); - } ); - - return this; -}; - -jQuery.extend( { - - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - } -} ); - -jQuery.ready.then = readyList.then; - -// The ready event handler and self cleanup method -function completed() { - document.removeEventListener( "DOMContentLoaded", completed ); - window.removeEventListener( "load", completed ); - jQuery.ready(); -} - -// Catch cases where $(document).ready() is called -// after the browser event has already occurred. -// Support: IE <=9 - 10 only -// Older IE sometimes signals "interactive" too soon -if ( document.readyState === "complete" || - ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { - - // Handle it asynchronously to allow scripts the opportunity to delay ready - window.setTimeout( jQuery.ready ); - -} else { - - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed ); -} - - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - len = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - access( elems, fn, i, key[ i ], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < len; i++ ) { - fn( - elems[ i ], key, raw ? - value : - value.call( elems[ i ], i, fn( elems[ i ], key ) ) - ); - } - } - } - - if ( chainable ) { - return elems; - } - - // Gets - if ( bulk ) { - return fn.call( elems ); - } - - return len ? fn( elems[ 0 ], key ) : emptyGet; -}; -var acceptData = function( owner ) { - - // Accepts only: - // - Node - // - Node.ELEMENT_NODE - // - Node.DOCUMENT_NODE - // - Object - // - Any - return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); -}; - - - - -function Data() { - this.expando = jQuery.expando + Data.uid++; -} - -Data.uid = 1; - -Data.prototype = { - - cache: function( owner ) { - - // Check if the owner object already has a cache - var value = owner[ this.expando ]; - - // If not, create one - if ( !value ) { - value = {}; - - // We can accept data for non-element nodes in modern browsers, - // but we should not, see #8335. - // Always return an empty object. - if ( acceptData( owner ) ) { - - // If it is a node unlikely to be stringify-ed or looped over - // use plain assignment - if ( owner.nodeType ) { - owner[ this.expando ] = value; - - // Otherwise secure it in a non-enumerable property - // configurable must be true to allow the property to be - // deleted when data is removed - } else { - Object.defineProperty( owner, this.expando, { - value: value, - configurable: true - } ); - } - } - } - - return value; - }, - set: function( owner, data, value ) { - var prop, - cache = this.cache( owner ); - - // Handle: [ owner, key, value ] args - // Always use camelCase key (gh-2257) - if ( typeof data === "string" ) { - cache[ jQuery.camelCase( data ) ] = value; - - // Handle: [ owner, { properties } ] args - } else { - - // Copy the properties one-by-one to the cache object - for ( prop in data ) { - cache[ jQuery.camelCase( prop ) ] = data[ prop ]; - } - } - return cache; - }, - get: function( owner, key ) { - return key === undefined ? - this.cache( owner ) : - - // Always use camelCase key (gh-2257) - owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; - }, - access: function( owner, key, value ) { - - // In cases where either: - // - // 1. No key was specified - // 2. A string key was specified, but no value provided - // - // Take the "read" path and allow the get method to determine - // which value to return, respectively either: - // - // 1. The entire cache object - // 2. The data stored at the key - // - if ( key === undefined || - ( ( key && typeof key === "string" ) && value === undefined ) ) { - - return this.get( owner, key ); - } - - // When the key is not a string, or both a key and value - // are specified, set or extend (existing objects) with either: - // - // 1. An object of properties - // 2. A key and value - // - this.set( owner, key, value ); - - // Since the "set" path can have two possible entry points - // return the expected data based on which path was taken[*] - return value !== undefined ? value : key; - }, - remove: function( owner, key ) { - var i, - cache = owner[ this.expando ]; - - if ( cache === undefined ) { - return; - } - - if ( key !== undefined ) { - - // Support array or space separated string of keys - if ( Array.isArray( key ) ) { - - // If key is an array of keys... - // We always set camelCase keys, so remove that. - key = key.map( jQuery.camelCase ); - } else { - key = jQuery.camelCase( key ); - - // If a key with the spaces exists, use it. - // Otherwise, create an array by matching non-whitespace - key = key in cache ? - [ key ] : - ( key.match( rnothtmlwhite ) || [] ); - } - - i = key.length; - - while ( i-- ) { - delete cache[ key[ i ] ]; - } - } - - // Remove the expando if there's no more data - if ( key === undefined || jQuery.isEmptyObject( cache ) ) { - - // Support: Chrome <=35 - 45 - // Webkit & Blink performance suffers when deleting properties - // from DOM nodes, so set to undefined instead - // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) - if ( owner.nodeType ) { - owner[ this.expando ] = undefined; - } else { - delete owner[ this.expando ]; - } - } - }, - hasData: function( owner ) { - var cache = owner[ this.expando ]; - return cache !== undefined && !jQuery.isEmptyObject( cache ); - } -}; -var dataPriv = new Data(); - -var dataUser = new Data(); - - - -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /[A-Z]/g; - -function getData( data ) { - if ( data === "true" ) { - return true; - } - - if ( data === "false" ) { - return false; - } - - if ( data === "null" ) { - return null; - } - - // Only convert to a number if it doesn't change the string - if ( data === +data + "" ) { - return +data; - } - - if ( rbrace.test( data ) ) { - return JSON.parse( data ); - } - - return data; -} - -function dataAttr( elem, key, data ) { - var name; - - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = getData( data ); - } catch ( e ) {} - - // Make sure we set the data so it isn't changed later - dataUser.set( elem, key, data ); - } else { - data = undefined; - } - } - return data; -} - -jQuery.extend( { - hasData: function( elem ) { - return dataUser.hasData( elem ) || dataPriv.hasData( elem ); - }, - - data: function( elem, name, data ) { - return dataUser.access( elem, name, data ); - }, - - removeData: function( elem, name ) { - dataUser.remove( elem, name ); - }, - - // TODO: Now that all calls to _data and _removeData have been replaced - // with direct calls to dataPriv methods, these can be deprecated. - _data: function( elem, name, data ) { - return dataPriv.access( elem, name, data ); - }, - - _removeData: function( elem, name ) { - dataPriv.remove( elem, name ); - } -} ); - -jQuery.fn.extend( { - data: function( key, value ) { - var i, name, data, - elem = this[ 0 ], - attrs = elem && elem.attributes; - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = dataUser.get( elem ); - - if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE 11 only - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice( 5 ) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - dataPriv.set( elem, "hasDataAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each( function() { - dataUser.set( this, key ); - } ); - } - - return access( this, function( value ) { - var data; - - // The calling jQuery object (element matches) is not empty - // (and therefore has an element appears at this[ 0 ]) and the - // `value` parameter was not undefined. An empty jQuery object - // will result in `undefined` for elem = this[ 0 ] which will - // throw an exception if an attempt to read a data cache is made. - if ( elem && value === undefined ) { - - // Attempt to get data from the cache - // The key will always be camelCased in Data - data = dataUser.get( elem, key ); - if ( data !== undefined ) { - return data; - } - - // Attempt to "discover" the data in - // HTML5 custom data-* attrs - data = dataAttr( elem, key ); - if ( data !== undefined ) { - return data; - } - - // We tried really hard, but the data doesn't exist. - return; - } - - // Set the data... - this.each( function() { - - // We always store the camelCased key - dataUser.set( this, key, value ); - } ); - }, null, value, arguments.length > 1, null, true ); - }, - - removeData: function( key ) { - return this.each( function() { - dataUser.remove( this, key ); - } ); - } -} ); - - -jQuery.extend( { - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = dataPriv.get( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || Array.isArray( data ) ) { - queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // Clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // Not public - generate a queueHooks object, or return the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { - empty: jQuery.Callbacks( "once memory" ).add( function() { - dataPriv.remove( elem, [ type + "queue", key ] ); - } ) - } ); - } -} ); - -jQuery.fn.extend( { - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[ 0 ], type ); - } - - return data === undefined ? - this : - this.each( function() { - var queue = jQuery.queue( this, type, data ); - - // Ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - } ); - }, - dequeue: function( type ) { - return this.each( function() { - jQuery.dequeue( this, type ); - } ); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -} ); -var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; - -var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); - - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var isHiddenWithinTree = function( elem, el ) { - - // isHiddenWithinTree might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - - // Inline style trumps all - return elem.style.display === "none" || - elem.style.display === "" && - - // Otherwise, check computed style - // Support: Firefox <=43 - 45 - // Disconnected elements can have computed display: none, so first confirm that elem is - // in the document. - jQuery.contains( elem.ownerDocument, elem ) && - - jQuery.css( elem, "display" ) === "none"; - }; - -var swap = function( elem, options, callback, args ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; -}; - - - - -function adjustCSS( elem, prop, valueParts, tween ) { - var adjusted, - scale = 1, - maxIterations = 20, - currentValue = tween ? - function() { - return tween.cur(); - } : - function() { - return jQuery.css( elem, prop, "" ); - }, - initial = currentValue(), - unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && - rcssNum.exec( jQuery.css( elem, prop ) ); - - if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { - - // Trust units reported by jQuery.css - unit = unit || initialInUnit[ 3 ]; - - // Make sure we update the tween properties later on - valueParts = valueParts || []; - - // Iteratively approximate from a nonzero starting point - initialInUnit = +initial || 1; - - do { - - // If previous iteration zeroed out, double until we get *something*. - // Use string for doubling so we don't accidentally see scale as unchanged below - scale = scale || ".5"; - - // Adjust and apply - initialInUnit = initialInUnit / scale; - jQuery.style( elem, prop, initialInUnit + unit ); - - // Update scale, tolerating zero or NaN from tween.cur() - // Break the loop if scale is unchanged or perfect, or if we've just had enough. - } while ( - scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations - ); - } - - if ( valueParts ) { - initialInUnit = +initialInUnit || +initial || 0; - - // Apply relative offset (+=/-=) if specified - adjusted = valueParts[ 1 ] ? - initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : - +valueParts[ 2 ]; - if ( tween ) { - tween.unit = unit; - tween.start = initialInUnit; - tween.end = adjusted; - } - } - return adjusted; -} - - -var defaultDisplayMap = {}; - -function getDefaultDisplay( elem ) { - var temp, - doc = elem.ownerDocument, - nodeName = elem.nodeName, - display = defaultDisplayMap[ nodeName ]; - - if ( display ) { - return display; - } - - temp = doc.body.appendChild( doc.createElement( nodeName ) ); - display = jQuery.css( temp, "display" ); - - temp.parentNode.removeChild( temp ); - - if ( display === "none" ) { - display = "block"; - } - defaultDisplayMap[ nodeName ] = display; - - return display; -} - -function showHide( elements, show ) { - var display, elem, - values = [], - index = 0, - length = elements.length; - - // Determine new display value for elements that need to change - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - display = elem.style.display; - if ( show ) { - - // Since we force visibility upon cascade-hidden elements, an immediate (and slow) - // check is required in this first loop unless we have a nonempty display value (either - // inline or about-to-be-restored) - if ( display === "none" ) { - values[ index ] = dataPriv.get( elem, "display" ) || null; - if ( !values[ index ] ) { - elem.style.display = ""; - } - } - if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { - values[ index ] = getDefaultDisplay( elem ); - } - } else { - if ( display !== "none" ) { - values[ index ] = "none"; - - // Remember what we're overwriting - dataPriv.set( elem, "display", display ); - } - } - } - - // Set the display of the elements in a second loop to avoid constant reflow - for ( index = 0; index < length; index++ ) { - if ( values[ index ] != null ) { - elements[ index ].style.display = values[ index ]; - } - } - - return elements; -} - -jQuery.fn.extend( { - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each( function() { - if ( isHiddenWithinTree( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - } ); - } -} ); -var rcheckableType = ( /^(?:checkbox|radio)$/i ); - -var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); - -var rscriptType = ( /^$|\/(?:java|ecma)script/i ); - - - -// We have to close these tags to support XHTML (#13200) -var wrapMap = { - - // Support: IE <=9 only - option: [ 1, "" ], - - // XHTML parsers do not magically insert elements in the - // same way that tag soup parsers do. So we cannot shorten - // this by omitting or other required elements. - thead: [ 1, "", "
" ], - col: [ 2, "", "
" ], - tr: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - _default: [ 0, "", "" ] -}; - -// Support: IE <=9 only -wrapMap.optgroup = wrapMap.option; - -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - - -function getAll( context, tag ) { - - // Support: IE <=9 - 11 only - // Use typeof to avoid zero-argument method invocation on host objects (#15151) - var ret; - - if ( typeof context.getElementsByTagName !== "undefined" ) { - ret = context.getElementsByTagName( tag || "*" ); - - } else if ( typeof context.querySelectorAll !== "undefined" ) { - ret = context.querySelectorAll( tag || "*" ); - - } else { - ret = []; - } - - if ( tag === undefined || tag && nodeName( context, tag ) ) { - return jQuery.merge( [ context ], ret ); - } - - return ret; -} - - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - dataPriv.set( - elems[ i ], - "globalEval", - !refElements || dataPriv.get( refElements[ i ], "globalEval" ) - ); - } -} - - -var rhtml = /<|&#?\w+;/; - -function buildFragment( elems, context, scripts, selection, ignored ) { - var elem, tmp, tag, wrap, contains, j, - fragment = context.createDocumentFragment(), - nodes = [], - i = 0, - l = elems.length; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; - - // Descend through wrappers to the right content - j = wrap[ 0 ]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( nodes, tmp.childNodes ); - - // Remember the top-level container - tmp = fragment.firstChild; - - // Ensure the created nodes are orphaned (#12392) - tmp.textContent = ""; - } - } - } - - // Remove wrapper from fragment - fragment.textContent = ""; - - i = 0; - while ( ( elem = nodes[ i++ ] ) ) { - - // Skip elements already in the context collection (trac-4087) - if ( selection && jQuery.inArray( elem, selection ) > -1 ) { - if ( ignored ) { - ignored.push( elem ); - } - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( fragment.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( ( elem = tmp[ j++ ] ) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - return fragment; -} - - -( function() { - var fragment = document.createDocumentFragment(), - div = fragment.appendChild( document.createElement( "div" ) ), - input = document.createElement( "input" ); - - // Support: Android 4.0 - 4.3 only - // Check state lost if the name is set (#11217) - // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) - input.setAttribute( "type", "radio" ); - input.setAttribute( "checked", "checked" ); - input.setAttribute( "name", "t" ); - - div.appendChild( input ); - - // Support: Android <=4.1 only - // Older WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE <=11 only - // Make sure textarea (and checkbox) defaultValue is properly cloned - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; -} )(); -var documentElement = document.documentElement; - - - -var - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -// Support: IE <=9 only -// See #13393 for more info -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -function on( elem, types, selector, data, fn, one ) { - var origFn, type; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - on( elem, type, selector, data, types[ type ], one ); - } - return elem; - } - - if ( data == null && fn == null ) { - - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return elem; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return elem.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - } ); -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.get( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Ensure that invalid selectors throw exceptions at attach time - // Evaluate against documentElement in case elem is a non-element node (e.g., document) - if ( selector ) { - jQuery.find.matchesSelector( documentElement, selector ); - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !( events = elemData.events ) ) { - events = elemData.events = {}; - } - if ( !( eventHandle = elemData.handle ) ) { - eventHandle = elemData.handle = function( e ) { - - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? - jQuery.event.dispatch.apply( elem, arguments ) : undefined; - }; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend( { - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join( "." ) - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !( handlers = events[ type ] ) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener if the special events handler returns false - if ( !special.setup || - special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - - var j, origCount, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, - elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); - - if ( !elemData || !( events = elemData.events ) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[ t ] ) || []; - type = origType = tmp[ 1 ]; - namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[ 2 ] && - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || - selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || - special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove data and the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - dataPriv.remove( elem, "handle events" ); - } - }, - - dispatch: function( nativeEvent ) { - - // Make a writable jQuery.Event from the native event object - var event = jQuery.event.fix( nativeEvent ); - - var i, j, ret, matched, handleObj, handlerQueue, - args = new Array( arguments.length ), - handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[ 0 ] = event; - - for ( i = 1; i < arguments.length; i++ ) { - args[ i ] = arguments[ i ]; - } - - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( ( handleObj = matched.handlers[ j++ ] ) && - !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). - if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || - handleObj.handler ).apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( ( event.result = ret ) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var i, handleObj, sel, matchedHandlers, matchedSelectors, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - if ( delegateCount && - - // Support: IE <=9 - // Black-hole SVG instance trees (trac-13180) - cur.nodeType && - - // Support: Firefox <=42 - // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) - // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click - // Support: IE 11 only - // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) - !( event.type === "click" && event.button >= 1 ) ) { - - for ( ; cur !== this; cur = cur.parentNode || this ) { - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { - matchedHandlers = []; - matchedSelectors = {}; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matchedSelectors[ sel ] === undefined ) { - matchedSelectors[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) > -1 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matchedSelectors[ sel ] ) { - matchedHandlers.push( handleObj ); - } - } - if ( matchedHandlers.length ) { - handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); - } - } - } - } - - // Add the remaining (directly-bound) handlers - cur = this; - if ( delegateCount < handlers.length ) { - handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); - } - - return handlerQueue; - }, - - addProp: function( name, hook ) { - Object.defineProperty( jQuery.Event.prototype, name, { - enumerable: true, - configurable: true, - - get: jQuery.isFunction( hook ) ? - function() { - if ( this.originalEvent ) { - return hook( this.originalEvent ); - } - } : - function() { - if ( this.originalEvent ) { - return this.originalEvent[ name ]; - } - }, - - set: function( value ) { - Object.defineProperty( this, name, { - enumerable: true, - configurable: true, - writable: true, - value: value - } ); - } - } ); - }, - - fix: function( originalEvent ) { - return originalEvent[ jQuery.expando ] ? - originalEvent : - new jQuery.Event( originalEvent ); - }, - - special: { - load: { - - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - this.focus(); - return false; - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - } -}; - -jQuery.removeEvent = function( elem, type, handle ) { - - // This "if" is needed for plain objects - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle ); - } -}; - -jQuery.Event = function( src, props ) { - - // Allow instantiation without the 'new' keyword - if ( !( this instanceof jQuery.Event ) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - - // Support: Android <=2.3 only - src.returnValue === false ? - returnTrue : - returnFalse; - - // Create target properties - // Support: Safari <=6 - 7 only - // Target should not be a text node (#504, #13143) - this.target = ( src.target && src.target.nodeType === 3 ) ? - src.target.parentNode : - src.target; - - this.currentTarget = src.currentTarget; - this.relatedTarget = src.relatedTarget; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - constructor: jQuery.Event, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - isSimulated: false, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - - if ( e && !this.isSimulated ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && !this.isSimulated ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Includes all common event props including KeyEvent and MouseEvent specific props -jQuery.each( { - altKey: true, - bubbles: true, - cancelable: true, - changedTouches: true, - ctrlKey: true, - detail: true, - eventPhase: true, - metaKey: true, - pageX: true, - pageY: true, - shiftKey: true, - view: true, - "char": true, - charCode: true, - key: true, - keyCode: true, - button: true, - buttons: true, - clientX: true, - clientY: true, - offsetX: true, - offsetY: true, - pointerId: true, - pointerType: true, - screenX: true, - screenY: true, - targetTouches: true, - toElement: true, - touches: true, - - which: function( event ) { - var button = event.button; - - // Add which for key events - if ( event.which == null && rkeyEvent.test( event.type ) ) { - return event.charCode != null ? event.charCode : event.keyCode; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { - if ( button & 1 ) { - return 1; - } - - if ( button & 2 ) { - return 3; - } - - if ( button & 4 ) { - return 2; - } - - return 0; - } - - return event.which; - } -}, jQuery.event.addProp ); - -// Create mouseenter/leave events using mouseover/out and event-time checks -// so that event delegation works in jQuery. -// Do the same for pointerenter/pointerleave and pointerover/pointerout -// -// Support: Safari 7 only -// Safari sends mouseenter too often; see: -// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 -// for the description of the bug (it existed in older Chrome versions as well). -jQuery.each( { - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mouseenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -} ); - -jQuery.fn.extend( { - - on: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn ); - }, - one: function( types, selector, data, fn ) { - return on( this, types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? - handleObj.origType + "." + handleObj.namespace : - handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each( function() { - jQuery.event.remove( this, types, fn, selector ); - } ); - } -} ); - - -var - - /* eslint-disable max-len */ - - // See https://github.com/eslint/eslint/issues/3229 - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - - /* eslint-enable */ - - // Support: IE <=10 - 11, Edge 12 - 13 - // In IE/Edge using regex groups here causes severe slowdowns. - // See https://connect.microsoft.com/IE/feedback/details/1736512/ - rnoInnerhtml = /\s*$/g; - -// Prefer a tbody over its parent table for containing new rows -function manipulationTarget( elem, content ) { - if ( nodeName( elem, "table" ) && - nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { - - return jQuery( ">tbody", elem )[ 0 ] || elem; - } - - return elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - - if ( match ) { - elem.type = match[ 1 ]; - } else { - elem.removeAttribute( "type" ); - } - - return elem; -} - -function cloneCopyEvent( src, dest ) { - var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; - - if ( dest.nodeType !== 1 ) { - return; - } - - // 1. Copy private data: events, handlers, etc. - if ( dataPriv.hasData( src ) ) { - pdataOld = dataPriv.access( src ); - pdataCur = dataPriv.set( dest, pdataOld ); - events = pdataOld.events; - - if ( events ) { - delete pdataCur.handle; - pdataCur.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - } - - // 2. Copy user data - if ( dataUser.hasData( src ) ) { - udataOld = dataUser.access( src ); - udataCur = jQuery.extend( {}, udataOld ); - - dataUser.set( dest, udataCur ); - } -} - -// Fix IE bugs, see support tests -function fixInput( src, dest ) { - var nodeName = dest.nodeName.toLowerCase(); - - // Fails to persist the checked state of a cloned checkbox or radio button. - if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - dest.checked = src.checked; - - // Fails to return the selected option to the default selected state when cloning options - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -function domManip( collection, args, callback, ignored ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var fragment, first, scripts, hasScripts, node, doc, - i = 0, - l = collection.length, - iNoClone = l - 1, - value = args[ 0 ], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return collection.each( function( index ) { - var self = collection.eq( index ); - if ( isFunction ) { - args[ 0 ] = value.call( this, index, self.html() ); - } - domManip( self, args, callback, ignored ); - } ); - } - - if ( l ) { - fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - // Require either new content or an interest in ignored elements to invoke the callback - if ( first || ignored ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item - // instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - - // Support: Android <=4.0 only, PhantomJS 1 only - // push.apply(_, arraylike) throws on ancient WebKit - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( collection[ i ], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !dataPriv.access( node, "globalEval" ) && - jQuery.contains( doc, node ) ) { - - if ( node.src ) { - - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); - } - } - } - } - } - } - - return collection; -} - -function remove( elem, selector, keepData ) { - var node, - nodes = selector ? jQuery.filter( selector, elem ) : elem, - i = 0; - - for ( ; ( node = nodes[ i ] ) != null; i++ ) { - if ( !keepData && node.nodeType === 1 ) { - jQuery.cleanData( getAll( node ) ); - } - - if ( node.parentNode ) { - if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { - setGlobalEval( getAll( node, "script" ) ); - } - node.parentNode.removeChild( node ); - } - } - - return elem; -} - -jQuery.extend( { - htmlPrefilter: function( html ) { - return html.replace( rxhtmlTag, "<$1>" ); - }, - - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var i, l, srcElements, destElements, - clone = elem.cloneNode( true ), - inPage = jQuery.contains( elem.ownerDocument, elem ); - - // Fix IE cloning issues - if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && - !jQuery.isXMLDoc( elem ) ) { - - // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - fixInput( srcElements[ i ], destElements[ i ] ); - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0, l = srcElements.length; i < l; i++ ) { - cloneCopyEvent( srcElements[ i ], destElements[ i ] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - // Return the cloned set - return clone; - }, - - cleanData: function( elems ) { - var data, elem, type, - special = jQuery.event.special, - i = 0; - - for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { - if ( acceptData( elem ) ) { - if ( ( data = elem[ dataPriv.expando ] ) ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataPriv.expando ] = undefined; - } - if ( elem[ dataUser.expando ] ) { - - // Support: Chrome <=35 - 45+ - // Assign undefined instead of using delete, see Data#remove - elem[ dataUser.expando ] = undefined; - } - } - } - } -} ); - -jQuery.fn.extend( { - detach: function( selector ) { - return remove( this, selector, true ); - }, - - remove: function( selector ) { - return remove( this, selector ); - }, - - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().each( function() { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - this.textContent = value; - } - } ); - }, null, value, arguments.length ); - }, - - append: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - } ); - }, - - prepend: function() { - return domManip( this, arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - } ); - }, - - before: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - } ); - }, - - after: function() { - return domManip( this, arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - } ); - }, - - empty: function() { - var elem, - i = 0; - - for ( ; ( elem = this[ i ] ) != null; i++ ) { - if ( elem.nodeType === 1 ) { - - // Prevent memory leaks - jQuery.cleanData( getAll( elem, false ) ); - - // Remove any remaining nodes - elem.textContent = ""; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - } ); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined && elem.nodeType === 1 ) { - return elem.innerHTML; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { - - value = jQuery.htmlPrefilter( value ); - - try { - for ( ; i < l; i++ ) { - elem = this[ i ] || {}; - - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch ( e ) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var ignored = []; - - // Make the changes, replacing each non-ignored context element with the new content - return domManip( this, arguments, function( elem ) { - var parent = this.parentNode; - - if ( jQuery.inArray( this, ignored ) < 0 ) { - jQuery.cleanData( getAll( this ) ); - if ( parent ) { - parent.replaceChild( elem, this ); - } - } - - // Force callback invocation - }, ignored ); - } -} ); - -jQuery.each( { - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1, - i = 0; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone( true ); - jQuery( insert[ i ] )[ original ]( elems ); - - // Support: Android <=4.0 only, PhantomJS 1 only - // .get() because push.apply(_, arraylike) throws on ancient WebKit - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -} ); -var rmargin = ( /^margin/ ); - -var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); - -var getStyles = function( elem ) { - - // Support: IE <=11 only, Firefox <=30 (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - var view = elem.ownerDocument.defaultView; - - if ( !view || !view.opener ) { - view = window; - } - - return view.getComputedStyle( elem ); - }; - - - -( function() { - - // Executing both pixelPosition & boxSizingReliable tests require only one layout - // so they're executed at the same time to save the second computation. - function computeStyleTests() { - - // This is a singleton, we need to execute it only once - if ( !div ) { - return; - } - - div.style.cssText = - "box-sizing:border-box;" + - "position:relative;display:block;" + - "margin:auto;border:1px;padding:1px;" + - "top:1%;width:50%"; - div.innerHTML = ""; - documentElement.appendChild( container ); - - var divStyle = window.getComputedStyle( div ); - pixelPositionVal = divStyle.top !== "1%"; - - // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 - reliableMarginLeftVal = divStyle.marginLeft === "2px"; - boxSizingReliableVal = divStyle.width === "4px"; - - // Support: Android 4.0 - 4.3 only - // Some styles come back with percentage values, even though they shouldn't - div.style.marginRight = "50%"; - pixelMarginRightVal = divStyle.marginRight === "4px"; - - documentElement.removeChild( container ); - - // Nullify the div so it wouldn't be stored in the memory and - // it will also be a sign that checks already performed - div = null; - } - - var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, - container = document.createElement( "div" ), - div = document.createElement( "div" ); - - // Finish early in limited (non-browser) environments - if ( !div.style ) { - return; - } - - // Support: IE <=9 - 11 only - // Style of cloned element affects source element cloned (#8908) - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + - "padding:0;margin-top:1px;position:absolute"; - container.appendChild( div ); - - jQuery.extend( support, { - pixelPosition: function() { - computeStyleTests(); - return pixelPositionVal; - }, - boxSizingReliable: function() { - computeStyleTests(); - return boxSizingReliableVal; - }, - pixelMarginRight: function() { - computeStyleTests(); - return pixelMarginRightVal; - }, - reliableMarginLeft: function() { - computeStyleTests(); - return reliableMarginLeftVal; - } - } ); -} )(); - - -function curCSS( elem, name, computed ) { - var width, minWidth, maxWidth, ret, - - // Support: Firefox 51+ - // Retrieving style before computed somehow - // fixes an issue with getting wrong values - // on detached elements - style = elem.style; - - computed = computed || getStyles( elem ); - - // getPropertyValue is needed for: - // .css('filter') (IE 9 only, #12537) - // .css('--customProperty) (#3144) - if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; - - if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Android Browser returns percentage for some values, - // but width seems to be reliably pixels. - // This is against the CSSOM draft spec: - // https://drafts.csswg.org/cssom/#resolved-values - if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret !== undefined ? - - // Support: IE <=9 - 11 only - // IE returns zIndex value as an integer. - ret + "" : - ret; -} - - -function addGetHookIf( conditionFn, hookFn ) { - - // Define the hook, we'll check on the first run if it's really needed. - return { - get: function() { - if ( conditionFn() ) { - - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. - delete this.get; - return; - } - - // Hook needed; redefine it so that the support test is not executed again. - return ( this.get = hookFn ).apply( this, arguments ); - } - }; -} - - -var - - // Swappable if display is none or starts with table - // except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: "0", - fontWeight: "400" - }, - - cssPrefixes = [ "Webkit", "Moz", "ms" ], - emptyStyle = document.createElement( "div" ).style; - -// Return a css property mapped to a potentially vendor prefixed property -function vendorPropName( name ) { - - // Shortcut for names that are not vendor prefixed - if ( name in emptyStyle ) { - return name; - } - - // Check for vendor prefixed names - var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in emptyStyle ) { - return name; - } - } -} - -// Return a property mapped along what jQuery.cssProps suggests or to -// a vendor prefixed property. -function finalPropName( name ) { - var ret = jQuery.cssProps[ name ]; - if ( !ret ) { - ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; - } - return ret; -} - -function setPositiveNumber( elem, value, subtract ) { - - // Any relative (+/-) values have already been - // normalized at this point - var matches = rcssNum.exec( value ); - return matches ? - - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : - value; -} - -function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { - var i, - val = 0; - - // If we already have the right measurement, avoid augmentation - if ( extra === ( isBorderBox ? "border" : "content" ) ) { - i = 4; - - // Otherwise initialize for horizontal or vertical properties - } else { - i = name === "width" ? 1 : 0; - } - - for ( ; i < 4; i += 2 ) { - - // Both box models exclude margin, so add it if we want it - if ( extra === "margin" ) { - val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); - } - - if ( isBorderBox ) { - - // border-box includes padding, so remove it if we want content - if ( extra === "content" ) { - val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // At this point, extra isn't border nor margin, so remove border - if ( extra !== "margin" ) { - val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } else { - - // At this point, extra isn't content, so add padding - val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // At this point, extra isn't content nor padding, so add border - if ( extra !== "padding" ) { - val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - return val; -} - -function getWidthOrHeight( elem, name, extra ) { - - // Start with computed style - var valueIsBorderBox, - styles = getStyles( elem ), - val = curCSS( elem, name, styles ), - isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test( val ) ) { - return val; - } - - // Check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = isBorderBox && - ( support.boxSizingReliable() || val === elem.style[ name ] ); - - // Fall back to offsetWidth/Height when value is "auto" - // This happens for inline elements with no explicit setting (gh-3571) - if ( val === "auto" ) { - val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ]; - } - - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; - - // Use the active box-sizing model to add/subtract irrelevant styles - return ( val + - augmentWidthOrHeight( - elem, - name, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles - ) - ) + "px"; -} - -jQuery.extend( { - - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "animationIterationCount": true, - "columnCount": true, - "fillOpacity": true, - "flexGrow": true, - "flexShrink": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: { - "float": "cssFloat" - }, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = jQuery.camelCase( name ), - isCustomProp = rcustomProp.test( name ), - style = elem.style; - - // Make sure that we're working with the right name. We don't - // want to query the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Gets hook for the prefixed version, then unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // Convert "+=" or "-=" to relative numbers (#7345) - if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { - value = adjustCSS( elem, name, ret ); - - // Fixes bug #9237 - type = "number"; - } - - // Make sure that null and NaN values aren't set (#7116) - if ( value == null || value !== value ) { - return; - } - - // If a number was passed in, add the unit (except for certain CSS properties) - if ( type === "number" ) { - value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); - } - - // background-* props affect original clone's values - if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !( "set" in hooks ) || - ( value = hooks.set( elem, value, extra ) ) !== undefined ) { - - if ( isCustomProp ) { - style.setProperty( name, value ); - } else { - style[ name ] = value; - } - } - - } else { - - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && - ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { - - return ret; - } - - // Otherwise just get the value from the style object - return style[ name ]; - } - }, - - css: function( elem, name, extra, styles ) { - var val, num, hooks, - origName = jQuery.camelCase( name ), - isCustomProp = rcustomProp.test( name ); - - // Make sure that we're working with the right name. We don't - // want to modify the value if it is a CSS custom property - // since they are user-defined. - if ( !isCustomProp ) { - name = finalPropName( origName ); - } - - // Try prefixed name followed by the unprefixed name - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - // Convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Make numeric if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || isFinite( num ) ? num || 0 : val; - } - - return val; - } -} ); - -jQuery.each( [ "height", "width" ], function( i, name ) { - jQuery.cssHooks[ name ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit - return rdisplayswap.test( jQuery.css( elem, "display" ) ) && - - // Support: Safari 8+ - // Table columns in Safari have non-zero offsetWidth & zero - // getBoundingClientRect().width unless display is changed. - // Support: IE <=11 only - // Running getBoundingClientRect on a disconnected node - // in IE throws an error. - ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? - swap( elem, cssShow, function() { - return getWidthOrHeight( elem, name, extra ); - } ) : - getWidthOrHeight( elem, name, extra ); - } - }, - - set: function( elem, value, extra ) { - var matches, - styles = extra && getStyles( elem ), - subtract = extra && augmentWidthOrHeight( - elem, - name, - extra, - jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - styles - ); - - // Convert to pixels if value adjustment is needed - if ( subtract && ( matches = rcssNum.exec( value ) ) && - ( matches[ 3 ] || "px" ) !== "px" ) { - - elem.style[ name ] = value; - value = jQuery.css( elem, name ); - } - - return setPositiveNumber( elem, value, subtract ); - } - }; -} ); - -jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, - function( elem, computed ) { - if ( computed ) { - return ( parseFloat( curCSS( elem, "marginLeft" ) ) || - elem.getBoundingClientRect().left - - swap( elem, { marginLeft: 0 }, function() { - return elem.getBoundingClientRect().left; - } ) - ) + "px"; - } - } -); - -// These hooks are used by animate to expand properties -jQuery.each( { - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // Assumes a single number if not a string - parts = typeof value === "string" ? value.split( " " ) : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( !rmargin.test( prefix ) ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -} ); - -jQuery.fn.extend( { - css: function( name, value ) { - return access( this, function( elem, name, value ) { - var styles, len, - map = {}, - i = 0; - - if ( Array.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - } -} ); - - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || jQuery.easing._default; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - // Use a property on the element directly when it is not a DOM element, - // or when there is no matching style property that exists. - if ( tween.elem.nodeType !== 1 || - tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { - return tween.elem[ tween.prop ]; - } - - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. - result = jQuery.css( tween.elem, tween.prop, "" ); - - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.nodeType === 1 && - ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || - jQuery.cssHooks[ tween.prop ] ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 only -// Panic based approach to setting things on disconnected nodes -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p * Math.PI ) / 2; - }, - _default: "swing" -}; - -jQuery.fx = Tween.prototype.init; - -// Back compat <1.8 extension point -jQuery.fx.step = {}; - - - - -var - fxNow, inProgress, - rfxtypes = /^(?:toggle|show|hide)$/, - rrun = /queueHooks$/; - -function schedule() { - if ( inProgress ) { - if ( document.hidden === false && window.requestAnimationFrame ) { - window.requestAnimationFrame( schedule ); - } else { - window.setTimeout( schedule, jQuery.fx.interval ); - } - - jQuery.fx.tick(); - } -} - -// Animations created synchronously will run synchronously -function createFxNow() { - window.setTimeout( function() { - fxNow = undefined; - } ); - return ( fxNow = jQuery.now() ); -} - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - i = 0, - attrs = { height: type }; - - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right - includeWidth = includeWidth ? 1 : 0; - for ( ; i < 4; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { - - // We're done with this property - return tween; - } - } -} - -function defaultPrefilter( elem, props, opts ) { - var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, - isBox = "width" in props || "height" in props, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHiddenWithinTree( elem ), - dataShow = dataPriv.get( elem, "fxshow" ); - - // Queue-skipping animations hijack the fx hooks - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always( function() { - - // Ensure the complete handler is called before this completes - anim.always( function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - } ); - } ); - } - - // Detect show/hide animations - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.test( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - - // Pretend to be hidden if this is a "show" and - // there is still data from a stopped show/hide - if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { - hidden = true; - - // Ignore all other no-op show/hide data - } else { - continue; - } - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - // Bail out if this is a no-op like .hide().hide() - propTween = !jQuery.isEmptyObject( props ); - if ( !propTween && jQuery.isEmptyObject( orig ) ) { - return; - } - - // Restrict "overflow" and "display" styles during box animations - if ( isBox && elem.nodeType === 1 ) { - - // Support: IE <=9 - 11, Edge 12 - 13 - // Record all 3 overflow attributes because IE does not infer the shorthand - // from identically-valued overflowX and overflowY - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Identify a display type, preferring old show/hide data over the CSS cascade - restoreDisplay = dataShow && dataShow.display; - if ( restoreDisplay == null ) { - restoreDisplay = dataPriv.get( elem, "display" ); - } - display = jQuery.css( elem, "display" ); - if ( display === "none" ) { - if ( restoreDisplay ) { - display = restoreDisplay; - } else { - - // Get nonempty value(s) by temporarily forcing visibility - showHide( [ elem ], true ); - restoreDisplay = elem.style.display || restoreDisplay; - display = jQuery.css( elem, "display" ); - showHide( [ elem ] ); - } - } - - // Animate inline elements as inline-block - if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { - if ( jQuery.css( elem, "float" ) === "none" ) { - - // Restore the original display value at the end of pure show/hide animations - if ( !propTween ) { - anim.done( function() { - style.display = restoreDisplay; - } ); - if ( restoreDisplay == null ) { - display = style.display; - restoreDisplay = display === "none" ? "" : display; - } - } - style.display = "inline-block"; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - anim.always( function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - } ); - } - - // Implement show/hide animations - propTween = false; - for ( prop in orig ) { - - // General show/hide setup for this element animation - if ( !propTween ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); - } - - // Store hidden/visible for toggle so `.stop().toggle()` "reverses" - if ( toggle ) { - dataShow.hidden = !hidden; - } - - // Show elements before animating them - if ( hidden ) { - showHide( [ elem ], true ); - } - - /* eslint-disable no-loop-func */ - - anim.done( function() { - - /* eslint-enable no-loop-func */ - - // The final step of a "hide" animation is actually hiding the element - if ( !hidden ) { - showHide( [ elem ] ); - } - dataPriv.remove( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - } ); - } - - // Per-property setup - propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = propTween.start; - if ( hidden ) { - propTween.end = propTween.start; - propTween.start = 0; - } - } - } -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = jQuery.camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( Array.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = Animation.prefilters.length, - deferred = jQuery.Deferred().always( function() { - - // Don't match elem in the :animated selector - delete tick.elem; - } ), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - - // Support: Android 2.3 only - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ] ); - - // If there's more to do, yield - if ( percent < 1 && length ) { - return remaining; - } - - // If this was an empty animation, synthesize a final progress notification - if ( !length ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - } - - // Resolve the animation and report its conclusion - deferred.resolveWith( elem, [ animation ] ); - return false; - }, - animation = deferred.promise( { - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { - specialEasing: {}, - easing: jQuery.easing._default - }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - - // If we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // Resolve when we played the last frame; otherwise, reject - if ( gotoEnd ) { - deferred.notifyWith( elem, [ animation, 1, 0 ] ); - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - } ), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length; index++ ) { - result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - if ( jQuery.isFunction( result.stop ) ) { - jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = - jQuery.proxy( result.stop, result ); - } - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( jQuery.isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - // Attach callbacks from options - animation - .progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - } ) - ); - - return animation; -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweeners: { - "*": [ function( prop, value ) { - var tween = this.createTween( prop, value ); - adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); - return tween; - } ] - }, - - tweener: function( props, callback ) { - if ( jQuery.isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.match( rnothtmlwhite ); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length; index++ ) { - prop = props[ index ]; - Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; - Animation.tweeners[ prop ].unshift( callback ); - } - }, - - prefilters: [ defaultPrefilter ], - - prefilter: function( callback, prepend ) { - if ( prepend ) { - Animation.prefilters.unshift( callback ); - } else { - Animation.prefilters.push( callback ); - } - } -} ); - -jQuery.speed = function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - jQuery.isFunction( speed ) && speed, - duration: speed, - easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing - }; - - // Go to the end state if fx are off - if ( jQuery.fx.off ) { - opt.duration = 0; - - } else { - if ( typeof opt.duration !== "number" ) { - if ( opt.duration in jQuery.fx.speeds ) { - opt.duration = jQuery.fx.speeds[ opt.duration ]; - - } else { - opt.duration = jQuery.fx.speeds._default; - } - } - } - - // Normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( jQuery.isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.fn.extend( { - fadeTo: function( speed, to, easing, callback ) { - - // Show any hidden elements after setting opacity to 0 - return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() - - // Animate to the value specified - .end().animate( { opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || dataPriv.get( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue && type !== false ) { - this.queue( type || "fx", [] ); - } - - return this.each( function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = dataPriv.get( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && - ( type == null || timers[ index ].queue === type ) ) { - - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - } ); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each( function() { - var index, - data = dataPriv.get( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // Enable finishing flag on private data - data.finish = true; - - // Empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // Look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // Look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // Turn off finishing flag - delete data.finish; - } ); - } -} ); - -jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -} ); - -// Generate shortcuts for custom animations -jQuery.each( { - slideDown: genFx( "show" ), - slideUp: genFx( "hide" ), - slideToggle: genFx( "toggle" ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } -}, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); - }; -} ); - -jQuery.timers = []; -jQuery.fx.tick = function() { - var timer, - i = 0, - timers = jQuery.timers; - - fxNow = jQuery.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - - // Run the timer and safely remove it when done (allowing for external removal) - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - jQuery.timers.push( timer ); - jQuery.fx.start(); -}; - -jQuery.fx.interval = 13; -jQuery.fx.start = function() { - if ( inProgress ) { - return; - } - - inProgress = true; - schedule(); -}; - -jQuery.fx.stop = function() { - inProgress = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - - // Default speed - _default: 400 -}; - - -// Based off of the plugin by Clint Helfers, with permission. -// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ -jQuery.fn.delay = function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = window.setTimeout( next, time ); - hooks.stop = function() { - window.clearTimeout( timeout ); - }; - } ); -}; - - -( function() { - var input = document.createElement( "input" ), - select = document.createElement( "select" ), - opt = select.appendChild( document.createElement( "option" ) ); - - input.type = "checkbox"; - - // Support: Android <=4.3 only - // Default value for a checkbox should be "on" - support.checkOn = input.value !== ""; - - // Support: IE <=11 only - // Must access selectedIndex to make default options select - support.optSelected = opt.selected; - - // Support: IE <=11 only - // An input loses its value after becoming a radio - input = document.createElement( "input" ); - input.value = "t"; - input.type = "radio"; - support.radioValue = input.value === "t"; -} )(); - - -var boolHook, - attrHandle = jQuery.expr.attrHandle; - -jQuery.fn.extend( { - attr: function( name, value ) { - return access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each( function() { - jQuery.removeAttr( this, name ); - } ); - } -} ); - -jQuery.extend( { - attr: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set attributes on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { - return jQuery.prop( elem, name, value ); - } - - // Attribute hooks are determined by the lowercase version - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - hooks = jQuery.attrHooks[ name.toLowerCase() ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); - } - - if ( value !== undefined ) { - if ( value === null ) { - jQuery.removeAttr( elem, name ); - return; - } - - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - elem.setAttribute( name, value + "" ); - return value; - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? undefined : ret; - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !support.radioValue && value === "radio" && - nodeName( elem, "input" ) ) { - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - removeAttr: function( elem, value ) { - var name, - i = 0, - - // Attribute names can contain non-HTML whitespace characters - // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 - attrNames = value && value.match( rnothtmlwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( ( name = attrNames[ i++ ] ) ) { - elem.removeAttribute( name ); - } - } - } -} ); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else { - elem.setAttribute( name, name ); - } - return name; - } -}; - -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { - var getter = attrHandle[ name ] || jQuery.find.attr; - - attrHandle[ name ] = function( elem, name, isXML ) { - var ret, handle, - lowercaseName = name.toLowerCase(); - - if ( !isXML ) { - - // Avoid an infinite loop by temporarily removing this function from the getter - handle = attrHandle[ lowercaseName ]; - attrHandle[ lowercaseName ] = ret; - ret = getter( elem, name, isXML ) != null ? - lowercaseName : - null; - attrHandle[ lowercaseName ] = handle; - } - return ret; - }; -} ); - - - - -var rfocusable = /^(?:input|select|textarea|button)$/i, - rclickable = /^(?:a|area)$/i; - -jQuery.fn.extend( { - prop: function( name, value ) { - return access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - removeProp: function( name ) { - return this.each( function() { - delete this[ jQuery.propFix[ name ] || name ]; - } ); - } -} ); - -jQuery.extend( { - prop: function( elem, name, value ) { - var ret, hooks, - nType = elem.nodeType; - - // Don't get/set properties on text, comment and attribute nodes - if ( nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - if ( hooks && "set" in hooks && - ( ret = hooks.set( elem, value, name ) ) !== undefined ) { - return ret; - } - - return ( elem[ name ] = value ); - } - - if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { - return ret; - } - - return elem[ name ]; - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - - // Support: IE <=9 - 11 only - // elem.tabIndex doesn't always return the - // correct value when it hasn't been explicitly set - // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - if ( tabindex ) { - return parseInt( tabindex, 10 ); - } - - if ( - rfocusable.test( elem.nodeName ) || - rclickable.test( elem.nodeName ) && - elem.href - ) { - return 0; - } - - return -1; - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - } -} ); - -// Support: IE <=11 only -// Accessing the selectedIndex property -// forces the browser to respect setting selected -// on the option -// The getter ensures a default option is selected -// when in an optgroup -// eslint rule "no-unused-expressions" is disabled for this code -// since it considers such accessions noop -if ( !support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent && parent.parentNode ) { - parent.parentNode.selectedIndex; - } - return null; - }, - set: function( elem ) { - - /* eslint no-unused-expressions: "off" */ - - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; - - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - } - }; -} - -jQuery.each( [ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -} ); - - - - - // Strip and collapse whitespace according to HTML spec - // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace - function stripAndCollapse( value ) { - var tokens = value.match( rnothtmlwhite ) || []; - return tokens.join( " " ); - } - - -function getClass( elem ) { - return elem.getAttribute && elem.getAttribute( "class" ) || ""; -} - -jQuery.fn.extend( { - addClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( jQuery.isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( typeof value === "string" && value ) { - classes = value.match( rnothtmlwhite ) || []; - - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, curValue, clazz, j, finalValue, - i = 0; - - if ( jQuery.isFunction( value ) ) { - return this.each( function( j ) { - jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); - } ); - } - - if ( !arguments.length ) { - return this.attr( "class", "" ); - } - - if ( typeof value === "string" && value ) { - classes = value.match( rnothtmlwhite ) || []; - - while ( ( elem = this[ i++ ] ) ) { - curValue = getClass( elem ); - - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); - - if ( cur ) { - j = 0; - while ( ( clazz = classes[ j++ ] ) ) { - - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) > -1 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - - // Only assign if different to avoid unneeded rendering. - finalValue = stripAndCollapse( cur ); - if ( curValue !== finalValue ) { - elem.setAttribute( "class", finalValue ); - } - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value; - - if ( typeof stateVal === "boolean" && type === "string" ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( jQuery.isFunction( value ) ) { - return this.each( function( i ) { - jQuery( this ).toggleClass( - value.call( this, i, getClass( this ), stateVal ), - stateVal - ); - } ); - } - - return this.each( function() { - var className, i, self, classNames; - - if ( type === "string" ) { - - // Toggle individual class names - i = 0; - self = jQuery( this ); - classNames = value.match( rnothtmlwhite ) || []; - - while ( ( className = classNames[ i++ ] ) ) { - - // Check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( value === undefined || type === "boolean" ) { - className = getClass( this ); - if ( className ) { - - // Store className if set - dataPriv.set( this, "__className__", className ); - } - - // If the element has a class name or if we're passed `false`, - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - if ( this.setAttribute ) { - this.setAttribute( "class", - className || value === false ? - "" : - dataPriv.get( this, "__className__" ) || "" - ); - } - } - } ); - }, - - hasClass: function( selector ) { - var className, elem, - i = 0; - - className = " " + selector + " "; - while ( ( elem = this[ i++ ] ) ) { - if ( elem.nodeType === 1 && - ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { - return true; - } - } - - return false; - } -} ); - - - - -var rreturn = /\r/g; - -jQuery.fn.extend( { - val: function( value ) { - var hooks, ret, isFunction, - elem = this[ 0 ]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || - jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && - "get" in hooks && - ( ret = hooks.get( elem, "value" ) ) !== undefined - ) { - return ret; - } - - ret = elem.value; - - // Handle most common string cases - if ( typeof ret === "string" ) { - return ret.replace( rreturn, "" ); - } - - // Handle cases where value is null/undef or number - return ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each( function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, jQuery( this ).val() ); - } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - - } else if ( typeof val === "number" ) { - val += ""; - - } else if ( Array.isArray( val ) ) { - val = jQuery.map( val, function( value ) { - return value == null ? "" : value + ""; - } ); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - } ); - } -} ); - -jQuery.extend( { - valHooks: { - option: { - get: function( elem ) { - - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - - // Support: IE <=10 - 11 only - // option.text throws exceptions (#14686, #14858) - // Strip and collapse whitespace - // https://html.spec.whatwg.org/#strip-and-collapse-whitespace - stripAndCollapse( jQuery.text( elem ) ); - } - }, - select: { - get: function( elem ) { - var value, option, i, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one", - values = one ? null : [], - max = one ? index + 1 : options.length; - - if ( index < 0 ) { - i = max; - - } else { - i = one ? index : 0; - } - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // Support: IE <=9 only - // IE8-9 doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - - // Don't return options that are disabled or in a disabled optgroup - !option.disabled && - ( !option.parentNode.disabled || - !nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - - /* eslint-disable no-cond-assign */ - - if ( option.selected = - jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 - ) { - optionSet = true; - } - - /* eslint-enable no-cond-assign */ - } - - // Force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - } -} ); - -// Radios and checkboxes getter/setter -jQuery.each( [ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( Array.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); - } - } - }; - if ( !support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - return elem.getAttribute( "value" ) === null ? "on" : elem.value; - }; - } -} ); - - - - -// Return jQuery for attributes-only inclusion - - -var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; - -jQuery.extend( jQuery.event, { - - trigger: function( event, data, elem, onlyHandlers ) { - - var i, cur, tmp, bubbleType, ontype, handle, special, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf( "." ) > -1 ) { - - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split( "." ); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf( ":" ) < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join( "." ); - event.rnamespace = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === ( elem.ownerDocument || document ) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && - dataPriv.get( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( ( !special._default || - special._default.apply( eventPath.pop(), data ) === false ) && - acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name as the event. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - elem[ type ](); - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - // Piggyback on a donor event to simulate a different one - // Used only for `focus(in | out)` events - simulate: function( type, elem, event ) { - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true - } - ); - - jQuery.event.trigger( e, null, elem ); - } - -} ); - -jQuery.fn.extend( { - - trigger: function( type, data ) { - return this.each( function() { - jQuery.event.trigger( type, data, this ); - } ); - }, - triggerHandler: function( type, data ) { - var elem = this[ 0 ]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -} ); - - -jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup contextmenu" ).split( " " ), - function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; -} ); - -jQuery.fn.extend( { - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -} ); - - - - -support.focusin = "onfocusin" in window; - - -// Support: Firefox <=44 -// Firefox doesn't have focus(in | out) events -// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 -// -// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 -// focus(in | out) events fire after focus & blur events, -// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order -// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 -if ( !support.focusin ) { - jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = dataPriv.access( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = dataPriv.access( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - dataPriv.remove( doc, fix ); - - } else { - dataPriv.access( doc, fix, attaches ); - } - } - }; - } ); -} -var location = window.location; - -var nonce = jQuery.now(); - -var rquery = ( /\?/ ); - - - -// Cross-browser xml parsing -jQuery.parseXML = function( data ) { - var xml; - if ( !data || typeof data !== "string" ) { - return null; - } - - // Support: IE 9 - 11 only - // IE throws on parseFromString with invalid input. - try { - xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); - } catch ( e ) { - xml = undefined; - } - - if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; -}; - - -var - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - if ( Array.isArray( obj ) ) { - - // Serialize array item. - jQuery.each( obj, function( i, v ) { - if ( traditional || rbracket.test( prefix ) ) { - - // Treat each array item as a scalar. - add( prefix, v ); - - } else { - - // Item is non-scalar (array or object), encode its numeric index. - buildParams( - prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", - v, - traditional, - add - ); - } - } ); - - } else if ( !traditional && jQuery.type( obj ) === "object" ) { - - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - - // Serialize scalar item. - add( prefix, obj ); - } -} - -// Serialize an array of form elements or a set of -// key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, valueOrFunction ) { - - // If value is a function, invoke it and use its return value - var value = jQuery.isFunction( valueOrFunction ) ? - valueOrFunction() : - valueOrFunction; - - s[ s.length ] = encodeURIComponent( key ) + "=" + - encodeURIComponent( value == null ? "" : value ); - }; - - // If an array was passed in, assume that it is an array of form elements. - if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { - - // Serialize the form elements - jQuery.each( a, function() { - add( this.name, this.value ); - } ); - - } else { - - // If traditional, encode the "old" way (the way 1.3.2 or older - // did it), otherwise encode params recursively. - for ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ); -}; - -jQuery.fn.extend( { - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map( function() { - - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - } ) - .filter( function() { - var type = this.type; - - // Use .is( ":disabled" ) so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !rcheckableType.test( type ) ); - } ) - .map( function( i, elem ) { - var val = jQuery( this ).val(); - - if ( val == null ) { - return null; - } - - if ( Array.isArray( val ) ) { - return jQuery.map( val, function( val ) { - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ); - } - - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - } ).get(); - } -} ); - - -var - r20 = /%20/g, - rhash = /#.*$/, - rantiCache = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, - - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), - - // Anchor tag for parsing the document origin - originAnchor = document.createElement( "a" ); - originAnchor.href = location.href; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { - - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; - - if ( jQuery.isFunction( func ) ) { - - // For each dataType in the dataTypeExpression - while ( ( dataType = dataTypes[ i++ ] ) ) { - - // Prepend if requested - if ( dataType[ 0 ] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); - - // Otherwise append - } else { - ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if ( typeof dataTypeOrTransport === "string" && - !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - } ); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, - contents = s.contents, - dataTypes = s.dataTypes; - - // Remove auto dataType and get content-type in the process - while ( dataTypes[ 0 ] === "*" ) { - dataTypes.shift(); - if ( ct === undefined ) { - ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); - } - } - - // Check if we're dealing with a known content-type - if ( ct ) { - for ( type in contents ) { - if ( contents[ type ] && contents[ type ].test( ct ) ) { - dataTypes.unshift( type ); - break; - } - } - } - - // Check to see if we have a response for the expected dataType - if ( dataTypes[ 0 ] in responses ) { - finalDataType = dataTypes[ 0 ]; - } else { - - // Try convertible dataTypes - for ( type in responses ) { - if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { - finalDataType = type; - break; - } - if ( !firstDataType ) { - firstDataType = type; - } - } - - // Or just use first one - finalDataType = finalDataType || firstDataType; - } - - // If we found a dataType - // We add the dataType to the list if needed - // and return the corresponding response - if ( finalDataType ) { - if ( finalDataType !== dataTypes[ 0 ] ) { - dataTypes.unshift( finalDataType ); - } - return responses[ finalDataType ]; - } -} - -/* Chain conversions given the request and the original response - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s.throws ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { - state: "parsererror", - error: conv ? e : "No conversion from " + prev + " to " + current - }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} - -jQuery.extend( { - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: location.href, - type: "GET", - isLocal: rlocalProtocol.test( location.protocol ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /\bxml\b/, - html: /\bhtml/, - json: /\bjson\b/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": String, - - // Text to html (true = no transformation) - "text html": true, - - // Evaluate text as a json expression - "text json": JSON.parse, - - // Parse text as xml - "text xml": jQuery.parseXML - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), - ajaxTransport: addToPrefiltersOrTransports( transports ), - - // Main method - ajax: function( url, options ) { - - // If url is an object, simulate pre-1.5 signature - if ( typeof url === "object" ) { - options = url; - url = undefined; - } - - // Force options to be an object - options = options || {}; - - var transport, - - // URL without anti-cache param - cacheURL, - - // Response headers - responseHeadersString, - responseHeaders, - - // timeout handle - timeoutTimer, - - // Url cleanup var - urlAnchor, - - // Request state (becomes false upon send and true upon completion) - completed, - - // To know if global events are to be dispatched - fireGlobals, - - // Loop variable - i, - - // uncached part of the url - uncached, - - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - - // Callbacks context - callbackContext = s.context || s, - - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && - ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks( "once memory" ), - - // Status-dependent callbacks - statusCode = s.statusCode || {}, - - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - - // Default abort message - strAbort = "canceled", - - // Fake xhr - jqXHR = { - readyState: 0, - - // Builds headers hashtable if needed - getResponseHeader: function( key ) { - var match; - if ( completed ) { - if ( !responseHeaders ) { - responseHeaders = {}; - while ( ( match = rheaders.exec( responseHeadersString ) ) ) { - responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; - } - } - match = responseHeaders[ key.toLowerCase() ]; - } - return match == null ? null : match; - }, - - // Raw string - getAllResponseHeaders: function() { - return completed ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - if ( completed == null ) { - name = requestHeadersNames[ name.toLowerCase() ] = - requestHeadersNames[ name.toLowerCase() ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( completed == null ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( completed ) { - - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } else { - - // Lazy-add the new callbacks in a way that preserves old ones - for ( code in map ) { - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ); - - // Add protocol if not provided (prefilters might expect it) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || location.href ) + "" ) - .replace( rprotocol, location.protocol + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; - - // A cross-domain request is in order when the origin doesn't match the current origin. - if ( s.crossDomain == null ) { - urlAnchor = document.createElement( "a" ); - - // Support: IE <=8 - 11, Edge 12 - 13 - // IE throws exception on accessing the href property if url is malformed, - // e.g. http://example.com:80x/ - try { - urlAnchor.href = s.url; - - // Support: IE <=8 - 11 only - // Anchor's host property isn't correctly set when s.url is relative - urlAnchor.href = urlAnchor.href; - s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== - urlAnchor.protocol + "//" + urlAnchor.host; - } catch ( e ) { - - // If there is an error parsing the URL, assume it is crossDomain, - // it can be rejected by the transport if it is invalid - s.crossDomain = true; - } - } - - // Convert data if not already a string - if ( s.data && s.processData && typeof s.data !== "string" ) { - s.data = jQuery.param( s.data, s.traditional ); - } - - // Apply prefilters - inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); - - // If request was aborted inside a prefilter, stop there - if ( completed ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger( "ajaxStart" ); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - // Remove hash to simplify url manipulation - cacheURL = s.url.replace( rhash, "" ); - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // Remember the hash so we can put it back - uncached = s.url.slice( cacheURL.length ); - - // If data is available, append data to url - if ( s.data ) { - cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; - - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add or update anti-cache param if needed - if ( s.cache === false ) { - cacheURL = cacheURL.replace( rantiCache, "$1" ); - uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; - } - - // Put hash and anti-cache on the URL that will be requested (gh-1732) - s.url = cacheURL + uncached; - - // Change '%20' to '+' if this is encoded form body content (gh-2658) - } else if ( s.data && s.processData && - ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { - s.data = s.data.replace( r20, "+" ); - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // Set the correct header, if data is being sent - if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - jqXHR.setRequestHeader( "Content-Type", s.contentType ); - } - - // Set the Accepts header for the server, depending on the dataType - jqXHR.setRequestHeader( - "Accept", - s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? - s.accepts[ s.dataTypes[ 0 ] ] + - ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : - s.accepts[ "*" ] - ); - - // Check for headers option - for ( i in s.headers ) { - jqXHR.setRequestHeader( i, s.headers[ i ] ); - } - - // Allow custom headers/mimetypes and early abort - if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { - - // Abort if not done already and return - return jqXHR.abort(); - } - - // Aborting is no longer a cancellation - strAbort = "abort"; - - // Install callbacks on deferreds - completeDeferred.add( s.complete ); - jqXHR.done( s.success ); - jqXHR.fail( s.error ); - - // Get transport - transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); - - // If no transport, we auto-abort - if ( !transport ) { - done( -1, "No Transport" ); - } else { - jqXHR.readyState = 1; - - // Send global event - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); - } - - // If request was aborted inside ajaxSend, stop there - if ( completed ) { - return jqXHR; - } - - // Timeout - if ( s.async && s.timeout > 0 ) { - timeoutTimer = window.setTimeout( function() { - jqXHR.abort( "timeout" ); - }, s.timeout ); - } - - try { - completed = false; - transport.send( requestHeaders, done ); - } catch ( e ) { - - // Rethrow post-completion exceptions - if ( completed ) { - throw e; - } - - // Propagate others as results - done( -1, e ); - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // Ignore repeat invocations - if ( completed ) { - return; - } - - completed = true; - - // Clear timeout if it exists - if ( timeoutTimer ) { - window.clearTimeout( timeoutTimer ); - } - - // Dereference transport for early garbage collection - // (no matter how long the jqXHR object will be used) - transport = undefined; - - // Cache response headers - responseHeadersString = headers || ""; - - // Set readyState - jqXHR.readyState = status > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader( "Last-Modified" ); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader( "etag" ); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - - // Extract error from statusText and normalize for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || statusText ) + ""; - - // Success/Error - if ( isSuccess ) { - deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); - } else { - deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); - } - - // Status-dependent callbacks - jqXHR.statusCode( statusCode ); - statusCode = undefined; - - if ( fireGlobals ) { - globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger( "ajaxStop" ); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -} ); - -jQuery.each( [ "get", "post" ], function( i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - - // Shift arguments if data argument was omitted - if ( jQuery.isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } - - // The url can be an options object (which then must have .url) - return jQuery.ajax( jQuery.extend( { - url: url, - type: method, - dataType: type, - data: data, - success: callback - }, jQuery.isPlainObject( url ) && url ) ); - }; -} ); - - -jQuery._evalUrl = function( url ) { - return jQuery.ajax( { - url: url, - - // Make this explicit, since user can override this through ajaxSetup (#11264) - type: "GET", - dataType: "script", - cache: true, - async: false, - global: false, - "throws": true - } ); -}; - - -jQuery.fn.extend( { - wrapAll: function( html ) { - var wrap; - - if ( this[ 0 ] ) { - if ( jQuery.isFunction( html ) ) { - html = html.call( this[ 0 ] ); - } - - // The elements to wrap the target around - wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); - - if ( this[ 0 ].parentNode ) { - wrap.insertBefore( this[ 0 ] ); - } - - wrap.map( function() { - var elem = this; - - while ( elem.firstElementChild ) { - elem = elem.firstElementChild; - } - - return elem; - } ).append( this ); - } - - return this; - }, - - wrapInner: function( html ) { - if ( jQuery.isFunction( html ) ) { - return this.each( function( i ) { - jQuery( this ).wrapInner( html.call( this, i ) ); - } ); - } - - return this.each( function() { - var self = jQuery( this ), - contents = self.contents(); - - if ( contents.length ) { - contents.wrapAll( html ); - - } else { - self.append( html ); - } - } ); - }, - - wrap: function( html ) { - var isFunction = jQuery.isFunction( html ); - - return this.each( function( i ) { - jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); - } ); - }, - - unwrap: function( selector ) { - this.parent( selector ).not( "body" ).each( function() { - jQuery( this ).replaceWith( this.childNodes ); - } ); - return this; - } -} ); - - -jQuery.expr.pseudos.hidden = function( elem ) { - return !jQuery.expr.pseudos.visible( elem ); -}; -jQuery.expr.pseudos.visible = function( elem ) { - return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); -}; - - - - -jQuery.ajaxSettings.xhr = function() { - try { - return new window.XMLHttpRequest(); - } catch ( e ) {} -}; - -var xhrSuccessStatus = { - - // File protocol always yields status code 0, assume 200 - 0: 200, - - // Support: IE <=9 only - // #1450: sometimes IE returns 1223 when it should be 204 - 1223: 204 - }, - xhrSupported = jQuery.ajaxSettings.xhr(); - -support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -support.ajax = xhrSupported = !!xhrSupported; - -jQuery.ajaxTransport( function( options ) { - var callback, errorCallback; - - // Cross domain only allowed if supported through XMLHttpRequest - if ( support.cors || xhrSupported && !options.crossDomain ) { - return { - send: function( headers, complete ) { - var i, - xhr = options.xhr(); - - xhr.open( - options.type, - options.url, - options.async, - options.username, - options.password - ); - - // Apply custom fields if provided - if ( options.xhrFields ) { - for ( i in options.xhrFields ) { - xhr[ i ] = options.xhrFields[ i ]; - } - } - - // Override mime type if needed - if ( options.mimeType && xhr.overrideMimeType ) { - xhr.overrideMimeType( options.mimeType ); - } - - // X-Requested-With header - // For cross-domain requests, seeing as conditions for a preflight are - // akin to a jigsaw puzzle, we simply never set it to be sure. - // (it can always be set on a per-request basis or even using ajaxSetup) - // For same-domain requests, won't change header if already provided. - if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { - headers[ "X-Requested-With" ] = "XMLHttpRequest"; - } - - // Set headers - for ( i in headers ) { - xhr.setRequestHeader( i, headers[ i ] ); - } - - // Callback - callback = function( type ) { - return function() { - if ( callback ) { - callback = errorCallback = xhr.onload = - xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; - - if ( type === "abort" ) { - xhr.abort(); - } else if ( type === "error" ) { - - // Support: IE <=9 only - // On a manual native abort, IE9 throws - // errors on any property access that is not readyState - if ( typeof xhr.status !== "number" ) { - complete( 0, "error" ); - } else { - complete( - - // File: protocol always yields status 0; see #8605, #14207 - xhr.status, - xhr.statusText - ); - } - } else { - complete( - xhrSuccessStatus[ xhr.status ] || xhr.status, - xhr.statusText, - - // Support: IE <=9 only - // IE9 has no XHR2 but throws on binary (trac-11426) - // For XHR2 non-text, let the caller handle it (gh-2498) - ( xhr.responseType || "text" ) !== "text" || - typeof xhr.responseText !== "string" ? - { binary: xhr.response } : - { text: xhr.responseText }, - xhr.getAllResponseHeaders() - ); - } - } - }; - }; - - // Listen to events - xhr.onload = callback(); - errorCallback = xhr.onerror = callback( "error" ); - - // Support: IE 9 only - // Use onreadystatechange to replace onabort - // to handle uncaught aborts - if ( xhr.onabort !== undefined ) { - xhr.onabort = errorCallback; - } else { - xhr.onreadystatechange = function() { - - // Check readyState before timeout as it changes - if ( xhr.readyState === 4 ) { - - // Allow onerror to be called first, - // but that will not handle a native abort - // Also, save errorCallback to a variable - // as xhr.onerror cannot be accessed - window.setTimeout( function() { - if ( callback ) { - errorCallback(); - } - } ); - } - }; - } - - // Create the abort callback - callback = callback( "abort" ); - - try { - - // Do send the request (this may raise an exception) - xhr.send( options.hasContent && options.data || null ); - } catch ( e ) { - - // #14683: Only rethrow if this hasn't been notified as an error yet - if ( callback ) { - throw e; - } - } - }, - - abort: function() { - if ( callback ) { - callback(); - } - } - }; - } -} ); - - - - -// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) -jQuery.ajaxPrefilter( function( s ) { - if ( s.crossDomain ) { - s.contents.script = false; - } -} ); - -// Install script dataType -jQuery.ajaxSetup( { - accepts: { - script: "text/javascript, application/javascript, " + - "application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /\b(?:java|ecma)script\b/ - }, - converters: { - "text script": function( text ) { - jQuery.globalEval( text ); - return text; - } - } -} ); - -// Handle cache's special case and crossDomain -jQuery.ajaxPrefilter( "script", function( s ) { - if ( s.cache === undefined ) { - s.cache = false; - } - if ( s.crossDomain ) { - s.type = "GET"; - } -} ); - -// Bind script tag hack transport -jQuery.ajaxTransport( "script", function( s ) { - - // This transport only deals with cross domain requests - if ( s.crossDomain ) { - var script, callback; - return { - send: function( _, complete ) { - script = jQuery( " diff --git a/beginner-tutorial.html b/beginner-tutorial.html index a6e0c4c7..efb36404 100644 --- a/beginner-tutorial.html +++ b/beginner-tutorial.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
- - - - - - - - - - - - - - - - -
- +
- -
-
-
+

Catalyst Beginner Tutorial

@@ -202,7 +326,7 @@ marketplace, Catalyst empowers users to share and curate data and build profitable, data-driven investment strategies.

This tutorial assumes that you have Catalyst correctly installed, see the -Install section if you haven’t set up Catalyst yet.

+Install section if you haven’t set up Catalyst yet.

Every catalyst algorithm consists of at least two functions you have to define:

    @@ -214,7 +338,7 @@ define:

    context is a persistent namespace for you to store variables you need to access from one algorithm iteration to the next.

    After the algorithm has been initialized, catalyst calls the -handle_data() function on each iteration, that’s one per day (daily) or +handle_data() function on each iteration, that’s one per day (daily) or once every minute (minute), depending on the frequency we choose to run our simulation. On every iteration, handle_data() passes the same context variable and an event-frame called data containing the current trading bar @@ -225,16 +349,16 @@ crypto asset in your universe.

    My first algorithm

    Lets take a look at a very simple algorithm from the examples directory: buy_btc_simple.py:

    -
    from catalyst.api import order, record, symbol
    +
    from catalyst.api import order, record, symbol
     
     
     def initialize(context):
    -    context.asset = symbol('btc_usd')
    +    context.asset = symbol('btc_usd')
     
     
     def handle_data(context, data):
         order(context.asset, 1)
    -    record(btc = data.current(context.asset, 'price'))
    +    record(btc = data.current(context.asset, 'price'))
     

    As you can see, we first have to import some functions we would like to @@ -259,28 +383,28 @@ pricing data that Catalyst needs to run your simulation through a process called form from the Enigma servers (which eventually will migrate to the Enigma Data Marketplace), and stores it locally to make it available at runtime.

    In order to ingest data, you need to run a command like the following:

    -
    catalyst ingest-exchange -x bitfinex -i btc_usd
    +
    catalyst ingest-exchange -x bitfinex -i btc_usd
     

    This instructs Catalyst to download pricing data from the Bitfinex exchange for the btc_usd currency pair (this follows from the simple algorithm -presented above where we want to trade btc_usd), and we’re choosing to test +presented above where we want to trade btc_usd), and we’re choosing to test our algorithm using historical pricing data from the Bitfinex exchange. By default, Catalyst assumes that you want data with daily frequency (one candle bar per day). If you want instead minute frequency (one candle bar for every minute), you would need to specify it as follows:

    -
    catalyst ingest-exchange -x bitfinex -i btc_usd -f minute
    +
    catalyst ingest-exchange -x bitfinex -i btc_usd -f minute
     
    -
    Ingesting exchange bundle bitfinex...
    -  [====================================]  Ingesting daily price data on bitfinex:  100%
    +
    Ingesting exchange bundle bitfinex...
    +  [====================================]  Ingesting daily price data on bitfinex:  100%
     

    We believe it is important for you to have a high-level understanding of how data is managed, hence the following overview:

    • Pricing data is split and packaged into bundles: chunks of data organized -as time series that are kept up to date daily on Enigma’s servers. Catalyst +as time series that are kept up to date daily on Enigma’s servers. Catalyst downloads the requested bundles and reconstructs the full dataset in your hard drive.
    • Pricing data is provided in daily and minute resolution. Those are @@ -299,13 +423,13 @@ to the exchange.
    • The ingest-exchange command in catalyst offers additional parameters to further tweak the data ingestion process. You can learn more by running the following from the command line:

      -
      catalyst ingest-exchange --help
      +
      catalyst ingest-exchange --help
       

      Running the algorithm

      -

      You can now test your algorithm using cryptoassets’ historical pricing data, +

      You can now test your algorithm using cryptoassets’ historical pricing data, catalyst provides three interfaces:

      • A command-line interface (CLI),
      • @@ -313,33 +437,33 @@ following from the command line:

        Python scripts,
      • and the Jupyter Notebook magic.
      -

      We’ll start with the CLI, and introduce the run_algorithm() in the last -example of this tutorial. Some of the example algorithms +

      We’ll start with the CLI, and introduce the run_algorithm() in the last +example of this tutorial. Some of the example algorithms provide instructions on how to run them both from the CLI, and using the run_algorithm() function. For the third method, refer to the -corresponding section on Catalyst & Jupyter Notebook after you +corresponding section on Catalyst & Jupyter Notebook after you have assimilated the contents of this tutorial.

      Command line interface

      After you installed Catalyst, you should be able to execute the following from your command line (e.g. cmd.exe or the Anaconda Prompt on Windows, or the Terminal application on MacOS).

      -
      $ catalyst --help
      +
      $ catalyst --help
       

      This is the resulting output, simplified for eductional purposes:

      -
      Usage: catalyst [OPTIONS] COMMAND [ARGS]...
      +
      Usage: catalyst [OPTIONS] COMMAND [ARGS]...
       
      -  Top level catalyst entry point.
      +  Top level catalyst entry point.
       
      -Options:
      -  --version               Show the version and exit.
      -  --help                  Show this message and exit.
      +Options:
      +  --version               Show the version and exit.
      +  --help                  Show this message and exit.
       
      -Commands:
      -  ingest-exchange  Ingest data for the given exchange.
      -  live             Trade live with the given algorithm.
      -  run              Run a backtest for the given algorithm.
      +Commands:
      +  ingest-exchange  Ingest data for the given exchange.
      +  live             Trade live with the given algorithm.
      +  run              Run a backtest for the given algorithm.
       

      There are three main modes you can run on Catalyst. The first being @@ -347,46 +471,46 @@ or the Terminal application on MacOS).

      section. The second is live to use your algorithm to trade live against a given exchange, and the third mode run is to backtest your algorithm before trading live with it.

      -

      Let’s start with backtesting, so run this other command to learn more about +

      Let’s start with backtesting, so run this other command to learn more about the available options:

      -
      $ catalyst run --help
      +
      $ catalyst run --help
       
      -
      Usage: catalyst run [OPTIONS]
      +
      Usage: catalyst run [OPTIONS]
       
      -  Run a backtest for the given algorithm.
      +  Run a backtest for the given algorithm.
       
      -Options:
      -  -f, --algofile FILENAME         The file that contains the algorithm to run.
      -  -t, --algotext TEXT             The algorithm script to run.
      -  -D, --define TEXT               Define a name to be bound in the namespace
      -                                  before executing the algotext. For example
      -                                  '-Dname=value'. The value may be any python
      -                                  expression. These are evaluated in order so
      -                                  they may refer to previously defined names.
      -  --data-frequency [daily|minute]
      -                                  The data frequency of the simulation.
      -                                  [default: daily]
      -  --capital-base FLOAT            The starting capital for the simulation.
      -                                  [default: 10000000.0]
      -  -b, --bundle BUNDLE-NAME        The data bundle to use for the simulation.
      -                                  [default: poloniex]
      -  --bundle-timestamp TIMESTAMP    The date to lookup data on or before.
      -                                  [default: <current-time>]
      -  -s, --start DATE                The start date of the simulation.
      -  -e, --end DATE                  The end date of the simulation.
      -  -o, --output FILENAME           The location to write the perf data. If this
      -                                  is '-' the perf will be written to stdout.
      -                                  [default: -]
      -  --print-algo / --no-print-algo  Print the algorithm to stdout.
      -  -x, --exchange-name [poloniex|bitfinex|bittrex]
      -                                  The name of the targeted exchange
      -                                  (supported: bitfinex, bittrex, poloniex).
      -  -n, --algo-namespace TEXT       A label assigned to the algorithm for data
      -                                  storage purposes.
      -  -c, --base-currency TEXT        The base currency used to calculate
      -                                  statistics (e.g. usd, btc, eth).
      -  --help                          Show this message and exit.
      +Options:
      +  -f, --algofile FILENAME         The file that contains the algorithm to run.
      +  -t, --algotext TEXT             The algorithm script to run.
      +  -D, --define TEXT               Define a name to be bound in the namespace
      +                                  before executing the algotext. For example
      +                                  '-Dname=value'. The value may be any python
      +                                  expression. These are evaluated in order so
      +                                  they may refer to previously defined names.
      +  --data-frequency [daily|minute]
      +                                  The data frequency of the simulation.
      +                                  [default: daily]
      +  --capital-base FLOAT            The starting capital for the simulation.
      +                                  [default: 10000000.0]
      +  -b, --bundle BUNDLE-NAME        The data bundle to use for the simulation.
      +                                  [default: poloniex]
      +  --bundle-timestamp TIMESTAMP    The date to lookup data on or before.
      +                                  [default: <current-time>]
      +  -s, --start DATE                The start date of the simulation.
      +  -e, --end DATE                  The end date of the simulation.
      +  -o, --output FILENAME           The location to write the perf data. If this
      +                                  is '-' the perf will be written to stdout.
      +                                  [default: -]
      +  --print-algo / --no-print-algo  Print the algorithm to stdout.
      +  -x, --exchange-name [poloniex|bitfinex|bittrex]
      +                                  The name of the targeted exchange
      +                                  (supported: bitfinex, bittrex, poloniex).
      +  -n, --algo-namespace TEXT       A label assigned to the algorithm for data
      +                                  storage purposes.
      +  -c, --base-currency TEXT        The base currency used to calculate
      +                                  statistics (e.g. usd, btc, eth).
      +  --help                          Show this message and exit.
       

      As you can see there are a couple of flags that specify where to find your @@ -399,18 +523,18 @@ performance metrics of your algorithm so that you can analyze how it performed. This is done via the --output flag and will cause it to write the performance DataFrame in the pickle Python file format. Note that you can also define a configuration file with these parameters that you can then -conveniently pass to the -c option so that you don’t have to supply the +conveniently pass to the -c option so that you don’t have to supply the command line args all the time.

      Thus, to execute our algorithm from above and save the results to buy_btc_simple_out.pickle we would call catalyst run as follows:

      -
      catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -c usd --capital-base 100000 -o buy_btc_simple_out.pickle
      +
      catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -c usd --capital-base 100000 -o buy_btc_simple_out.pickle
       
      -
      INFO: run_algo: running algo in backtest mode
      -INFO: exchange_algorithm: initialized trading algorithm in backtest mode
      -INFO: Performance: Simulated 639 trading days out of 639.
      -INFO: Performance: first open: 2016-01-01 00:00:00+00:00
      -INFO: Performance: last close: 2017-09-30 23:59:00+00:00
      +
      INFO: run_algo: running algo in backtest mode
      +INFO: exchange_algorithm: initialized trading algorithm in backtest mode
      +INFO: Performance: Simulated 639 trading days out of 639.
      +INFO: Performance: first open: 2016-01-01 00:00:00+00:00
      +INFO: Performance: last close: 2017-09-30 23:59:00+00:00
       

      run first calls the initialize() function, and then @@ -425,19 +549,19 @@ applying the slippage model which models the influence of your order on the stock price, so your algorithm will be charged more than just the asset price. (Note, that you can also change the commission and slippage model that catalyst uses).

      -

      Let’s take a quick look at the performance DataFrame. For this, we write -different Python script–let’s call it print_results.py–and we make use of +

      Let’s take a quick look at the performance DataFrame. For this, we write +different Python script–let’s call it print_results.py–and we make use of the fantastic pandas library to print the first ten rows. Note that catalyst makes heavy usage of pandas, -especially for data analysis and outputting so it’s worth spending some time to +especially for data analysis and outputting so it’s worth spending some time to learn it.

      -
      import pandas as pd
      -perf = pd.read_pickle('buy_btc_simple_out.pickle') # read in perf DataFrame
      +
      import pandas as pd
      +perf = pd.read_pickle('buy_btc_simple_out.pickle') # read in perf DataFrame
       print(perf.head())
       

      Which we execute by running:

      -
      $ python print_results.py
      +
      $ python print_results.py
       
      @@ -608,25 +732,25 @@ as how initialize()context, which we discussed at the very beginning, and perf, which is the pandas dataframe containing the performance data for our algorithm that we reviewed above. Inside the analyze() function is where we can -analyze and visualize the results of our strategy. Here’s the revised simple +analyze and visualize the results of our strategy. Here’s the revised simple algorithm (note the addition of Line 1, and Lines 11-18)

      -
      import matplotlib.pyplot as plt
      +
      import matplotlib.pyplot as plt
       from catalyst.api import order, record, symbol
       
       def initialize(context):
      -    context.asset = symbol('btc_usd')
      +    context.asset = symbol('btc_usd')
       
       def handle_data(context, data):
           order(context.asset, 1)
      -    record(btc = data.current(context.asset, 'price'))
      +    record(btc = data.current(context.asset, 'price'))
       
       def analyze(context, perf):
           ax1 = plt.subplot(211)
           perf.portfolio_value.plot(ax=ax1)
      -    ax1.set_ylabel('portfolio value')
      +    ax1.set_ylabel('portfolio value')
           ax2 = plt.subplot(212, sharex=ax1)
           perf.btc.plot(ax=ax2)
      -    ax2.set_ylabel('bitcoin price')
      +    ax2.set_ylabel('bitcoin price')
           plt.show()
       
      @@ -634,11 +758,11 @@ algorithm (note the addition of Line 1, and Lines 11-18)

      matplotlib, which you might recall we installed alongside enigma-catalyst (with the exception of the Conda install, where it was included by default inside the conda environment we created). If for any -reason you don’t have it installed, you can add it by running:

      -
      (catalyst)$ pip install matplotlib
      +reason you don’t have it installed, you can add it by running:

      +
      (catalyst)$ pip install matplotlib
       
      -

      If everything works well, you’ll see the following chart:

      +

      If everything works well, you’ll see the following chart:

      https://s3.amazonaws.com/enigmaco-docs/github.io/buy_btc_simple_graph.png

      Our algorithm performance as assessed by the portfolio_value closely matches that of the bitcoin price. This is not surprising as our algorithm @@ -648,11 +772,11 @@ only bought bitcoin every chance it got.

      results refer to MacOS + Matplotlib. Alternatively, some users have reported the following error when running an algo in a Linux environment:

      -
      ImportError: No module named _tkinter, please install the python-tk package
      +
      ImportError: No module named _tkinter, please install the python-tk package
       

      Which can easily solved by running (in Ubuntu/Debian-based systems):

      -
      sudo apt install python-tk
      +
      sudo apt install python-tk
       
      @@ -662,10 +786,10 @@ in a Linux environment:

      Access to previous prices using history

      Working example: Dual Moving Average Cross-Over

      -

      The Dual Moving Average (DMA) is a classic momentum strategy. It’s +

      The Dual Moving Average (DMA) is a classic momentum strategy. It’s probably not used by any serious trader anymore but is still very instructive. The basic idea is that we compute two rolling or moving -averages (mavg) – one with a longer window that is supposed to capture +averages (mavg) – one with a longer window that is supposed to capture long-term trends and one shorter window that is supposed to capture short-term trends. Once the short-mavg crosses the long-mavg from below we assume that the stock price has upwards momentum and long the stock. @@ -679,12 +803,12 @@ for daily or '1m' minute-level data when using 1m). This is a function we use in the handle_data() section.

      You will note that the code below is substantially longer than the previous -examples. Don’t get overwhelmed by it as the logic is fairly simple and easy to +examples. Don’t get overwhelmed by it as the logic is fairly simple and easy to follow. Most of the added some complexity has been added to beautify the output, which you can skim through for now. A copy of this algorithm is available in the examples directory: dual_moving_average.py.

      -
      import numpy as np
      +
      import numpy as np
       import pandas as pd
       from logbook import Logger
       import matplotlib.pyplot as plt
      @@ -694,91 +818,91 @@ the examples dire
               get_open_orders)
       from catalyst.exchange.utils.stats_utils import extract_transactions
       
      -NAMESPACE = 'dual_moving_average'
      +NAMESPACE = 'dual_moving_average'
       log = Logger(NAMESPACE)
       
       def initialize(context):
           context.i = 0
      -    context.asset = symbol('ltc_usd')
      +    context.asset = symbol('ltc_usd')
           context.base_price = None
       
       
       def handle_data(context, data):
      -    # define the windows for the moving averages
      +    # define the windows for the moving averages
           short_window = 50
           long_window = 200
       
      -    # Skip as many bars as long_window to properly compute the average
      +    # Skip as many bars as long_window to properly compute the average
           context.i += 1
           if context.i < long_window:
              return
       
      -    # Compute moving averages calling data.history() for each
      -    # moving average with the appropriate parameters. We choose to use
      -    # minute bars for this simulation -> freq="1m"
      -    # Returns a pandas dataframe.
      -    short_mavg = data.history(context.asset, 'price',
      -                        bar_count=short_window, frequency="1m").mean()
      -    long_mavg = data.history(context.asset, 'price',
      -                        bar_count=long_window, frequency="1m").mean()
      +    # Compute moving averages calling data.history() for each
      +    # moving average with the appropriate parameters. We choose to use
      +    # minute bars for this simulation -> freq="1m"
      +    # Returns a pandas dataframe.
      +    short_mavg = data.history(context.asset, 'price',
      +                        bar_count=short_window, frequency="1m").mean()
      +    long_mavg = data.history(context.asset, 'price',
      +                        bar_count=long_window, frequency="1m").mean()
       
      -    # Let's keep the price of our asset in a more handy variable
      -    price = data.current(context.asset, 'price')
      +    # Let's keep the price of our asset in a more handy variable
      +    price = data.current(context.asset, 'price')
       
      -    # If base_price is not set, we use the current value. This is the
      -    # price at the first bar which we reference to calculate price_change.
      +    # If base_price is not set, we use the current value. This is the
      +    # price at the first bar which we reference to calculate price_change.
           if context.base_price is None:
               context.base_price = price
           price_change = (price - context.base_price) / context.base_price
       
      -    # Save values for later inspection
      +    # Save values for later inspection
           record(price=price,
                  cash=context.portfolio.cash,
                  price_change=price_change,
                  short_mavg=short_mavg,
                  long_mavg=long_mavg)
       
      -    # Since we are using limit orders, some orders may not execute immediately
      -    # we wait until all orders are executed before considering more trades.
      +    # Since we are using limit orders, some orders may not execute immediately
      +    # we wait until all orders are executed before considering more trades.
           orders = get_open_orders(context.asset)
           if len(orders) > 0:
               return
       
      -    # Exit if we cannot trade
      +    # Exit if we cannot trade
           if not data.can_trade(context.asset):
               return
       
      -    # We check what's our position on our portfolio and trade accordingly
      +    # We check what's our position on our portfolio and trade accordingly
           pos_amount = context.portfolio.positions[context.asset].amount
       
      -    # Trading logic
      +    # Trading logic
           if short_mavg > long_mavg and pos_amount == 0:
      -       # we buy 100% of our portfolio for this asset
      +       # we buy 100% of our portfolio for this asset
              order_target_percent(context.asset, 1)
           elif short_mavg < long_mavg and pos_amount > 0:
      -       # we sell all our positions for this asset
      +       # we sell all our positions for this asset
              order_target_percent(context.asset, 0)
       
       
       def analyze(context, perf):
       
      -    # Get the base_currency that was passed as a parameter to the simulation
      +    # Get the base_currency that was passed as a parameter to the simulation
           exchange = list(context.exchanges.values())[0]
           base_currency = exchange.base_currency.upper()
       
      -    # First chart: Plot portfolio value using base_currency
      +    # First chart: Plot portfolio value using base_currency
           ax1 = plt.subplot(411)
      -    perf.loc[:, ['portfolio_value']].plot(ax=ax1)
      +    perf.loc[:, ['portfolio_value']].plot(ax=ax1)
           ax1.legend_.remove()
      -    ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency))
      +    ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency))
           start, end = ax1.get_ylim()
           ax1.yaxis.set_ticks(np.arange(start, end, (end-start)/5))
       
      -    # Second chart: Plot asset price, moving averages and buys/sells
      +    # Second chart: Plot asset price, moving averages and buys/sells
           ax2 = plt.subplot(412, sharex=ax1)
      -    perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price')
      +    perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price')
           ax2.legend_.remove()
      -    ax2.set_ylabel('{asset}\n({base})'.format(
      +    ax2.set_ylabel('{asset}\n({base})'.format(
               asset = context.asset.symbol,
               base = base_currency
               ))
      @@ -787,71 +911,71 @@ the examples dire
       
           transaction_df = extract_transactions(perf)
           if not transaction_df.empty:
      -        buy_df = transaction_df[transaction_df['amount'] > 0]
      -        sell_df = transaction_df[transaction_df['amount'] < 0]
      +        buy_df = transaction_df[transaction_df['amount'] > 0]
      +        sell_df = transaction_df[transaction_df['amount'] < 0]
               ax2.scatter(
                   buy_df.index.to_pydatetime(),
      -            perf.loc[buy_df.index, 'price'],
      -            marker='^',
      +            perf.loc[buy_df.index, 'price'],
      +            marker='^',
                   s=100,
      -            c='green',
      -            label=''
      +            c='green',
      +            label=''
               )
               ax2.scatter(
                   sell_df.index.to_pydatetime(),
      -            perf.loc[sell_df.index, 'price'],
      -            marker='v',
      +            perf.loc[sell_df.index, 'price'],
      +            marker='v',
                   s=100,
      -            c='red',
      -            label=''
      +            c='red',
      +            label=''
               )
       
      -    # Third chart: Compare percentage change between our portfolio
      -    # and the price of the asset
      +    # Third chart: Compare percentage change between our portfolio
      +    # and the price of the asset
           ax3 = plt.subplot(413, sharex=ax1)
      -    perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3)
      +    perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3)
           ax3.legend_.remove()
      -    ax3.set_ylabel('Percent Change')
      +    ax3.set_ylabel('Percent Change')
           start, end = ax3.get_ylim()
           ax3.yaxis.set_ticks(np.arange(start, end, (end-start)/5))
       
      -    # Fourth chart: Plot our cash
      +    # Fourth chart: Plot our cash
           ax4 = plt.subplot(414, sharex=ax1)
           perf.cash.plot(ax=ax4)
      -    ax4.set_ylabel('Cash\n({})'.format(base_currency))
      +    ax4.set_ylabel('Cash\n({})'.format(base_currency))
           start, end = ax4.get_ylim()
           ax4.yaxis.set_ticks(np.arange(0, end, end/5))
       
           plt.show()
       
       
      -if __name__ == '__main__':
      +if __name__ == '__main__':
           run_algorithm(
                   capital_base=1000,
      -            data_frequency='minute',
      +            data_frequency='minute',
                   initialize=initialize,
                   handle_data=handle_data,
                   analyze=analyze,
      -            exchange_name='bitfinex',
      +            exchange_name='bitfinex',
                   algo_namespace=NAMESPACE,
      -            base_currency='usd',
      -            start=pd.to_datetime('2017-9-22', utc=True),
      -            end=pd.to_datetime('2017-9-23', utc=True),
      +            base_currency='usd',
      +            start=pd.to_datetime('2017-9-22', utc=True),
      +            end=pd.to_datetime('2017-9-23', utc=True),
               )
       

      In order to run the code above, you have to ingest the needed data first:

      -
      catalyst ingest-exchange -x bitfinex -f minute -i ltc_usd
      +
      catalyst ingest-exchange -x bitfinex -f minute -i ltc_usd
       

      And then run the code above with the following command:

      -
      catalyst run -f dual_moving_average.py -x bitfinex -s 2017-9-22 -e 2017-9-23 --capital-base 1000 --base-currency usd --data-frequency minute -o out.pickle
      +
      catalyst run -f dual_moving_average.py -x bitfinex -s 2017-9-22 -e 2017-9-23 --capital-base 1000 --base-currency usd --data-frequency minute -o out.pickle
       

      Alternatively, we can make use of the run_algorithm() function included at the end of the file, where we can specify all the simulation parameters, and execute this file as a Python script:

      -
      python dual_moving_average.py
      +
      python dual_moving_average.py
       

      Either way, we obtain the following charts:

      @@ -859,7 +983,7 @@ execute this file as a Python script:

      A few comments on the code above:

      At the beginning of our code, we import a number of Python libraries that we -will be using in different parts of our script. It’s good practice to keep all +will be using in different parts of our script. It’s good practice to keep all imports at the beginning of the file, as they are available globally throughout our script. All the libraries imported in this example are already present in your environment since they are prerequisites for the Catalyst @@ -910,16 +1034,16 @@ running algorithms through the command line.

      Install

      In order to use Jupyter Notebook, you first have to install it inside your -environment. It’s available as pip package, so regardless of how you +environment. It’s available as pip package, so regardless of how you installed Catalyst, go inside your catalyst environemnt and run:

      -
      (catalyst)$ pip install jupyter
      +
      (catalyst)$ pip install jupyter
       

      Once you have Jupyter Notebook installed, every time you want to use it run:

      -
      (catalyst)$ jupyter notebook
      +
      (catalyst)$ jupyter notebook
       
      -

      A local server will launch, and will open a new window on your browser. That’s +

      A local server will launch, and will open a new window on your browser. That’s the interface through which you will interact with Jupyter Notebook.

      @@ -927,7 +1051,7 @@ the interface through which you will interact with Jupyter Notebook.

      Before running your algorithms inside the Jupyter Notebook, remember to ingest the data from the command line interface (CLI). In the example below, you would need to run first:

      -
      catalyst ingest-exchange -x bitfinex -i btc_usd
      +
      catalyst ingest-exchange -x bitfinex -i btc_usd
       

      To use Catalyst inside a Jupyter Noebook, you have to write your algorithm in a @@ -938,152 +1062,152 @@ takes the same arguments as the command line interface. Thus to run the algorithm just supply the same parameters as the CLI but without the -f and -o arguments. We just have to execute the following cell after importing catalyst to register the magic.

      -
      # Register the catalyst magic
      -%load_ext catalyst
      +
      # Register the catalyst magic
      +%load_ext catalyst
       
      -
      # Setup matplotlib to display graphs inline in this Notebook
      -%matplotlib inline
      +
      # Setup matplotlib to display graphs inline in this Notebook
      +%matplotlib inline
       

      Note below that we do not have to specify an input file (-f) since the magic will use the contents of the cell and look for your algorithm functions.

      -
      %%catalyst --start 2015-3-2 --end 2017-6-28 --capital-base 100000 -x bitfinex -c usd
      +
      %%catalyst --start 2015-3-2 --end 2017-6-28 --capital-base 100000 -x bitfinex -c usd
       
      -from catalyst.finance.slippage import VolumeShareSlippage
      +from catalyst.finance.slippage import VolumeShareSlippage
       
      -from catalyst.api import (
      -    order_target_value,
      -    symbol,
      -    record,
      -    cancel_order,
      -    get_open_orders,
      -)
      +from catalyst.api import (
      +    order_target_value,
      +    symbol,
      +    record,
      +    cancel_order,
      +    get_open_orders,
      +)
       
      -def initialize(context):
      -    context.ASSET_NAME = 'btc_usd'
      -    context.TARGET_HODL_RATIO = 0.8
      -    context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO
      +def initialize(context):
      +    context.ASSET_NAME = 'btc_usd'
      +    context.TARGET_HODL_RATIO = 0.8
      +    context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO
       
      -    # For all trading pairs in the poloniex bundle, the default denomination
      -    # currently supported by Catalyst is 1/1000th of a full coin. Use this
      -    # constant to scale the price of up to that of a full coin if desired.
      -    context.TICK_SIZE = 1000.0
      +    # For all trading pairs in the poloniex bundle, the default denomination
      +    # currently supported by Catalyst is 1/1000th of a full coin. Use this
      +    # constant to scale the price of up to that of a full coin if desired.
      +    context.TICK_SIZE = 1000.0
       
      -    context.is_buying = True
      -    context.asset = symbol(context.ASSET_NAME)
      +    context.is_buying = True
      +    context.asset = symbol(context.ASSET_NAME)
       
      -    context.i = 0
      +    context.i = 0
       
      -def handle_data(context, data):
      -    context.i += 1
      +def handle_data(context, data):
      +    context.i += 1
       
      -    starting_cash = context.portfolio.starting_cash
      -    target_hodl_value = context.TARGET_HODL_RATIO * starting_cash
      -    reserve_value = context.RESERVE_RATIO * starting_cash
      +    starting_cash = context.portfolio.starting_cash
      +    target_hodl_value = context.TARGET_HODL_RATIO * starting_cash
      +    reserve_value = context.RESERVE_RATIO * starting_cash
       
      -    # Cancel any outstanding orders
      -    orders = get_open_orders(context.asset) or []
      -    for order in orders:
      -        cancel_order(order)
      +    # Cancel any outstanding orders
      +    orders = get_open_orders(context.asset) or []
      +    for order in orders:
      +        cancel_order(order)
       
      -    # Stop buying after passing the reserve threshold
      -    cash = context.portfolio.cash
      -    if cash <= reserve_value:
      -        context.is_buying = False
      +    # Stop buying after passing the reserve threshold
      +    cash = context.portfolio.cash
      +    if cash <= reserve_value:
      +        context.is_buying = False
       
      -    # Retrieve current asset price from pricing data
      -    price = data.current(context.asset, 'price')
      +    # Retrieve current asset price from pricing data
      +    price = data.current(context.asset, 'price')
       
      -    # Check if still buying and could (approximately) afford another purchase
      -    if context.is_buying and cash > price:
      -        # Place order to make position in asset equal to target_hodl_value
      -        order_target_value(
      -            context.asset,
      -            target_hodl_value,
      -            limit_price=price*1.1,
      -        )
      +    # Check if still buying and could (approximately) afford another purchase
      +    if context.is_buying and cash > price:
      +        # Place order to make position in asset equal to target_hodl_value
      +        order_target_value(
      +            context.asset,
      +            target_hodl_value,
      +            limit_price=price*1.1,
      +        )
       
      -    record(
      -        price=price,
      -        volume=data.current(context.asset, 'volume'),
      -        cash=cash,
      -        starting_cash=context.portfolio.starting_cash,
      -        leverage=context.account.leverage,
      -    )
      +    record(
      +        price=price,
      +        volume=data.current(context.asset, 'volume'),
      +        cash=cash,
      +        starting_cash=context.portfolio.starting_cash,
      +        leverage=context.account.leverage,
      +    )
       
      -def analyze(context=None, results=None):
      -    import matplotlib.pyplot as plt
      +def analyze(context=None, results=None):
      +    import matplotlib.pyplot as plt
       
      -    # Plot the portfolio and asset data.
      -    ax1 = plt.subplot(611)
      -    results[['portfolio_value']].plot(ax=ax1)
      -    ax1.set_ylabel('Portfolio Value (USD)')
      +    # Plot the portfolio and asset data.
      +    ax1 = plt.subplot(611)
      +    results[['portfolio_value']].plot(ax=ax1)
      +    ax1.set_ylabel('Portfolio Value (USD)')
       
      -    ax2 = plt.subplot(612, sharex=ax1)
      -    ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME))
      -    (context.TICK_SIZE * results[['price']]).plot(ax=ax2)
      +    ax2 = plt.subplot(612, sharex=ax1)
      +    ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME))
      +    (context.TICK_SIZE * results[['price']]).plot(ax=ax2)
       
      -    trans = results.ix[[t != [] for t in results.transactions]]
      -    buys = trans.ix[
      -        [t[0]['amount'] > 0 for t in trans.transactions]
      -    ]
      -    ax2.plot(
      -        buys.index,
      -        context.TICK_SIZE * results.price[buys.index],
      -        '^',
      -        markersize=10,
      -        color='g',
      -    )
      +    trans = results.ix[[t != [] for t in results.transactions]]
      +    buys = trans.ix[
      +        [t[0]['amount'] > 0 for t in trans.transactions]
      +    ]
      +    ax2.plot(
      +        buys.index,
      +        context.TICK_SIZE * results.price[buys.index],
      +        '^',
      +        markersize=10,
      +        color='g',
      +    )
       
      -    ax3 = plt.subplot(613, sharex=ax1)
      -    results[['leverage', 'alpha', 'beta']].plot(ax=ax3)
      -    ax3.set_ylabel('Leverage ')
      +    ax3 = plt.subplot(613, sharex=ax1)
      +    results[['leverage', 'alpha', 'beta']].plot(ax=ax3)
      +    ax3.set_ylabel('Leverage ')
       
      -    ax4 = plt.subplot(614, sharex=ax1)
      -    results[['starting_cash', 'cash']].plot(ax=ax4)
      -    ax4.set_ylabel('Cash (USD)')
      +    ax4 = plt.subplot(614, sharex=ax1)
      +    results[['starting_cash', 'cash']].plot(ax=ax4)
      +    ax4.set_ylabel('Cash (USD)')
       
      -    results[[
      -        'treasury',
      -        'algorithm',
      -        'benchmark',
      -    ]] = results[[
      -        'treasury_period_return',
      -        'algorithm_period_return',
      -        'benchmark_period_return',
      -    ]]
      +    results[[
      +        'treasury',
      +        'algorithm',
      +        'benchmark',
      +    ]] = results[[
      +        'treasury_period_return',
      +        'algorithm_period_return',
      +        'benchmark_period_return',
      +    ]]
       
      -    ax5 = plt.subplot(615, sharex=ax1)
      -    results[[
      -        'treasury',
      -        'algorithm',
      -        'benchmark',
      -    ]].plot(ax=ax5)
      -    ax5.set_ylabel('Percent Change')
      +    ax5 = plt.subplot(615, sharex=ax1)
      +    results[[
      +        'treasury',
      +        'algorithm',
      +        'benchmark',
      +    ]].plot(ax=ax5)
      +    ax5.set_ylabel('Percent Change')
       
      -    ax6 = plt.subplot(616, sharex=ax1)
      -    results[['volume']].plot(ax=ax6)
      -    ax6.set_ylabel('Volume (mCoins/5min)')
      +    ax6 = plt.subplot(616, sharex=ax1)
      +    results[['volume']].plot(ax=ax6)
      +    ax6.set_ylabel('Volume (mCoins/5min)')
       
      -    plt.legend(loc=3)
      +    plt.legend(loc=3)
       
      -    # Show the plot.
      -    plt.gcf().set_size_inches(18, 8)
      -    plt.show()
      +    # Show the plot.
      +    plt.gcf().set_size_inches(18, 8)
      +    plt.show()
       
      -
      [2017-08-11 07:19:46.411748] INFO: Loader: Loading benchmark data for 'USDT_BTC' from 1989-12-31 00:00:00+00:00 to 2017-08-09 00:00:00+00:00
      -[2017-08-11 07:19:46.418983] INFO: Loader: Loading data for /Users/<snipped>/.catalyst/data/USDT_BTC_benchmark.csv failed with error [Unknown string format].
      -[2017-08-11 07:19:46.419740] INFO: Loader: Cache at /Users/<snipped>/.catalyst/data/USDT_BTC_benchmark.csv does not have data from 1990-01-01 00:00:00+00:00 to 2017-08-09 00:00:00+00:00.
      +
      [2017-08-11 07:19:46.411748] INFO: Loader: Loading benchmark data for 'USDT_BTC' from 1989-12-31 00:00:00+00:00 to 2017-08-09 00:00:00+00:00
      +[2017-08-11 07:19:46.418983] INFO: Loader: Loading data for /Users/<snipped>/.catalyst/data/USDT_BTC_benchmark.csv failed with error [Unknown string format].
      +[2017-08-11 07:19:46.419740] INFO: Loader: Cache at /Users/<snipped>/.catalyst/data/USDT_BTC_benchmark.csv does not have data from 1990-01-01 00:00:00+00:00 to 2017-08-09 00:00:00+00:00.
       
      -[2017-08-11 07:19:46.420770] INFO: Loader: Downloading benchmark data for 'USDT_BTC' from 1989-12-31 00:00:00+00:00 to 2017-08-09 00:00:00+00:00
      -[2017-08-11 07:19:50.060244] WARNING: Loader: Still don't have expected data after redownload!
      -[2017-08-11 07:19:50.097334] WARNING: Loader: Refusing to download new treasury data because a download succeeded at 2017-08-11 06:56:49+00:00.
      -[2017-08-11 07:19:54.618399] INFO: Performance: Simulated 851 trading days out of 851.
      -[2017-08-11 07:19:54.619301] INFO: Performance: first open: 2015-03-01 00:00:00+00:00
      -[2017-08-11 07:19:54.620430] INFO: Performance: last close: 2017-06-28 23:59:00+00:00
      +[2017-08-11 07:19:46.420770] INFO: Loader: Downloading benchmark data for 'USDT_BTC' from 1989-12-31 00:00:00+00:00 to 2017-08-09 00:00:00+00:00
      +[2017-08-11 07:19:50.060244] WARNING: Loader: Still don't have expected data after redownload!
      +[2017-08-11 07:19:50.097334] WARNING: Loader: Refusing to download new treasury data because a download succeeded at 2017-08-11 06:56:49+00:00.
      +[2017-08-11 07:19:54.618399] INFO: Performance: Simulated 851 trading days out of 851.
      +[2017-08-11 07:19:54.619301] INFO: Performance: first open: 2015-03-01 00:00:00+00:00
      +[2017-08-11 07:19:54.620430] INFO: Performance: last close: 2017-06-28 23:59:00+00:00
       
      @@ -2453,10 +2577,10 @@ functions.

      7.135895

      9.470831

      851 rows × 45 columns

      -

      Also, instead of defining an output file we are accessing it via the “_” +

      Also, instead of defining an output file we are accessing it via the “_” variable that will be created in the name space and contain the performance DataFrame.

      -
      _.head()
      +
      _.head()
       

      algo_volatility

      @@ -2597,7 +2721,7 @@ performance DataFrame.

      Next steps

      We hope that this tutorial gave you a little insight into the architecture, API, and features of Catalyst. For next steps, check -out some of the other example algorithms.

      +out some of the other example algorithms.

      Feel free to ask questions on the #catalyst_dev channel of our Discord group and report problems on our GitHub issue tracker.

      @@ -2605,19 +2729,15 @@ problems on our - - @@ -2651,8 +2770,7 @@ problems on our diff --git a/bundles.html b/bundles.html index 78785407..30f2ad7a 100644 --- a/bundles.html +++ b/bundles.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -44,28 +39,21 @@ -
      - - - - - - - - - - - - - - - - -
      - +
      - -
      -
      -
      +

      Data Bundles

      @@ -168,12 +311,12 @@ backtests and store the data for future runs.

      Zipline comes with a few bundles by default as well as the ability to register new bundles. To see which bundles we have have available, we may run the bundles command, for example:

      -
      $ zipline bundles
      -my-custom-bundle 2016-05-05 20:35:19.809398
      -my-custom-bundle 2016-05-05 20:34:53.654082
      -my-custom-bundle 2016-05-05 20:34:48.401767
      +
      $ zipline bundles
      +my-custom-bundle 2016-05-05 20:35:19.809398
      +my-custom-bundle 2016-05-05 20:34:53.654082
      +my-custom-bundle 2016-05-05 20:34:48.401767
       quandl <no ingestions>
      -quantopian-quandl 2016-05-05 20:06:40.894956
      +quantopian-quandl 2016-05-05 20:06:40.894956
       

      The output here shows that there are 3 bundles available:

      @@ -196,11 +339,11 @@ standard location that zipline can find. By default the location where ingested data will be written is $ZIPLINE_ROOT/data/<bundle> where by default ZIPLINE_ROOT=~/.zipline. The ingestion step may take some time as it could involve downloading and processing a lot of data. This can be run with:

      -
      $ zipline ingest [-b <bundle>]
      +
      $ zipline ingest [-b <bundle>]
       

      where <bundle> is the name of the bundle to ingest, defaulting to -quantopian-quandl.

      +quantopian-quandl.

      Old Data

      @@ -211,21 +354,21 @@ copies. Running a backtest with an old ingestion makes it easier to reproduce backtest results later.

      One drawback of saving all of the data by default is that the data directory may grow quite large even if you do not want to use the data. As shown earlier, -we can list all of the ingestions with the bundles command. To solve the problem of leaking old data there is another +we can list all of the ingestions with the bundles command. To solve the problem of leaking old data there is another command: clean, which will clear data bundles based on some time constraints.

      For example:

      -
      # clean everything older than <date>
      -$ zipline clean [-b <bundle>] --before <date>
      +
      # clean everything older than <date>
      +$ zipline clean [-b <bundle>] --before <date>
       
      -# clean everything newer than <date>
      -$ zipline clean [-b <bundle>] --after <date>
      +# clean everything newer than <date>
      +$ zipline clean [-b <bundle>] --after <date>
       
      -# keep everything in the range of [before, after] and delete the rest
      -$ zipline clean [-b <bundle>] --before <date> --after <after>
      +# keep everything in the range of [before, after] and delete the rest
      +$ zipline clean [-b <bundle>] --before <date> --after <after>
       
      -# clean all but the last <int> runs
      -$ zipline clean [-b <bundle>] --keep-last <int>
      +# clean all but the last <int> runs
      +$ zipline clean [-b <bundle>] --keep-last <int>
       
      @@ -234,7 +377,7 @@ $ zipline clean [-b <bundle>]Now that the data has been ingested we can use it to run backtests with the run command. The bundle to use can be specified with the --bundle option like:

      -
      $ zipline run --bundle <bundle> --algofile algo.py ...
      +
      $ zipline run --bundle <bundle> --algofile algo.py ...
       

      We may also specify the date to use to look up the bundle data with the @@ -250,13 +393,13 @@ current day to use the most recent data.

      Default Data Bundles

      Quandl WIKI Bundle

      -

      By default zipline comes with the quandl data bundle which uses quandl’s +

      By default zipline comes with the quandl data bundle which uses quandl’s WIKI dataset. The quandl data bundle includes daily pricing data, splits, cash dividends, and asset metadata. To ingest the quandl data bundle we recommend creating an account on quandl.com to get an API key to be able to make more API requests per day. Once we have an API key we may run:

      -
      $ QUANDL_API_KEY=<api-key> zipline ingest -b quandl
      +
      $ QUANDL_API_KEY=<api-key> zipline ingest -b quandl
       

      though we may still run ingest as an anonymous quandl user (with no API @@ -287,23 +430,23 @@ cache the data for a set of equities from yahoo. The yahoo bundles include daily pricing data along with splits, cash dividends, and inferred asset metadata. To create a bundle from a set of equities, add the following to your ~/.zipline/extensions.py file:

      -
      from zipline.data.bundles import register, yahoo_equities
      +
      from zipline.data.bundles import register, yahoo_equities
       
      -# these are the tickers you would like data for
      +# these are the tickers you would like data for
       equities = {
      -    'AAPL',
      -    'MSFT',
      -    'GOOG',
      +    'AAPL',
      +    'MSFT',
      +    'GOOG',
       }
       register(
      -    'my-yahoo-equities-bundle',  # name this whatever you like
      +    'my-yahoo-equities-bundle',  # name this whatever you like
           yahoo_equities(equities),
       )
       

      This may now be used like:

      -
      $ zipline ingest -b my-yahoo-equities-bundle
      -$ zipline run -f algo.py --bundle my-yahoo-equities-bundle
      +
      $ zipline ingest -b my-yahoo-equities-bundle
      +$ zipline run -f algo.py --bundle my-yahoo-equities-bundle
       

      More than one yahoo equities bundle may be registered as long as they use @@ -316,14 +459,14 @@ different names.

      zipline. To add a new bundle, one must implement an ingest function.

      The ingest function is responsible for loading the data into memory and passing it to a set of writer objects provided by zipline to convert the data to -zipline’s internal format. The ingest function may work by downloading data from +zipline’s internal format. The ingest function may work by downloading data from a remote location like the quandl bundle or yahoo bundles or it may just load files that are already on the machine. The function is provided with writers that will write the data to the correct location transactionally. If an ingestion fails part way through the bundle will not be written in an incomplete state.

      The signature of the ingest function should be:

      -
      ingest(environ,
      +
      ingest(environ,
              asset_db_writer,
              minute_bar_writer,
              daily_bar_writer,
      @@ -357,7 +500,7 @@ docs for write.

      minute_bar_writer

      minute_bar_writer is an instance of BcolzMinuteBarWriter. This writer is used to -convert data to zipline’s internal bcolz format to later be read by a +convert data to zipline’s internal bcolz format to later be read by a BcolzMinuteBarReader. If minute data is provided, users should call write() with an iterable of @@ -379,7 +522,7 @@ as the dates are strictly increasing.

      daily_bar_writer

      daily_bar_writer is an instance of BcolzDailyBarWriter. This writer is -used to convert data into zipline’s internal bcolz format to later be read by a +used to convert data into zipline’s internal bcolz format to later be read by a BcolzDailyBarReader. If daily data is provided, users should call write() with an iterable of @@ -429,7 +572,7 @@ that the bundle should load data for.

      cache is an instance of dataframe_cache. This object is a mapping from strings to dataframes. This object is provided in case an ingestion crashes part way through. The idea is that the ingest function -should check the cache for raw data, if it doesn’t exist in the cache, it should +should check the cache for raw data, if it doesn’t exist in the cache, it should acquire it and then store it in the cache. Then it can parse and write the data. The cache will be cleared only after a successful load, this prevents the ingest function from needing to redownload all the data if there is some bug in @@ -439,7 +582,7 @@ from another local file, then there is no need to use this cache.

      show_progress

      show_progress is a boolean indicating that the user would like to receive -feedback about the ingest function’s progress fetching and writing the +feedback about the ingest function’s progress fetching and writing the data. Some examples for where to show how many files you have downloaded out of the total needed, or how far into some data conversion the ingest function is. One tool that may help with implementing show_progress for a loop is @@ -452,17 +595,13 @@ forwarded to minute_bar_writer. written. output_dir will be some subdirectory of $ZIPLINE_ROOT and will contain the time of the start of the current ingestion. This can be used to directly move resources here if for some reason your ingest function can produce -it’s own outputs without the writers. For example, the quantopian:quandl +it’s own outputs without the writers. For example, the quantopian:quandl bundle uses this to directly untar the bundle into the output_dir.

      -
      -
      - -
      @@ -472,10 +611,9 @@ bundle uses this to directly untar the bundle into the

      © Copyright 2018, Enigma MPC, Inc.. -

      - Built with Sphinx using a theme provided by Read the Docs. + Built with Sphinx using a theme provided by Read the Docs. @@ -496,8 +634,7 @@ bundle uses this to directly untar the bundle into the diff --git a/development-guidelines.html b/development-guidelines.html index 0194487b..1051b30a 100644 --- a/development-guidelines.html +++ b/development-guidelines.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
      - - - - - - - - - - - - - - - - -
      - +
      - -
      -
      -
      +

      Development Guidelines

      @@ -174,30 +309,30 @@

      All contributions, bug reports, bug fixes, documentation improvements, enhancements and ideas are welcome. We track issues on GitHub and also have a discord group where you can ask questions.

      Creating a Development Environment

      -

      First, you’ll need to clone Catalyst by running:

      -
      $ git clone git@github.com:enigmampc/catalyst.git
      +

      First, you’ll need to clone Catalyst by running:

      +
      $ git clone git@github.com:enigmampc/catalyst.git
       

      Then check out to a new branch where you can make your changes:

      -
      $ git checkout -b some-short-descriptive-name
      +
      $ git checkout -b some-short-descriptive-name
       
      -

      If you don’t already have them, you’ll need some C library dependencies. You can follow the install guide to get the appropriate dependencies.

      +

      If you don’t already have them, you’ll need some C library dependencies. You can follow the install guide to get the appropriate dependencies.

      The following section assumes you already have virtualenvwrapper and pip installed on your system. Suggested installation of Python library dependencies used for development:

      -
      $ mkvirtualenv catalyst
      -$ ./etc/ordered_pip.sh ./etc/requirements.txt
      -$ pip install -r ./etc/requirements_dev.txt
      -$ pip install -r ./etc/requirements_blaze.txt
      +
      $ mkvirtualenv catalyst
      +$ ./etc/ordered_pip.sh ./etc/requirements.txt
      +$ pip install -r ./etc/requirements_dev.txt
      +$ pip install -r ./etc/requirements_blaze.txt
       

      Finally, you can build the C extensions by running:

      -
      $ python setup.py build_ext --inplace
      +
      $ python setup.py build_ext --inplace
       

      Development with Docker

      -

      If you want to work with zipline using a Docker container, you’ll need to +

      If you want to work with zipline using a Docker container, you’ll need to build the Dockerfile in the Zipline root directory, and then build Dockerfile-dev. Instructions for building both containers can be found in Dockerfile and Dockerfile-dev, respectively.

      @@ -209,22 +344,22 @@ build the Dockerfile

      Contributing to the Docs

      -

      If you’d like to contribute to the documentation on enigmampc.github.io, you can navigate to docs/source/ where each reStructuredText file is a separate section there. To add a section, create a new file called some-descriptive-name.rst and add some-descriptive-name to index.rst. To edit a section, simply open up one of the existing files, make your changes, and save them.

      +

      If you’d like to contribute to the documentation on enigmampc.github.io, you can navigate to docs/source/ where each reStructuredText file is a separate section there. To add a section, create a new file called some-descriptive-name.rst and add some-descriptive-name to index.rst. To edit a section, simply open up one of the existing files, make your changes, and save them.

      We use Sphinx to generate documentation for Catalyst, which you will need to install by running:

      -
      $ pip install -r ./etc/requirements_docs.txt
      +
      $ pip install -r ./etc/requirements_docs.txt
       

      To build and view the docs locally, run:

      -
      # assuming you're in the Catalyst root directory
      -$ cd docs
      -$ make html
      -$ {BROWSER} build/html/index.html
      +
      # assuming you're in the Catalyst root directory
      +$ cd docs
      +$ make html
      +$ {BROWSER} build/html/index.html
       

      There is a documented issue with sphinx and docutils that causes the error below when trying to build the docs.

      -
      Exception occurred:
      +
      Exception occurred:
         File "(...)/env-c/lib/python2.7/site-packages/docutils/writers/_html_base.py", line 671, in depart_document
           assert not self.context, 'len(context) = %s' % len(self.context)
       AssertionError: len(context) = 3
      @@ -232,14 +367,14 @@ AssertionError: len(context) = 3
       

      If you get this error, you need to downgrade your version of docutils as follows, and build the docs again:

      -
      $ pip install docutils==0.12
      +
      $ pip install docutils==0.12
       

      Commit messages

      Standard prefixes to start a commit message:

      -
      BLD: change related to building Catalyst
      +
      BLD: change related to building Catalyst
       BUG: bug fix
       DEP: deprecate something, or remove a deprecated object
       DEV: development tool or utility
      @@ -256,7 +391,7 @@ PERF: performance enhancements
       

      Some commit style guidelines:

      Commit lines should be no longer than 72 characters. The first line of the commit should include one of the above prefixes. There should be an empty line between the commit subject and the body of the commit. In general, the message should be in the imperative tense. Best practice is to include not only what the change is, but why the change was made.

      Example:

      -
      MAINT: Remove unused calculations of max_leverage, et al.
      +
      MAINT: Remove unused calculations of max_leverage, et al.
       
       In the performance period the max_leverage, max_capital_used,
       cumulative_capital_used were calculated but not used.
      @@ -278,19 +413,15 @@ the algorithm has little cash on hand.
       
      -
      -
      - -
      @@ -324,8 +454,7 @@ the algorithm has little cash on hand. VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/example-algos.html b/example-algos.html index a3bf5def..40f0dc77 100644 --- a/example-algos.html +++ b/example-algos.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
      - - - - - - - - - - - - - - - - -
      - +
      - -
      -
      -
      +

      @@ -180,29 +314,29 @@ using Catalyst.

      Overview

        -
      • Buy BTC Simple: The simplest algorithm that introduces +
      • Buy BTC Simple: The simplest algorithm that introduces the initialize() and handle_data() functions, and is used in the -beginner tutorial to show how to run catalyst +beginner tutorial to show how to run catalyst for the first time.
      • -
      • Buy and Hodl: A very straightforward buy and hold that +
      • Buy and Hodl: A very straightforward buy and hold that makes one single buy at the very beginning. Introduces the notions of cash, management of outstanding orders, and order_target_value to place orders. It also introduces the analyze() function to visualize the performance of our strategy using the external library matplotlib.
      • -
      • Dual Moving Average Crossover: A classic momentum +
      • Dual Moving Average Crossover: A classic momentum strategy used in the second part of the beginner tutorial to introduce the data.history() function. It makes a heavy use of matplotlib library in the analyze() function to chart the performance of the algorithm.
      • -
      • Mean Reversion Algorithm: Another simple momentum +
      • Mean Reversion Algorithm: Another simple momentum strategy that is used in our two-part video tutorial to show how to get started in backtesting and live trading with Catalyst.
      • -
      • Simple Universe: This code provides the ‘universe’ +
      • Simple Universe: This code provides the ‘universe’ of available trading pairs on a given exchange on any given day. You can use this code to dynamically select which currency pairs you want to trade each day of your strategy. This example does not make any trades.
      • -
      • Portfolio Optimization: Use this code to +
      • Portfolio Optimization: Use this code to execute a portfolio optimization model. This strategy will select the portfolio with the maximum Sharpe Ratio. The parameters are set to use 180 days of historical data and rebalance every 30 days. This code was used in @@ -213,7 +347,7 @@ writting the following article:

        Buy BTC Simple Algorithm

        Source code: examples/buy_btc_simple.py

        -
        '''
        +
        '''
           Run this example, by executing the following from your terminal:
             catalyst ingest-exchange -x bitfinex -f daily -i btc_usdt
             catalyst run -f buy_btc_simple.py -x bitfinex --start 2016-1-1 --end 2017-9-30 -o buy_btc_simple_out.pickle
        @@ -235,11 +369,11 @@ writting the following article:
         from catalyst.api import order, record, symbol
         
         def initialize(context):
        -    context.asset = symbol('btc_usd')
        +    context.asset = symbol('btc_usd')
         
         def handle_data(context, data):
             order(context.asset, 1)
        -    record(btc = data.current(context.asset, 'price'))
        +    record(btc = data.current(context.asset, 'price'))
         

        This simple algorithm does not produce any output nor displays any chart.

        @@ -248,40 +382,40 @@ writting the following article:

        Buy and Hodl Algorithm

        Source code: examples/buy_and_hodl.py

        First ingest the historical pricing data needed to run this algorithm:

        -
        catalyst ingest-exchange -x bitfinex -f daily -i btc_usd
        +
        catalyst ingest-exchange -x bitfinex -f daily -i btc_usd
         

        Then, you can run the code below with the following command:

        -
        catalyst run -f buy_and_hodl.py --start 2015-3-1 --end 2017-10-31 --capital-base 100000 -x bitfinex -c btc -o bah.pickle
        +
        catalyst run -f buy_and_hodl.py --start 2015-3-1 --end 2017-10-31 --capital-base 100000 -x bitfinex -c btc -o bah.pickle
         

        or using the same parameters specified in the run_algorithm() function at the end of the file:

        -
        python buy_and_hodl.py
        +
        python buy_and_hodl.py
         

        This command will run the trading algorithm in the specified time range and plot the resulting performance using the matplotlib library. You can choose any date interval with the --start and --end parameters, but bear in mind that 2015-3-1 is the earliest date that Catalyst supports (if you choose an -earlier date, you’ll get an error), and the most recent date you can choose is +earlier date, you’ll get an error), and the most recent date you can choose is one day prior to the current date.

        -
        #!/usr/bin/env python
        -#
        -# Copyright 2017 Enigma MPC, Inc.
        -# Copyright 2015 Quantopian, Inc.
        -#
        -# Licensed under the Apache License, Version 2.0 (the "License");
        -# you may not use this file except in compliance with the License.
        -# You may obtain a copy of the License at
        -#
        -#     http://www.apache.org/licenses/LICENSE-2.0
        -#
        -# Unless required by applicable law or agreed to in writing, software
        -# distributed under the License is distributed on an "AS IS" BASIS,
        -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        -# See the License for the specific language governing permissions and
        -# limitations under the License.
        +
        #!/usr/bin/env python
        +#
        +# Copyright 2017 Enigma MPC, Inc.
        +# Copyright 2015 Quantopian, Inc.
        +#
        +# Licensed under the Apache License, Version 2.0 (the "License");
        +# you may not use this file except in compliance with the License.
        +# You may obtain a copy of the License at
        +#
        +#     http://www.apache.org/licenses/LICENSE-2.0
        +#
        +# Unless required by applicable law or agreed to in writing, software
        +# distributed under the License is distributed on an "AS IS" BASIS,
        +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        +# See the License for the specific language governing permissions and
        +# limitations under the License.
         import pandas as pd
         import matplotlib.pyplot as plt
         
        @@ -291,7 +425,7 @@ one day prior to the current date.

        def initialize(context): - context.ASSET_NAME = 'btc_usd' + context.ASSET_NAME = 'btc_usd' context.TARGET_HODL_RATIO = 0.8 context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO @@ -308,23 +442,23 @@ one day prior to the current date.

        target_hodl_value = context.TARGET_HODL_RATIO * starting_cash reserve_value = context.RESERVE_RATIO * starting_cash - # Cancel any outstanding orders + # Cancel any outstanding orders orders = get_open_orders(context.asset) or [] for order in orders: cancel_order(order) - # Stop buying after passing the reserve threshold + # Stop buying after passing the reserve threshold cash = context.portfolio.cash if cash <= reserve_value: context.is_buying = False - # Retrieve current asset price from pricing data - price = data.current(context.asset, 'price') + # Retrieve current asset price from pricing data + price = data.current(context.asset, 'price') - # Check if still buying and could (approximately) afford another purchase + # Check if still buying and could (approximately) afford another purchase if context.is_buying and cash > price: - print('buying') - # Place order to make position in asset equal to target_hodl_value + print('buying') + # Place order to make position in asset equal to target_hodl_value order_target_value( context.asset, target_hodl_value, @@ -333,7 +467,7 @@ one day prior to the current date.

        record( price=price, - volume=data.current(context.asset, 'volume'), + volume=data.current(context.asset, 'volume'), cash=cash, starting_cash=context.portfolio.starting_cash, leverage=context.account.leverage, @@ -342,77 +476,77 @@ one day prior to the current date.

        def analyze(context=None, results=None): - # Plot the portfolio and asset data. + # Plot the portfolio and asset data. ax1 = plt.subplot(611) - results[['portfolio_value']].plot(ax=ax1) - ax1.set_ylabel('Portfolio Value (USD)') + results[['portfolio_value']].plot(ax=ax1) + ax1.set_ylabel('Portfolio Value (USD)') ax2 = plt.subplot(612, sharex=ax1) - ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME)) - results[['price']].plot(ax=ax2) + ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME)) + results[['price']].plot(ax=ax2) trans = results.ix[[t != [] for t in results.transactions]] buys = trans.ix[ - [t[0]['amount'] > 0 for t in trans.transactions] + [t[0]['amount'] > 0 for t in trans.transactions] ] ax2.scatter( buys.index.to_pydatetime(), results.price[buys.index], - marker='^', + marker='^', s=100, - c='g', - label='' + c='g', + label='' ) ax3 = plt.subplot(613, sharex=ax1) - results[['leverage', 'alpha', 'beta']].plot(ax=ax3) - ax3.set_ylabel('Leverage ') + results[['leverage', 'alpha', 'beta']].plot(ax=ax3) + ax3.set_ylabel('Leverage ') ax4 = plt.subplot(614, sharex=ax1) - results[['starting_cash', 'cash']].plot(ax=ax4) - ax4.set_ylabel('Cash (USD)') + results[['starting_cash', 'cash']].plot(ax=ax4) + ax4.set_ylabel('Cash (USD)') results[[ - 'treasury', - 'algorithm', - 'benchmark', + 'treasury', + 'algorithm', + 'benchmark', ]] = results[[ - 'treasury_period_return', - 'algorithm_period_return', - 'benchmark_period_return', + 'treasury_period_return', + 'algorithm_period_return', + 'benchmark_period_return', ]] ax5 = plt.subplot(615, sharex=ax1) results[[ - 'treasury', - 'algorithm', - 'benchmark', + 'treasury', + 'algorithm', + 'benchmark', ]].plot(ax=ax5) - ax5.set_ylabel('Percent Change') + ax5.set_ylabel('Percent Change') ax6 = plt.subplot(616, sharex=ax1) - results[['volume']].plot(ax=ax6) - ax6.set_ylabel('Volume (mCoins/5min)') + results[['volume']].plot(ax=ax6) + ax6.set_ylabel('Volume (mCoins/5min)') plt.legend(loc=3) - # Show the plot. + # Show the plot. plt.gcf().set_size_inches(18, 8) plt.show() -if __name__ == '__main__': +if __name__ == '__main__': run_algorithm( capital_base=10000, - data_frequency='daily', + data_frequency='daily', initialize=initialize, handle_data=handle_data, analyze=analyze, - exchange_name='bitfinex', - algo_namespace='buy_and_hodl', - base_currency='usd', - start=pd.to_datetime('2015-03-01', utc=True), - end=pd.to_datetime('2017-10-31', utc=True), + exchange_name='bitfinex', + algo_namespace='buy_and_hodl', + base_currency='usd', + start=pd.to_datetime('2015-03-01', utc=True), + end=pd.to_datetime('2017-10-31', utc=True), )
        @@ -423,7 +557,7 @@ one day prior to the current date.

        Source Code: examples/dual_moving_average.py

        This strategy is covered in detail in the last part of this tutorial.

        -
        import numpy as np
        +
        import numpy as np
         import pandas as pd
         from logbook import Logger
         import matplotlib.pyplot as plt
        @@ -433,90 +567,90 @@ one day prior to the current date.

        get_open_orders) from catalyst.exchange.stats_utils import extract_transactions -NAMESPACE = 'dual_moving_average' +NAMESPACE = 'dual_moving_average' log = Logger(NAMESPACE) def initialize(context): context.i = 0 - context.asset = symbol('ltc_usd') + context.asset = symbol('ltc_usd') context.base_price = None def handle_data(context, data): - # define the windows for the moving averages + # define the windows for the moving averages short_window = 50 long_window = 200 - # Skip as many bars as long_window to properly compute the average + # Skip as many bars as long_window to properly compute the average context.i += 1 if context.i < long_window: return - # Compute moving averages calling data.history() for each - # moving average with the appropriate parameters. We choose to use - # minute bars for this simulation -> freq="1m" - # Returns a pandas dataframe. - short_mavg = data.history(context.asset, 'price', - bar_count=short_window, frequency="1m").mean() - long_mavg = data.history(context.asset, 'price', - bar_count=long_window, frequency="1m").mean() + # Compute moving averages calling data.history() for each + # moving average with the appropriate parameters. We choose to use + # minute bars for this simulation -> freq="1m" + # Returns a pandas dataframe. + short_mavg = data.history(context.asset, 'price', + bar_count=short_window, frequency="1m").mean() + long_mavg = data.history(context.asset, 'price', + bar_count=long_window, frequency="1m").mean() - # Let's keep the price of our asset in a more handy variable - price = data.current(context.asset, 'price') + # Let's keep the price of our asset in a more handy variable + price = data.current(context.asset, 'price') - # If base_price is not set, we use the current value. This is the - # price at the first bar which we reference to calculate price_change. + # If base_price is not set, we use the current value. This is the + # price at the first bar which we reference to calculate price_change. if context.base_price is None: context.base_price = price price_change = (price - context.base_price) / context.base_price - # Save values for later inspection + # Save values for later inspection record(price=price, cash=context.portfolio.cash, price_change=price_change, short_mavg=short_mavg, long_mavg=long_mavg) - # Since we are using limit orders, some orders may not execute immediately - # we wait until all orders are executed before considering more trades. + # Since we are using limit orders, some orders may not execute immediately + # we wait until all orders are executed before considering more trades. orders = get_open_orders(context.asset) if len(orders) > 0: return - # Exit if we cannot trade + # Exit if we cannot trade if not data.can_trade(context.asset): return - # We check what's our position on our portfolio and trade accordingly + # We check what's our position on our portfolio and trade accordingly pos_amount = context.portfolio.positions[context.asset].amount - # Trading logic + # Trading logic if short_mavg > long_mavg and pos_amount == 0: - # we buy 100% of our portfolio for this asset + # we buy 100% of our portfolio for this asset order_target_percent(context.asset, 1) elif short_mavg < long_mavg and pos_amount > 0: - # we sell all our positions for this asset + # we sell all our positions for this asset order_target_percent(context.asset, 0) def analyze(context, perf): - # Get the base_currency that was passed as a parameter to the simulation + # Get the base_currency that was passed as a parameter to the simulation base_currency = context.exchanges.values()[0].base_currency.upper() - # First chart: Plot portfolio value using base_currency + # First chart: Plot portfolio value using base_currency ax1 = plt.subplot(411) - perf.loc[:, ['portfolio_value']].plot(ax=ax1) + perf.loc[:, ['portfolio_value']].plot(ax=ax1) ax1.legend_.remove() - ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency)) + ax1.set_ylabel('Portfolio Value\n({})'.format(base_currency)) start, end = ax1.get_ylim() ax1.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - # Second chart: Plot asset price, moving averages and buys/sells + # Second chart: Plot asset price, moving averages and buys/sells ax2 = plt.subplot(412, sharex=ax1) - perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price') + perf.loc[:, ['price','short_mavg','long_mavg']].plot(ax=ax2, label='Price') ax2.legend_.remove() - ax2.set_ylabel('{asset}\n({base})'.format( + ax2.set_ylabel('{asset}\n({base})'.format( asset = context.asset.symbol, base = base_currency )) @@ -525,56 +659,56 @@ one day prior to the current date.

        transaction_df = extract_transactions(perf) if not transaction_df.empty: - buy_df = transaction_df[transaction_df['amount'] > 0] - sell_df = transaction_df[transaction_df['amount'] < 0] + buy_df = transaction_df[transaction_df['amount'] > 0] + sell_df = transaction_df[transaction_df['amount'] < 0] ax2.scatter( buy_df.index.to_pydatetime(), - perf.loc[buy_df.index, 'price'], - marker='^', + perf.loc[buy_df.index, 'price'], + marker='^', s=100, - c='green', - label='' + c='green', + label='' ) ax2.scatter( sell_df.index.to_pydatetime(), - perf.loc[sell_df.index, 'price'], - marker='v', + perf.loc[sell_df.index, 'price'], + marker='v', s=100, - c='red', - label='' + c='red', + label='' ) - # Third chart: Compare percentage change between our portfolio - # and the price of the asset + # Third chart: Compare percentage change between our portfolio + # and the price of the asset ax3 = plt.subplot(413, sharex=ax1) - perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3) + perf.loc[:, ['algorithm_period_return', 'price_change']].plot(ax=ax3) ax3.legend_.remove() - ax3.set_ylabel('Percent Change') + ax3.set_ylabel('Percent Change') start, end = ax3.get_ylim() ax3.yaxis.set_ticks(np.arange(start, end, (end-start)/5)) - # Fourth chart: Plot our cash + # Fourth chart: Plot our cash ax4 = plt.subplot(414, sharex=ax1) perf.cash.plot(ax=ax4) - ax4.set_ylabel('Cash\n({})'.format(base_currency)) + ax4.set_ylabel('Cash\n({})'.format(base_currency)) start, end = ax4.get_ylim() ax4.yaxis.set_ticks(np.arange(0, end, end/5)) plt.show() -if __name__ == '__main__': +if __name__ == '__main__': run_algorithm( capital_base=1000, - data_frequency='minute', + data_frequency='minute', initialize=initialize, handle_data=handle_data, analyze=analyze, - exchange_name='bitfinex', + exchange_name='bitfinex', algo_namespace=NAMESPACE, - base_currency='usd', - start=pd.to_datetime('2017-9-22', utc=True), - end=pd.to_datetime('2017-9-23', utc=True), + base_currency='usd', + start=pd.to_datetime('2017-9-22', utc=True), + end=pd.to_datetime('2017-9-23', utc=True), )
        @@ -584,21 +718,21 @@ one day prior to the current date.

        Mean Reversion Algorithm

        Source code: examples/mean_reversion_simple.py

        This algorithm is based on a simple momentum strategy. When the cryptoasset goes -up quickly, we’re going to buy; when it goes down quickly, we’re going to sell. -Hopefully, we’ll ride the waves.

        +up quickly, we’re going to buy; when it goes down quickly, we’re going to sell. +Hopefully, we’ll ride the waves.

        We are choosing to backtest this trading algorithm with the neo_usd currency pairon the Bitfinex exchange. Thus, first ingest the historical pricing data that we need, with minute resolution:

        -
        catalyst ingest-exchange -x bitfinex -f minute -i neo_usd
        +
        catalyst ingest-exchange -x bitfinex -f minute -i neo_usd
         

        To run this algorithm, we are opting for the Python interpreter, instead of the command line (CLI). All of the parameters for the simulation are specified in lines 218-245, so in order to run the algorithm we just type:

        -
        python mean_reversion_simple.py
        +
        python mean_reversion_simple.py
         
        -
        import os
        +
        import os
         import tempfile
         import time
         
        @@ -610,124 +744,124 @@ lines 218-245, so in order to run the algorithm we just type:

        from catalyst import run_algorithm from catalyst.api import symbol, record, order_target_percent, get_open_orders from catalyst.exchange.stats_utils import extract_transactions -# We give a name to the algorithm which Catalyst will use to persist its state. -# In this example, Catalyst will create the `.catalyst/data/live_algos` -# directory. If we stop and start the algorithm, Catalyst will resume its -# state using the files included in the folder. +# We give a name to the algorithm which Catalyst will use to persist its state. +# In this example, Catalyst will create the `.catalyst/data/live_algos` +# directory. If we stop and start the algorithm, Catalyst will resume its +# state using the files included in the folder. from catalyst.utils.paths import ensure_directory -NAMESPACE = 'mean_reversion_simple' +NAMESPACE = 'mean_reversion_simple' log = Logger(NAMESPACE) -# To run an algorithm in Catalyst, you need two functions: initialize and -# handle_data. +# To run an algorithm in Catalyst, you need two functions: initialize and +# handle_data. def initialize(context): - # This initialize function sets any data or variables that you'll use in - # your algorithm. For instance, you'll want to define the trading pair (or - # trading pairs) you want to backtest. You'll also want to define any - # parameters or values you're going to use. + # This initialize function sets any data or variables that you'll use in + # your algorithm. For instance, you'll want to define the trading pair (or + # trading pairs) you want to backtest. You'll also want to define any + # parameters or values you're going to use. - # In our example, we're looking at Neo in USD. - context.neo_eth = symbol('neo_usd') + # In our example, we're looking at Neo in USD. + context.neo_eth = symbol('neo_usd') context.base_price = None context.current_day = None context.RSI_OVERSOLD = 30 context.RSI_OVERBOUGHT = 80 - context.CANDLE_SIZE = '15T' + context.CANDLE_SIZE = '15T' context.start_time = time.time() def handle_data(context, data): - # This handle_data function is where the real work is done. Our data is - # minute-level tick data, and each minute is called a frame. This function - # runs on each frame of the data. + # This handle_data function is where the real work is done. Our data is + # minute-level tick data, and each minute is called a frame. This function + # runs on each frame of the data. - # We flag the first period of each day. - # Since cryptocurrencies trade 24/7 the `before_trading_starts` handle - # would only execute once. This method works with minute and daily - # frequencies. - today = data.current_dt.floor('1D') + # We flag the first period of each day. + # Since cryptocurrencies trade 24/7 the `before_trading_starts` handle + # would only execute once. This method works with minute and daily + # frequencies. + today = data.current_dt.floor('1D') if today != context.current_day: context.traded_today = False context.current_day = today - # We're computing the volume-weighted-average-price of the security - # defined above, in the context.neo_eth variable. For this example, we're - # using three bars on the 15 min bars. + # We're computing the volume-weighted-average-price of the security + # defined above, in the context.neo_eth variable. For this example, we're + # using three bars on the 15 min bars. - # The frequency attribute determine the bar size. We use this convention - # for the frequency alias: - # http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases + # The frequency attribute determine the bar size. We use this convention + # for the frequency alias: + # http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases prices = data.history( context.neo_eth, - fields='close', + fields='close', bar_count=50, frequency=context.CANDLE_SIZE ) - # Ta-lib calculates various technical indicator based on price and - # volume arrays. + # Ta-lib calculates various technical indicator based on price and + # volume arrays. - # In this example, we are comp + # In this example, we are comp rsi = talib.RSI(prices.values, timeperiod=14) - # We need a variable for the current price of the security to compare to - # the average. Since we are requesting two fields, data.current() - # returns a DataFrame with - current = data.current(context.neo_eth, fields=['close', 'volume']) - price = current['close'] + # We need a variable for the current price of the security to compare to + # the average. Since we are requesting two fields, data.current() + # returns a DataFrame with + current = data.current(context.neo_eth, fields=['close', 'volume']) + price = current['close'] - # If base_price is not set, we use the current value. This is the - # price at the first bar which we reference to calculate price_change. + # If base_price is not set, we use the current value. This is the + # price at the first bar which we reference to calculate price_change. if context.base_price is None: context.base_price = price price_change = (price - context.base_price) / context.base_price cash = context.portfolio.cash - # Now that we've collected all current data for this frame, we use - # the record() method to save it. This data will be available as - # a parameter of the analyze() function for further analysis. + # Now that we've collected all current data for this frame, we use + # the record() method to save it. This data will be available as + # a parameter of the analyze() function for further analysis. record( price=price, - volume=current['volume'], + volume=current['volume'], price_change=price_change, rsi=rsi[-1], cash=cash ) - # We are trying to avoid over-trading by limiting our trades to - # one per day. + # We are trying to avoid over-trading by limiting our trades to + # one per day. if context.traded_today: return - # Since we are using limit orders, some orders may not execute immediately - # we wait until all orders are executed before considering more trades. + # Since we are using limit orders, some orders may not execute immediately + # we wait until all orders are executed before considering more trades. orders = get_open_orders(context.neo_eth) if len(orders) > 0: return - # Exit if we cannot trade + # Exit if we cannot trade if not data.can_trade(context.neo_eth): return - # Another powerful built-in feature of the Catalyst backtester is the - # portfolio object. The portfolio object tracks your positions, cash, - # cost basis of specific holdings, and more. In this line, we calculate - # how long or short our position is at this minute. + # Another powerful built-in feature of the Catalyst backtester is the + # portfolio object. The portfolio object tracks your positions, cash, + # cost basis of specific holdings, and more. In this line, we calculate + # how long or short our position is at this minute. pos_amount = context.portfolio.positions[context.neo_eth].amount if rsi[-1] <= context.RSI_OVERSOLD and pos_amount == 0: log.info( - '{}: buying - price: {}, rsi: {}'.format( + '{}: buying - price: {}, rsi: {}'.format( data.current_dt, price, rsi[-1] ) ) - # Set a style for limit orders, + # Set a style for limit orders, limit_price = price * 1.005 order_target_percent( context.neo_eth, 1, limit_price=limit_price @@ -736,7 +870,7 @@ lines 218-245, so in order to run the algorithm we just type:

        elif rsi[-1] >= context.RSI_OVERBOUGHT and pos_amount > 0: log.info( - '{}: selling - price: {}, rsi: {}'.format( + '{}: selling - price: {}, rsi: {}'.format( data.current_dt, price, rsi[-1] ) ) @@ -749,129 +883,129 @@ lines 218-245, so in order to run the algorithm we just type:

        def analyze(context=None, perf=None): end = time.time() - log.info('elapsed time: {}'.format(end - context.start_time)) + log.info('elapsed time: {}'.format(end - context.start_time)) import matplotlib.pyplot as plt - # The base currency of the algo exchange + # The base currency of the algo exchange base_currency = context.exchanges.values()[0].base_currency.upper() - # Plot the portfolio value over time. + # Plot the portfolio value over time. ax1 = plt.subplot(611) - perf.loc[:, 'portfolio_value'].plot(ax=ax1) - ax1.set_ylabel('Portfolio\nValue\n({})'.format(base_currency)) + perf.loc[:, 'portfolio_value'].plot(ax=ax1) + ax1.set_ylabel('Portfolio\nValue\n({})'.format(base_currency)) - # Plot the price increase or decrease over time. + # Plot the price increase or decrease over time. ax2 = plt.subplot(612, sharex=ax1) - perf.loc[:, 'price'].plot(ax=ax2, label='Price') + perf.loc[:, 'price'].plot(ax=ax2, label='Price') - ax2.set_ylabel('{asset}\n({base})'.format( + ax2.set_ylabel('{asset}\n({base})'.format( asset=context.neo_eth.symbol, base=base_currency )) transaction_df = extract_transactions(perf) if not transaction_df.empty: - buy_df = transaction_df[transaction_df['amount'] > 0] - sell_df = transaction_df[transaction_df['amount'] < 0] + buy_df = transaction_df[transaction_df['amount'] > 0] + sell_df = transaction_df[transaction_df['amount'] < 0] ax2.scatter( buy_df.index.to_pydatetime(), - perf.loc[buy_df.index.floor('1 min'), 'price'], - marker='^', + perf.loc[buy_df.index.floor('1 min'), 'price'], + marker='^', s=100, - c='green', - label='' + c='green', + label='' ) ax2.scatter( sell_df.index.to_pydatetime(), - perf.loc[sell_df.index.floor('1 min'), 'price'], - marker='v', + perf.loc[sell_df.index.floor('1 min'), 'price'], + marker='v', s=100, - c='red', - label='' + c='red', + label='' ) ax4 = plt.subplot(613, sharex=ax1) - perf.loc[:, 'cash'].plot( - ax=ax4, label='Base Currency ({})'.format(base_currency) + perf.loc[:, 'cash'].plot( + ax=ax4, label='Base Currency ({})'.format(base_currency) ) - ax4.set_ylabel('Cash\n({})'.format(base_currency)) + ax4.set_ylabel('Cash\n({})'.format(base_currency)) - perf['algorithm'] = perf.loc[:, 'algorithm_period_return'] + perf['algorithm'] = perf.loc[:, 'algorithm_period_return'] ax5 = plt.subplot(614, sharex=ax1) - perf.loc[:, ['algorithm', 'price_change']].plot(ax=ax5) - ax5.set_ylabel('Percent\nChange') + perf.loc[:, ['algorithm', 'price_change']].plot(ax=ax5) + ax5.set_ylabel('Percent\nChange') ax6 = plt.subplot(615, sharex=ax1) - perf.loc[:, 'rsi'].plot(ax=ax6, label='RSI') - ax6.set_ylabel('RSI') - ax6.axhline(context.RSI_OVERBOUGHT, color='darkgoldenrod') - ax6.axhline(context.RSI_OVERSOLD, color='darkgoldenrod') + perf.loc[:, 'rsi'].plot(ax=ax6, label='RSI') + ax6.set_ylabel('RSI') + ax6.axhline(context.RSI_OVERBOUGHT, color='darkgoldenrod') + ax6.axhline(context.RSI_OVERSOLD, color='darkgoldenrod') if not transaction_df.empty: ax6.scatter( buy_df.index.to_pydatetime(), - perf.loc[buy_df.index.floor('1 min'), 'rsi'], - marker='^', + perf.loc[buy_df.index.floor('1 min'), 'rsi'], + marker='^', s=100, - c='green', - label='' + c='green', + label='' ) ax6.scatter( sell_df.index.to_pydatetime(), - perf.loc[sell_df.index.floor('1 min'), 'rsi'], - marker='v', + perf.loc[sell_df.index.floor('1 min'), 'rsi'], + marker='v', s=100, - c='red', - label='' + c='red', + label='' ) plt.legend(loc=3) start, end = ax6.get_ylim() ax6.yaxis.set_ticks(np.arange(0, end, end/5)) - # Show the plot. + # Show the plot. plt.gcf().set_size_inches(18, 8) plt.show() pass -if __name__ == '__main__': - # The execution mode: backtest or live - MODE = 'backtest' +if __name__ == '__main__': + # The execution mode: backtest or live + MODE = 'backtest' - if MODE == 'backtest': + if MODE == 'backtest': folder = os.path.join( - tempfile.gettempdir(), 'catalyst', NAMESPACE + tempfile.gettempdir(), 'catalyst', NAMESPACE ) ensure_directory(folder) - timestr = time.strftime('%Y%m%d-%H%M%S') - out = os.path.join(folder, '{}.p'.format(timestr)) - # catalyst run -f catalyst/examples/mean_reversion_simple.py -x bitfinex -s 2017-10-1 -e 2017-11-10 -c usdt -n mean-reversion --data-frequency minute --capital-base 10000 + timestr = time.strftime('%Y%m%d-%H%M%S') + out = os.path.join(folder, '{}.p'.format(timestr)) + # catalyst run -f catalyst/examples/mean_reversion_simple.py -x bitfinex -s 2017-10-1 -e 2017-11-10 -c usdt -n mean-reversion --data-frequency minute --capital-base 10000 run_algorithm( capital_base=10000, - data_frequency='minute', + data_frequency='minute', initialize=initialize, handle_data=handle_data, analyze=analyze, - exchange_name='bitfinex', + exchange_name='bitfinex', algo_namespace=NAMESPACE, - base_currency='usd', - start=pd.to_datetime('2017-10-01', utc=True), - end=pd.to_datetime('2017-11-10', utc=True), + base_currency='usd', + start=pd.to_datetime('2017-10-01', utc=True), + end=pd.to_datetime('2017-11-10', utc=True), output=out ) - log.info('saved perf stats: {}'.format(out)) + log.info('saved perf stats: {}'.format(out)) - elif MODE == 'live': + elif MODE == 'live': run_algorithm( capital_base=0.5, initialize=initialize, handle_data=handle_data, analyze=analyze, - exchange_name='bittrex', + exchange_name='bittrex', live=True, algo_namespace=NAMESPACE, - base_currency='usd', + base_currency='usd', live_graph=False )
        @@ -906,14 +1040,14 @@ environment). The first one retrieves all the pricing data needed for this script to run (only needs to be run once), and the second one executes this script with the parameters specified in the run_algorithm() call at the end of the file:

        -
        catalyst ingest-exchange -x bitfinex -f minute
        +
        catalyst ingest-exchange -x bitfinex -f minute
         
        -
        python simple_universe.py
        +
        python simple_universe.py
         

        Credits: This code was originally submitted by Abner Ayala-Acevedo. Thank you!

        -
        from datetime import timedelta
        +
        from datetime import timedelta
         
         import numpy as np
         import pandas as pd
        @@ -924,55 +1058,55 @@ of the file:

        def initialize(context): - context.i = -1 # minute counter + context.i = -1 # minute counter context.exchange = context.exchanges.values()[0].name.lower() context.base_currency = context.exchanges.values()[0].base_currency.lower() def handle_data(context, data): context.i += 1 - lookback_days = 7 # 7 days + lookback_days = 7 # 7 days - # current date & time in each iteration formatted into a string + # current date & time in each iteration formatted into a string now = data.current_dt - date, time = now.strftime('%Y-%m-%d %H:%M:%S').split(' ') + date, time = now.strftime('%Y-%m-%d %H:%M:%S').split(' ') lookback_date = now - timedelta(days=lookback_days) - # keep only the date as a string, discard the time - lookback_date = lookback_date.strftime('%Y-%m-%d %H:%M:%S').split(' ')[0] + # keep only the date as a string, discard the time + lookback_date = lookback_date.strftime('%Y-%m-%d %H:%M:%S').split(' ')[0] - one_day_in_minutes = 1440 # 60 * 24 assumes data_frequency='minute' - # update universe everyday at midnight + one_day_in_minutes = 1440 # 60 * 24 assumes data_frequency='minute' + # update universe everyday at midnight if not context.i % one_day_in_minutes: context.universe = universe(context, lookback_date, date) - # get data every 30 minutes + # get data every 30 minutes minutes = 30 - # get lookback_days of history data: that is 'lookback' number of bins + # get lookback_days of history data: that is 'lookback' number of bins lookback = one_day_in_minutes / minutes * lookback_days if not context.i % minutes and context.universe: - # we iterate for every pair in the current universe + # we iterate for every pair in the current universe for coin in context.coins: pair = str(coin.symbol) - # Get 30 minute interval OHLCV data. This is the standard data - # required for candlestick or indicators/signals. Return Pandas - # DataFrames. 30T means 30-minute re-sampling of one minute data. - # Adjust it to your desired time interval as needed. - opened = fill(data.history(coin, 'open', - bar_count=lookback, frequency='30T')).values - high = fill(data.history(coin, 'high', - bar_count=lookback, frequency='30T')).values - low = fill(data.history(coin, 'low', - bar_count=lookback, frequency='30T')).values - close = fill(data.history(coin, 'price', - bar_count=lookback, frequency='30T')).values - volume = fill(data.history(coin, 'volume', - bar_count=lookback, frequency='30T')).values + # Get 30 minute interval OHLCV data. This is the standard data + # required for candlestick or indicators/signals. Return Pandas + # DataFrames. 30T means 30-minute re-sampling of one minute data. + # Adjust it to your desired time interval as needed. + opened = fill(data.history(coin, 'open', + bar_count=lookback, frequency='30T')).values + high = fill(data.history(coin, 'high', + bar_count=lookback, frequency='30T')).values + low = fill(data.history(coin, 'low', + bar_count=lookback, frequency='30T')).values + close = fill(data.history(coin, 'price', + bar_count=lookback, frequency='30T')).values + volume = fill(data.history(coin, 'volume', + bar_count=lookback, frequency='30T')).values - # close[-1] is the last value in the set, which is the equivalent - # to current price (as in the most recent value) - # displays the minute price for each pair every 30 minutes - print('{now}: {pair} -\tO:{o},\tH:{h},\tL:{c},\tC{c},\tV:{v}'.format( + # close[-1] is the last value in the set, which is the equivalent + # to current price (as in the most recent value) + # displays the minute price for each pair every 30 minutes + print('{now}: {pair} -\tO:{o},\tH:{h},\tL:{c},\tC{c},\tV:{v}'.format( now=now, pair=pair, o=opened[-1], @@ -982,37 +1116,37 @@ of the file:

        v=volume[-1], )) - # ------------------------------------------------------------- - # --------------- Insert Your Strategy Here ------------------- - # ------------------------------------------------------------- + # ------------------------------------------------------------- + # --------------- Insert Your Strategy Here ------------------- + # ------------------------------------------------------------- def analyze(context=None, results=None): pass -# Get the universe for a given exchange and a given base_currency market -# Example: Poloniex BTC Market +# Get the universe for a given exchange and a given base_currency market +# Example: Poloniex BTC Market def universe(context, lookback_date, current_date): - # get all the pairs for the given exchange + # get all the pairs for the given exchange json_symbols = get_exchange_symbols(context.exchange) - # convert into a DataFrame for easier processing + # convert into a DataFrame for easier processing df = pd.DataFrame.from_dict(json_symbols).transpose().astype(str) - df['base_currency'] = df.apply(lambda row: row.symbol.split('_')[1],axis=1) - df['market_currency'] = df.apply(lambda row: row.symbol.split('_')[0],axis=1) + df['base_currency'] = df.apply(lambda row: row.symbol.split('_')[1],axis=1) + df['market_currency'] = df.apply(lambda row: row.symbol.split('_')[0],axis=1) - # Filter all the pairs to get only the ones for a given base_currency - df = df[df['base_currency'] == context.base_currency] + # Filter all the pairs to get only the ones for a given base_currency + df = df[df['base_currency'] == context.base_currency] - # Filter all the pairs to ensure that pair existed in the current date range + # Filter all the pairs to ensure that pair existed in the current date range df = df[df.start_date < lookback_date] df = df[df.end_daily >= current_date] - context.coins = symbols(*df.symbol) # convert all the pairs to symbols + context.coins = symbols(*df.symbol) # convert all the pairs to symbols return df.symbol.tolist() -# Replace all NA, NAN or infinite values with its nearest value +# Replace all NA, NAN or infinite values with its nearest value def fill(series): if isinstance(series, pd.Series): return series.replace([np.inf, -np.inf], np.nan).ffill().bfill() @@ -1024,21 +1158,21 @@ of the file:

        return series -if __name__ == '__main__': - start_date = pd.to_datetime('2017-11-10', utc=True) - end_date = pd.to_datetime('2017-11-13', utc=True) +if __name__ == '__main__': + start_date = pd.to_datetime('2017-11-10', utc=True) + end_date = pd.to_datetime('2017-11-13', utc=True) performance = run_algorithm(start=start_date, end=end_date, - capital_base=100.0, # amount of base_currency + capital_base=100.0, # amount of base_currency initialize=initialize, handle_data=handle_data, analyze=analyze, - exchange_name='bitfinex', - data_frequency='minute', - base_currency='btc', + exchange_name='bitfinex', + data_frequency='minute', + base_currency='btc', live=False, live_graph=False, - algo_namespace='simple_universe') + algo_namespace='simple_universe')
        @@ -1049,7 +1183,7 @@ select the portfolio with the maximum Sharpe Ratio. The parameters are set to use 180 days of historical data and rebalance every 30 days. This code was used in writting the following article: Markowitz Portfolio Optimization for Cryptocurrencies.

        -
        '''
        +
        '''
            You can run this code using the Python interpreter:
         
            $ python portfolio_optimization.py
        @@ -1067,49 +1201,49 @@ in writting the following article:
         from catalyst.api import record, symbol, symbols, order_target_percent
         from catalyst.utils.run_algo import run_algorithm
         
        -np.set_printoptions(threshold='nan', suppress=True)
        +np.set_printoptions(threshold='nan', suppress=True)
         
         
         def initialize(context):
        -   # Portfolio assets list
        -   context.assets = symbols('btc_usdt', 'eth_usdt', 'ltc_usdt', 'dash_usdt',
        -                            'xmr_usdt')
        +   # Portfolio assets list
        +   context.assets = symbols('btc_usdt', 'eth_usdt', 'ltc_usdt', 'dash_usdt',
        +                            'xmr_usdt')
            context.nassets = len(context.assets)
        -   # Set the time window that will be used to compute expected return
        -   # and asset correlations
        +   # Set the time window that will be used to compute expected return
        +   # and asset correlations
            context.window = 180
        -   # Set the number of days between each portfolio rebalancing
        +   # Set the number of days between each portfolio rebalancing
            context.rebalance_period = 30
            context.i = 0
         
         
         def handle_data(context, data):
        -   # Only rebalance at the beggining of the algorithm execution and
        -   # every multiple of the rebalance period
        +   # Only rebalance at the beggining of the algorithm execution and
        +   # every multiple of the rebalance period
            if context.i == 0 or context.i%context.rebalance_period == 0:
                n = context.window
        -       prices = data.history(context.assets, fields='price',
        -                             bar_count=n+1, frequency='1d')
        +       prices = data.history(context.assets, fields='price',
        +                             bar_count=n+1, frequency='1d')
                pr = np.asmatrix(prices)
                t_prices = prices.iloc[1:n+1]
                t_val = t_prices.values
                tminus_prices = prices.iloc[0:n]
                tminus_val = tminus_prices.values
        -       # Compute daily returns (r)
        +       # Compute daily returns (r)
                r = np.asmatrix(t_val/tminus_val-1)
        -       # Compute the expected returns of each asset with the average
        -       # daily return for the selected time window
        +       # Compute the expected returns of each asset with the average
        +       # daily return for the selected time window
                m = np.asmatrix(np.mean(r, axis=0))
        -       # ###
        +       # ###
                stds = np.std(r, axis=0)
        -       # Compute excess returns matrix (xr)
        +       # Compute excess returns matrix (xr)
                xr = r - m
        -       # Matrix algebra to get variance-covariance matrix
        +       # Matrix algebra to get variance-covariance matrix
                cov_m = np.dot(np.transpose(xr),xr)/n
        -       # Compute asset correlation matrix (informative only)
        +       # Compute asset correlation matrix (informative only)
                corr_m = cov_m/np.dot(np.transpose(stds),stds)
         
        -       # Define portfolio optimization parameters
        +       # Define portfolio optimization parameters
                n_portfolios = 50000
                results_array = np.zeros((3+context.nassets,n_portfolios))
                for p in xrange(n_portfolios):
        @@ -1119,38 +1253,38 @@ in writting the following article:
                    p_r = np.sum(np.dot(w,np.transpose(m)))*365
                    p_std = np.sqrt(np.dot(np.dot(w,cov_m),np.transpose(w)))*np.sqrt(365)
         
        -           #store results in results array
        +           #store results in results array
                    results_array[0,p] = p_r
                    results_array[1,p] = p_std
        -           #store Sharpe Ratio (return / volatility) - risk free rate element
        -           #excluded for simplicity
        +           #store Sharpe Ratio (return / volatility) - risk free rate element
        +           #excluded for simplicity
                    results_array[2,p] = results_array[0,p] / results_array[1,p]
                    i = 0
                    for iw in weights:
                        results_array[3+i,p] = weights[i]
                        i += 1
         
        -       #convert results array to Pandas DataFrame
        +       #convert results array to Pandas DataFrame
                results_frame = pd.DataFrame(np.transpose(results_array),
        -                          columns=['r','stdev','sharpe']+context.assets)
        -       #locate position of portfolio with highest Sharpe Ratio
        -       max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()]
        -       #locate positon of portfolio with minimum standard deviation
        -       min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()]
        +                          columns=['r','stdev','sharpe']+context.assets)
        +       #locate position of portfolio with highest Sharpe Ratio
        +       max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()]
        +       #locate positon of portfolio with minimum standard deviation
        +       min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()]
         
        -       #order optimal weights for each asset
        +       #order optimal weights for each asset
                for asset in context.assets:
                    if data.can_trade(asset):
                        order_target_percent(asset, max_sharpe_port[asset])
         
        -       #create scatter plot coloured by Sharpe Ratio
        -       plt.scatter(results_frame.stdev,results_frame.r,c=results_frame.sharpe,cmap='RdYlGn')
        -       plt.xlabel('Volatility')
        -       plt.ylabel('Returns')
        +       #create scatter plot coloured by Sharpe Ratio
        +       plt.scatter(results_frame.stdev,results_frame.r,c=results_frame.sharpe,cmap='RdYlGn')
        +       plt.xlabel('Volatility')
        +       plt.ylabel('Returns')
                plt.colorbar()
        -       #plot red star to highlight position of portfolio with highest Sharpe Ratio
        -       plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker='o',color='b',s=200)
        -       #plot green star to highlight position of minimum variance portfolio
        +       #plot red star to highlight position of portfolio with highest Sharpe Ratio
        +       plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker='o',color='b',s=200)
        +       #plot green star to highlight position of minimum variance portfolio
                plt.show()
                print(max_sharpe_port)
                record(pr=pr,r=r, m=m, stds=stds ,max_sharpe_port=max_sharpe_port, corr_m=corr_m)
        @@ -1158,15 +1292,15 @@ in writting the following article:
         
         
         def analyze(context=None, results=None):
        -   # Form DataFrame with selected data
        -   data = results[['pr','r','m','stds','max_sharpe_port','corr_m','portfolio_value']]
        +   # Form DataFrame with selected data
        +   data = results[['pr','r','m','stds','max_sharpe_port','corr_m','portfolio_value']]
         
        -   # Save results in CSV file
        -   filename = os.path.splitext(os.path.basename(__file__))[0]
        -   data.to_csv(filename + '.csv')
        +   # Save results in CSV file
        +   filename = os.path.splitext(os.path.basename(__file__))[0]
        +   data.to_csv(filename + '.csv')
         
         
        -# Bitcoin data is available from 2015-3-2. Dates vary for other tokens.
        +# Bitcoin data is available from 2015-3-2. Dates vary for other tokens.
         start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc)
         end = datetime(2017, 8, 16, 0, 0, 0, 0, pytz.utc)
         results = run_algorithm(initialize=initialize,
        @@ -1174,7 +1308,7 @@ in writting the following article:
                                 analyze=analyze,
                                 start=start,
                                 end=end,
        -                        exchange_name='poloniex',
        +                        exchange_name='poloniex',
                                 capital_base=100000, )
         
        @@ -1183,19 +1317,15 @@ in writting the following article:
        -
        -
        - -
        @@ -1229,8 +1358,7 @@ in writting the following article: VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/features.html b/features.html index 708dc073..b3af2dec 100644 --- a/features.html +++ b/features.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
        - - - - - - - - - - - - - - - - -
        - +
        - -
        -
        -
        +

        Features

        @@ -187,7 +325,7 @@ details.
      • structure in backtesting and paper trading.
      • Standardized naming convention for all asset pairs trading on any exchange in the form {market_currency}_{base_currency}. See -Naming Convention.
      • +Naming Convention.
      • Output of performance statistics based on Pandas DataFrames to integrate nicely into the existing PyData ecosystem.
      • Support for accessing multiple exchanges per algorithm, which opens the door @@ -204,7 +342,7 @@ can be specified through set_be
      • Support for Python2 and Python3.

      For additional details on the functionality added on recent releases, see the -Release Notes.

      +Release Notes.

      Upcoming features

      @@ -236,29 +374,29 @@ exchange. Catalyst will always expect in all its functions that you will refer t the asset pairs by using the Catalyst naming convention.

      If at any point, you input the wrong name for an asset pair, you will get an error of that pair not found in the given exchange, and a list of pairs available on that exchange:

      -
      $ catalyst ingest-exchange -x poloniex -i btc_usd
      +
      $ catalyst ingest-exchange -x poloniex -i btc_usd
       
      -
      Ingesting exchange bundle poloniex...
      -Error traceback: /Volumes/Data/Users/victoris/Desktop/Enigma/user-install/catalyst-dev/catalyst/exchange/exchange.py (line 175)
      -SymbolNotFoundOnExchange:  Symbol btc_usd not found on exchange Poloniex.
      -Choose from: ['rep_usdt', 'gno_btc', 'xvc_btc', 'pink_btc', 'sys_btc',
      -'emc2_btc', 'rads_btc', 'note_btc', 'maid_btc', 'bch_btc', 'gnt_btc',
      -'bcn_btc', 'rep_btc', 'bcy_btc', 'cvc_btc', 'nxt_xmr', 'zec_usdt',
      -'fct_btc', 'gas_btc', 'pot_btc', 'eth_usdt', 'btc_usdt', 'lbc_btc',
      -'dcr_btc', 'etc_usdt', 'omg_eth', 'amp_btc', 'xpm_btc', 'nxt_btc',
      -'vtc_btc', 'steem_eth', 'blk_xmr', 'pasc_btc', 'zec_xmr', 'grc_btc',
      -'nxc_btc', 'btcd_btc', 'ltc_btc', 'dash_btc', 'naut_btc', 'zec_eth',
      -'zec_btc', 'burst_btc', 'zrx_eth', 'bela_btc', 'steem_btc', 'etc_btc',
      -'eth_btc', 'huc_btc', 'strat_btc', 'lsk_btc', 'exp_btc', 'clam_btc',
      -'rep_eth', 'dash_xmr', 'cvc_eth', 'bch_usdt', 'zrx_btc', 'dash_usdt',
      -'blk_btc', 'xrp_btc', 'nxt_usdt', 'neos_btc', 'omg_btc', 'bts_btc',
      -'doge_btc', 'gnt_eth', 'sbd_btc', 'gno_eth', 'xcp_btc', 'ltc_usdt',
      -'btm_btc', 'xmr_usdt', 'lsk_eth', 'omni_btc', 'nav_btc', 'fldc_btc',
      -'ppc_btc', 'xbc_btc', 'dgb_btc', 'sc_btc', 'btcd_xmr', 'vrc_btc',
      -'ric_btc', 'str_btc', 'maid_xmr', 'xmr_btc', 'sjcx_btc', 'via_btc',
      -'xem_btc', 'nmc_btc', 'etc_eth', 'ltc_xmr', 'ardr_btc', 'gas_eth',
      -'flo_btc', 'xrp_usdt', 'game_btc', 'bch_eth', 'bcn_xmr', 'str_usdt']
      +
      Ingesting exchange bundle poloniex...
      +Error traceback: /Volumes/Data/Users/victoris/Desktop/Enigma/user-install/catalyst-dev/catalyst/exchange/exchange.py (line 175)
      +SymbolNotFoundOnExchange:  Symbol btc_usd not found on exchange Poloniex.
      +Choose from: ['rep_usdt', 'gno_btc', 'xvc_btc', 'pink_btc', 'sys_btc',
      +'emc2_btc', 'rads_btc', 'note_btc', 'maid_btc', 'bch_btc', 'gnt_btc',
      +'bcn_btc', 'rep_btc', 'bcy_btc', 'cvc_btc', 'nxt_xmr', 'zec_usdt',
      +'fct_btc', 'gas_btc', 'pot_btc', 'eth_usdt', 'btc_usdt', 'lbc_btc',
      +'dcr_btc', 'etc_usdt', 'omg_eth', 'amp_btc', 'xpm_btc', 'nxt_btc',
      +'vtc_btc', 'steem_eth', 'blk_xmr', 'pasc_btc', 'zec_xmr', 'grc_btc',
      +'nxc_btc', 'btcd_btc', 'ltc_btc', 'dash_btc', 'naut_btc', 'zec_eth',
      +'zec_btc', 'burst_btc', 'zrx_eth', 'bela_btc', 'steem_btc', 'etc_btc',
      +'eth_btc', 'huc_btc', 'strat_btc', 'lsk_btc', 'exp_btc', 'clam_btc',
      +'rep_eth', 'dash_xmr', 'cvc_eth', 'bch_usdt', 'zrx_btc', 'dash_usdt',
      +'blk_btc', 'xrp_btc', 'nxt_usdt', 'neos_btc', 'omg_btc', 'bts_btc',
      +'doge_btc', 'gnt_eth', 'sbd_btc', 'gno_eth', 'xcp_btc', 'ltc_usdt',
      +'btm_btc', 'xmr_usdt', 'lsk_eth', 'omni_btc', 'nav_btc', 'fldc_btc',
      +'ppc_btc', 'xbc_btc', 'dgb_btc', 'sc_btc', 'btcd_xmr', 'vrc_btc',
      +'ric_btc', 'str_btc', 'maid_xmr', 'xmr_btc', 'sjcx_btc', 'via_btc',
      +'xem_btc', 'nmc_btc', 'etc_eth', 'ltc_xmr', 'ardr_btc', 'gas_eth',
      +'flo_btc', 'xrp_usdt', 'game_btc', 'bch_eth', 'bcn_xmr', 'str_usdt']
       

      In the example above, exchange Poloniex does not use USD, but uses instead the @@ -266,30 +404,26 @@ USDT cryptocurrency asset that is issued on the Bitcoin blockchain via the Omni Layer Protocol. Each USDT unit is backed by a U.S Dollar held in the reserves of Tether Limited. USDT can be transferred, stored, and spent, just like bitcoins or any other cryptocurrency. Given its 1:1 mapping to the USD, is a viable alternative.

      -
      $ catalyst ingest-exchange -x poloniex -i btc_usdt
      +
      $ catalyst ingest-exchange -x poloniex -i btc_usdt
       
      -
      Ingesting exchange bundle poloniex...
      -    [====================================]  Fetching poloniex daily candles: :  100%
      +
      Ingesting exchange bundle poloniex...
      +    [====================================]  Fetching poloniex daily candles: :  100%
       
      -
      -
      - -
      @@ -323,8 +456,7 @@ or any other cryptocurrency. Given its 1:1 mapping to the USD, is a viable alter VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/genindex.html b/genindex.html index cfcf457c..0fda09ca 100644 --- a/genindex.html +++ b/genindex.html @@ -14,8 +14,6 @@ - - @@ -33,9 +31,6 @@ - - @@ -45,28 +40,21 @@ -
      - - - - - - - - - - - - - - - - -
      - +
        - -
      • Docs »
      • - -
      • Index
      • - - +
      • Docs »
      • + +
      • - +
      • -
      - -
      -
      -
      +

      Index

      @@ -184,370 +327,582 @@

      A

      - - + +
      + +
      Asset (class in catalyst.assets) +
      + +
      + +
      AssetConvertible (class in catalyst.assets) +
      + +

      B

      - +
      + +
      BarData (class in catalyst.protocol) +
      + +

      C

      - - + +
      + +
      CachedObject (class in catalyst.utils.cache) +
      + + +
      calculate() (catalyst.finance.commission.CommissionModel method) +
      + + +
      can_trade() (catalyst.protocol.BarData method) +
      + + +
      cancel_order() (in module catalyst.api) +
      + +
      + +
      CancelPolicy (class in catalyst.finance.cancel_policy) +
      + + +
      clear_calendars() (in module catalyst.utils.calendars) +
      + + +
      CommissionModel (class in catalyst.finance.commission) +
      + + +
      current() (catalyst.protocol.BarData method) +
      + +

      D

      - - + +
      + +
      dataframe_cache (class in catalyst.utils.cache) +
      + + +
      date_rules (class in catalyst.api) +
      + +
      + +
      deregister_calendar() (in module catalyst.utils.calendars) +
      + +

      E

      - - + +
      + +
      EODCancel() (in module catalyst.api) +
      + + +
      every_day (catalyst.api.date_rules attribute) +
      + + +
      every_minute (catalyst.api.time_rules attribute) +
      + +
      + +
      exchange (catalyst.finance.execution.ExecutionStyle attribute) +
      + + +
      ExecutionStyle (class in catalyst.finance.execution) +
      + + +
      ExpiringCache (class in catalyst.utils.cache) +
      + +

      F

      - - + +
      + +
      fetch_csv() (in module catalyst.api) +
      + + +
      first_traded (catalyst.assets.Asset attribute) +
      + +
      + +
      FixedSlippage (class in catalyst.finance.slippage) +
      + + +
      from_dict() (catalyst.assets.Asset method) +
      + +

      G

      - - + +
      + +
      get_calendar() (in module catalyst.utils.calendars) +
      + + +
      get_environment() (in module catalyst.api) +
      + + +
      get_limit_price() (catalyst.finance.execution.ExecutionStyle method) +
      + +
      + +
      get_open_orders() (in module catalyst.api) +
      + + +
      get_order() (in module catalyst.api) +
      + + +
      get_stop_price() (catalyst.finance.execution.ExecutionStyle method) +
      + +

      H

      - +
      + +
      history() (catalyst.protocol.BarData method) +
      + +

      I

      - - + +
      + +
      is_alive_for_session() (catalyst.assets.Asset method) +
      + + +
      is_exchange_open() (catalyst.assets.Asset method) +
      + + +
      is_open_on_minute() (catalyst.utils.calendars.TradingCalendar method) +
      + +
      + +
      is_session() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      is_stale() (catalyst.protocol.BarData method) +
      + +

      L

      - +
      + +
      LimitOrder (class in catalyst.finance.execution) +
      + +

      M

      - - + +
      + +
      market_close (catalyst.api.time_rules attribute) +
      + + +
      market_open (catalyst.api.time_rules attribute) +
      + + +
      MarketOrder (class in catalyst.finance.execution) +
      + + +
      maybe_show_progress() (in module catalyst.utils.cli) +
      + + +
      minute_index_to_session_labels() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      minute_to_session_label() (catalyst.utils.calendars.TradingCalendar method) +
      + +
      + +
      minutes_count_for_sessions_in_range() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      minutes_for_session() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      minutes_for_sessions_in_range() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      minutes_in_range() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      month_end() (catalyst.api.date_rules static method) +
      + + +
      month_start() (catalyst.api.date_rules static method) +
      + +

      N

      - - + +
      + +
      NeverCancel() (in module catalyst.api) +
      + + +
      next_close() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      next_minute() (catalyst.utils.calendars.TradingCalendar method) +
      + +
      + +
      next_open() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      next_session_label() (catalyst.utils.calendars.TradingCalendar method) +
      + +

      O

      - - + +
      + +
      open_and_close_for_session() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      order() (in module catalyst.api) +
      + + +
      order_percent() (in module catalyst.api) +
      + + +
      order_target() (in module catalyst.api) +
      + +
      + +
      order_target_percent() (in module catalyst.api) +
      + + +
      order_target_value() (in module catalyst.api) +
      + + +
      order_value() (in module catalyst.api) +
      + +

      P

      - - + +
      + +
      PerDollar (class in catalyst.finance.commission) +
      + + +
      PerShare (class in catalyst.finance.commission) +
      + + +
      PerTrade (class in catalyst.finance.commission) +
      + + +
      previous_close() (catalyst.utils.calendars.TradingCalendar method) +
      + +
      + +
      previous_minute() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      previous_open() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      previous_session_label() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      process_order() (catalyst.finance.slippage.SlippageModel method) +
      + +

      R

      - - + +
      + +
      record() (in module catalyst.api) +
      + + +
      register_calendar() (in module catalyst.utils.calendars) +
      + + +
      register_calendar_type() (in module catalyst.utils.calendars) +
      + +
      + +
      regular_holidays (catalyst.utils.calendars.TradingCalendar attribute) +
      + + +
      run_algorithm() (in module catalyst) +
      + +

      S

      - - + +
      + +
      schedule_function() (in module catalyst.api) +
      + + +
      session_distance() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      sessions_in_range() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      sessions_window() (catalyst.utils.calendars.TradingCalendar method) +
      + + +
      set_benchmark() (in module catalyst.api) +
      + + +
      set_cancel_policy() (in module catalyst.api) +
      + + +
      set_commission() (in module catalyst.api) +
      + + +
      set_do_not_order_list() (in module catalyst.api) +
      + + +
      set_long_only() (in module catalyst.api) +
      + + +
      set_max_leverage() (in module catalyst.api) +
      + + +
      set_max_order_count() (in module catalyst.api) +
      + + +
      set_max_order_size() (in module catalyst.api) +
      + + +
      set_max_position_size() (in module catalyst.api) +
      + +
      + +
      set_slippage() (in module catalyst.api) +
      + + +
      set_symbol_lookup_date() (in module catalyst.api) +
      + + +
      should_cancel() (catalyst.finance.cancel_policy.CancelPolicy method) +
      + + +
      sid() (in module catalyst.api) +
      + + +
      SlippageModel (class in catalyst.finance.slippage) +
      + + +
      special_closes (catalyst.utils.calendars.TradingCalendar attribute) +
      + + +
      special_closes_adhoc (catalyst.utils.calendars.TradingCalendar attribute) +
      + + +
      special_opens (catalyst.utils.calendars.TradingCalendar attribute) +
      + + +
      special_opens_adhoc (catalyst.utils.calendars.TradingCalendar attribute) +
      + + +
      StopLimitOrder (class in catalyst.finance.execution) +
      + + +
      StopOrder (class in catalyst.finance.execution) +
      + + +
      symbol() (in module catalyst.api) +
      + + +
      symbols() (in module catalyst.api) +
      + +

      T

      - - + +
      + +
      time_rules (class in catalyst.api) +
      + + +
      to_dict() (catalyst.assets.Asset method) +
      + +
      + +
      TradingCalendar (class in catalyst.utils.calendars) +
      + +

      V

      - +
      + +
      VolumeShareSlippage (class in catalyst.finance.slippage) +
      + +

      W

      - - + +
      + +
      week_end() (catalyst.api.date_rules static method) +
      + + +
      week_start() (catalyst.api.date_rules static method) +
      + +
      + +
      working_dir (class in catalyst.utils.cache) +
      + + +
      working_file (class in catalyst.utils.cache) +
      + +
      -
      -
      - -
      @@ -581,8 +935,7 @@ VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/index.html b/index.html index 14cf06af..dae5ea4b 100644 --- a/index.html +++ b/index.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -45,28 +40,21 @@ -
      - - - - - - - - - - - - - - - - -
      - +
      - -
      -
      -
      +
      Enigma | Catalyst

      version tag @@ -170,7 +313,7 @@

      Catalyst is an algorithmic trading library for crypto-assets written in Python. It allows trading strategies to be easily expressed and backtested against historical data (with daily and minute resolution), providing analytics and -insights regarding a particular strategy’s performance. Catalyst also supports +insights regarding a particular strategy’s performance. Catalyst also supports live-trading of crypto-assets starting with three exchanges (Bitfinex, Bittrex, and Poloniex) with more being added over time. Catalyst empowers users to share and curate data and build profitable, data-driven investment strategies. Please @@ -230,16 +373,12 @@ performance across trading algorithms.

      -
      -
      - -
      @@ -274,8 +412,7 @@ performance across trading algorithms. VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/install.html b/install.html index 1ba9708e..3887a974 100644 --- a/install.html +++ b/install.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
      - - - - - - - - - - - - - - - - -
      - +
      - -
      -
      -
      +

      Install

      @@ -190,29 +311,29 @@ Like any other piece of software, Catalyst has a number of dependencies well. We recommend using a software named Conda that will manage all these dependencies for you, and set up the environment needed to get you up and running as easily as possible. This is the recommended installation method -for Windows, MacOS and Linux. See Installing with Conda.

      +for Windows, MacOS and Linux. See Installing with Conda.

      What conda does is create a pre-configured environment, and inside that -environment install Catalyst using pip, Python’s package manager. Thus, +environment install Catalyst using pip, Python’s package manager. Thus, as an alternative installation method for MacOS and Linux, you can install Catalyst directly with pip (we recommend in combination with a virtual -environemnt). See Installing with pip.

      +environemnt). See Installing with pip.

      Alternatively you can install Catalyst using pipenv which is a mix of pip -and virtualenv. See Installing with pipenv.

      +and virtualenv. See Installing with pipenv.

      Regardless of the method, each operating system (OS), has its own prerequisites, make sure to review the corresponding sections for your system: -Linux, MacOS and Windows.

      +Linux, MacOS and Windows.

      Installing with conda

      The preferred method to install Catalyst is via the conda package manager, -which comes as part of Continuum Analytics’ Anaconda distribution.

      +which comes as part of Continuum Analytics’ Anaconda distribution.

      The primary advantage of using Conda over pip is that conda natively understands the complex binary dependencies of packages like numpy and scipy. This means that conda can install Catalyst and its -dependencies without requiring the use of a second tool to acquire Catalyst’s +dependencies without requiring the use of a second tool to acquire Catalyst’s non-Python dependencies.

      For Windows, you will first need to install the Microsoft Visual C++ -Compiler for Python 2.7. Follow the instructions on the Windows section and come back here.
      +Compiler for Python 2.7. Follow the instructions on the Windows section and come back here.

      For instructions on how to install conda, see the Conda Installation Documentation. Alternatively, you can install MiniConda, which is a smaller footprint (fewer packages and @@ -226,18 +347,18 @@ for your Operating System. window, which should print the list of packages installed with Conda.

      -
      For Windows, if you accepted the default installation options, you didn’t +
      For Windows, if you accepted the default installation options, you didn’t check an option to add Conda to the PATH, so trying to run conda from a regular Command Prompt will result in the following error: 'conda' is no recognized as an internal or external command, operatble program or -batch file. That’s to be expected. You will nee to launch an Anaconda +batch file. That’s to be expected. You will nee to launch an Anaconda Prompt that was added at installation time to your list of programs available from the Start menu.

      Once either Conda or MiniConda has been set up you can install Catalyst:

      1. Download the file python2.7-environment.yml.

        -

        To download, simply click on the ‘Raw’ button and save the file locally +

        To download, simply click on the ‘Raw’ button and save the file locally to a folder you can remember. Make sure that the file gets saved with the .yml extension, and nothing like a .txt file or anything else.

        @@ -246,23 +367,23 @@ to a folder you can remember. Make sure that the file gets saved with the saved the above python2.7-environment.yml file.

      2. Install using this file. This step can take about 5-10 minutes to install.

        -
        conda env create -f python2.7-environment.yml
        +
        conda env create -f python2.7-environment.yml
         
      3. Activate the environment (which you need to do every time you start a new session to run Catalyst):

        Linux or MacOS:

        -
        source activate catalyst
        +
        source activate catalyst
         

        Windows:

        -
        activate catalyst
        +
        activate catalyst
         
      4. Verify that Catalyst is install correctly:

        -
        catalyst --version
        +
        catalyst --version
         

        which should display the current version.

        @@ -278,32 +399,32 @@ with the following steps:

      5. If the above installation failed, and you have a partially set up catalyst environment, remove it first. If you are starting from scratch, proceed to step #2:

        -
        conda env remove --name catalyst
        +
        conda env remove --name catalyst
         
      6. Create the environment:

        -
        conda create --name catalyst python=2.7 scipy zlib
        +
        conda create --name catalyst python=2.7 scipy zlib
         
      7. Activate the environment:

        Linux or MacOS:

        -
        source activate catalyst
        +
        source activate catalyst
         

        Windows:

        -
        activate catalyst
        +
        activate catalyst
         
      8. Install the Catalyst inside the environment:

        -
        pip install enigma-catalyst matplotlib
        +
        pip install enigma-catalyst matplotlib
         
      9. Verify that Catalyst is installed correctly:

        -
        catalyst --version
        +
        catalyst --version
         

        which should display the current version.

        @@ -325,26 +446,26 @@ CPython header files for your Python installation.
      10. numerical array computing in Python. Numpy depends on having the LAPACK linear algebra routines available.

      Because LAPACK and the CPython headers are non-Python dependencies, the -correctway to install them varies from platform to platform. If you’d rather -use a single tool to install Python and non-Python dependencies, or if you’re +correctway to install them varies from platform to platform. If you’d rather +use a single tool to install Python and non-Python dependencies, or if you’re already using Anaconda as your Python -distribution, refer to the Installing with Conda section.

      +distribution, refer to the Installing with Conda section.

      If you use Python for anything other than Catalyst, we strongly recommend -that you install in a virtualenv. The Hitchhiker’s Guide to -Python provides an excellent tutorial on virtualenv. Here’s a +that you install in a virtualenv. The Hitchhiker’s Guide to +Python provides an excellent tutorial on virtualenv. Here’s a summarized version:

      -
      $ pip install virtualenv
      -$ virtualenv catalyst-venv
      -$ source ./catalyst-venv/bin/activate
      +
      $ pip install virtualenv
      +$ virtualenv catalyst-venv
      +$ source ./catalyst-venv/bin/activate
       
      -

      Once you’ve installed the necessary additional dependencies for your system -(GNU/Linux Requirements, MacOS Requirements or Windows Requirements) and have activated your virtualenv, you should be able to simply run

      -
      $ pip install enigma-catalyst matplotlib
      +

      Once you’ve installed the necessary additional dependencies for your system +(GNU/Linux Requirements, MacOS Requirements or Windows Requirements) and have activated your virtualenv, you should be able to simply run

      +
      $ pip install enigma-catalyst matplotlib
       

      Note that in the command above we install two different packages. The second -one, matplotlib is a visualization library. While it’s not strictly +one, matplotlib is a visualization library. While it’s not strictly required to run catalyst simulations or live trading, it comes in very handy to visualize the performance of your algorithms, and for this reason we recommend you install it, as well.

      @@ -355,11 +476,11 @@ recommend you install it, as well.

      Package enigma-catalyst cannot be found
      Solution:

      Make sure you have the most up-to-date version of pip installed, by running:

      -
      $ pip install --upgrade pip
      +
      $ pip install --upgrade pip
       

      On Windows, the recommended command is:

      -
      $ python -m pip install --upgrade pip
      +
      $ python -m pip install --upgrade pip
       
      @@ -369,10 +490,10 @@ recommend you install it, as well.

      Issue:

      Package enigma-catalyst cannot still be found, even after upgrading pip (see above), with an error similar to:

      -
      Downloading/unpacking enigma-catalyst
      +
      Downloading/unpacking enigma-catalyst
       Could not find a version that satisfies the requirement enigma-catalyst
      -(from versions: 0.1.dev9, 0.2.dev2, 0.1.dev4, 0.1.dev5, 0.1.dev3,
      -0.2.dev1, 0.1.dev8, 0.1.dev6)
      +(from versions: 0.1.dev9, 0.2.dev2, 0.1.dev4, 0.1.dev5, 0.1.dev3,
      +0.2.dev1, 0.1.dev8, 0.1.dev6)
       Cleaning up...
       No distributions matching the version for enigma-catalyst
       
      @@ -382,9 +503,9 @@ No distributions matching the version for enigma-catalyst

      In some systems (this error has been reported in Ubuntu), pip is configured to only find stable versions by default. Since Catalyst is in alpha version, pip cannot find a matching version that satisfies the installation -requirements. The solution is to include the –pre flag to include +requirements. The solution is to include the –pre flag to include pre-release and development versions:

      -
      $ pip install --pre enigma-catalyst
      +
      $ pip install --pre enigma-catalyst
       
      @@ -395,7 +516,7 @@ pre-release and development versions:

      Package enigma-catalyst fails to install because of outdated setuptools
      Solution:

      Upgrade to the most up-to-date setuptools package by running:

      -
      $ pip install --upgrade pip setuptools
      +
      $ pip install --upgrade pip setuptools
       
      @@ -406,9 +527,9 @@ pre-release and development versions:

      Missing required packages
      Solution:

      Download requirements.txt -(click on the Raw button and Right click -> Save As…) and use it to +(click on the Raw button and Right click -> Save As...) and use it to install all the required dependencies by running:

      -
      $ pip install -r requirements.txt
      +
      $ pip install -r requirements.txt
       
      @@ -423,7 +544,7 @@ install all the required dependencies by running:

      for the proper build and installation of package dependencies. The solution is to install python-dev, which is independent of the virtual environment. In Ubuntu, you would need to run:

      -
      $ sudo apt-get install python-dev
      +
      $ sudo apt-get install python-dev
       
      @@ -434,21 +555,21 @@ In Ubuntu, you would need to run:

      Installing with pipenv

      Installing Catalyst via pipenv is perhaps easier that installing it via pip itself but you need to install pipenv first via pip.

      -
      $ pip install pipenv
      +
      $ pip install pipenv
       

      Once pipenv is installed you can proceed by creating a project folder and installing Catalyst on that project automagically as follows:

      -
      $ mkdir project
      -$ cd project
      -$ pipenv --two
      -$ pipenv install enigma-catalyst matplotlib
      +
      $ mkdir project
      +$ cd project
      +$ pipenv --two
      +$ pipenv install enigma-catalyst matplotlib
       

      Until now the workflow compared to pip is almost identical, the difference -is that you don’t need to load manually any virtualenv however you need to use +is that you don’t need to load manually any virtualenv however you need to use the pipenv run prefix to run the catalyst command as follows:

      -
      $ pipenv run catalyst --version
      +
      $ pipenv run catalyst --version
       

      If you want to know more about pipenv go to the pipenv github repo

      @@ -457,29 +578,29 @@ the pipenv run prefix to run the catalyst command as f

      GNU/Linux Requirements

      On Debian-derived Linux distributions, you can acquire all the necessary binary dependencies from apt by running:

      -
      $ sudo apt-get install libatlas-base-dev python-dev gfortran pkg-config libfreetype6-dev
      +
      $ sudo apt-get install libatlas-base-dev python-dev gfortran pkg-config libfreetype6-dev
       

      On recent RHEL-derived derived Linux distributions (e.g. Fedora), the following should be sufficient to acquire the necessary additional dependencies:

      -
      $ sudo dnf install atlas-devel gcc-c++ gcc-gfortran libgfortran python-devel redhat-rep-config
      +
      $ sudo dnf install atlas-devel gcc-c++ gcc-gfortran libgfortran python-devel redhat-rep-config
       

      On Arch Linux, you can acquire the additional dependencies via pacman:

      -
      $ pacman -S lapack gcc gcc-fortran pkg-config
      +
      $ pacman -S lapack gcc gcc-fortran pkg-config
       

      Amazon Linux AMI Notes

      The packages pip and setuptools that come shipped by default are very outdated. Thus, you first need to run:

      -
      $ pip install --upgrade pip setuptools
      +
      $ pip install --upgrade pip setuptools
       

      The default installation is also missing the C and C++ compilers, which you install by:

      -
      $ sudo yum install gcc gcc-c++
      +
      $ sudo yum install gcc gcc-c++
       

      Then you should follow the regular installation instructions outlined at the @@ -489,21 +610,21 @@ beginning of this page.

      MacOS Requirements

      The version of Python shipped with MacOS by default is generally out of date, -and has a number of quirks because it’s used directly by the operating system. +and has a number of quirks because it’s used directly by the operating system. For these reasons, many developers choose to install and use a separate Python -installation. The Hitchhiker’s Guide to Python provides an excellent guide +installation. The Hitchhiker’s Guide to Python provides an excellent guide to Installing Python on MacOS, which explains how to install Python with the Homebrew manager.

      -

      Assuming you’ve installed Python with Homebrew, you’ll also likely need the +

      Assuming you’ve installed Python with Homebrew, you’ll also likely need the following brew packages:

      -
      $ brew install freetype pkg-config gcc openssl
      +
      $ brew install freetype pkg-config gcc openssl
       

      MacOS + virtualenv/conda + matplotlib

      The first time that you try to run an algorithm that loads the matplotlib library, you may get the following error:

      -
      RuntimeError: Python is not installed as a framework. The Mac OS X backend
      +
      RuntimeError: Python is not installed as a framework. The Mac OS X backend
       will not be able to function correctly if Python is not installed as a
       framework. See the Python documentation for more information on installing
       Python as a framework on Mac OS X. Please either reinstall Python as a
      @@ -515,7 +636,7 @@ information.
       

      This is a matplotlib-specific error, that will go away once you run the following command:

      -
      $ echo "backend: TkAgg" > ~/.matplotlib/matplotlibrc
      +
      $ echo "backend: TkAgg" > ~/.matplotlib/matplotlibrc
       

      in order to override the default MacOS backend for your system, which @@ -531,11 +652,11 @@ about matplotlib backends, please refer to the

      In Windows, you will first need to install the Microsoft Visual C++ Compiler for Python 2.7. This package contains the compiler and the set of system headers necessary for -producing binary wheels for Python 2.7 packages. If it’s not already in your +producing binary wheels for Python 2.7 packages. If it’s not already in your system, download it and install it before proceeding to the next step.

      Once you have the above compiler installed, the easiest and best supported way -to install Catalyst in Windows is to use Conda. If you didn’t -any problems installing the compiler, jump to the Conda section, +to install Catalyst in Windows is to use Conda. If you didn’t +any problems installing the compiler, jump to the Conda section, otherwise keep on reading to troubleshoot the C++ compiler installtion.

      Some problems we have encountered installing the Visual C++ Compiler mentioned above are as follows:

      @@ -543,7 +664,7 @@ mentioned above are as follows:

    • The system administrator has set policies to prevent this installation.

      In some systems, there is a default Windows Software Restriction policy that prevents the installation of some software packages like this one. -You’ll have to change the Registry to circumvent this:

      +You’ll have to change the Registry to circumvent this:

      • Click Start, and search for regedit and launch the Registry Editor
      • @@ -585,12 +706,12 @@ update Catalyst frequently. Once installed, Catalyst can easily be updated as a pip package regardless of the environemnt used for installation. Make sure you activate your environment first as you did in your first install, and then execute:

        -
        $ pip uninstall enigma-catalyst
        -$ pip install enigma-catalyst
        +
        $ pip uninstall enigma-catalyst
        +$ pip install enigma-catalyst
         

        Alternatively, you could update Catalyst issuing the following command:

        -
        $ pip install -U enigma-catalyst
        +
        $ pip install -U enigma-catalyst
         

        but this command will also upgrade all the Catalyst dependencies to the latest @@ -620,19 +741,15 @@ and you get a hint on how to solve it.

        -
        -
        - -
        @@ -666,8 +782,7 @@ and you get a hint on how to solve it. VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/live-trading.html b/live-trading.html index 67b5e515..ec63fdc4 100644 --- a/live-trading.html +++ b/live-trading.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
        - - - - - - - - - - - - - - - - -
        - +
        - -
        -
        -
        +

        Live Trading

        @@ -248,7 +384,7 @@ Here is how to generate key and secret values for the Bitfinex exchange: https://docs.bitfinex.com/v1/docs/api-access. Most exchanges follow a similar process.

        The auth.json file:

        -
        {
        +
        {
           "name": "bitfinex",
           "key": "my-key",
           "secret": "my-secret"
        @@ -257,7 +393,7 @@ a similar process.

        The file goes here: ~/.catalyst/data/exchanges/bitfinex/auth.json

        Note that the bitfinex part in the directory above corresponds to the id of the Bitfinex -exchange as defined in the “Supported Exchanges” section above. +exchange as defined in the “Supported Exchanges” section above. Attempting to run an algorithm where the targeted exchange is missing its auth.json file will create the directory structure and create an empty auth.json file, but will result in an error.

        @@ -278,13 +414,13 @@ seperator.

        [Market Currency]_[Base Currency] all lowercase.

        Currency symbols (e.g. btc, eth, ltc) follow the Bittrex convention.

        Here are some examples:

        -
        # With Bitfinex
        -bitcoin_usd_asset = symbol('btc_usd')
        -ethereum_bitcoin_asset = symbol('eth_btc')
        +
        # With Bitfinex
        +bitcoin_usd_asset = symbol('btc_usd')
        +ethereum_bitcoin_asset = symbol('eth_btc')
         
        -# With Bittrex
        -ethereum_bitcoin_asset = symbol('eth_btc')
        -neo_ethereum_asset = symbol('neo_eth)
        +# With Bittrex
        +ethereum_bitcoin_asset = symbol('eth_btc')
        +neo_ethereum_asset = symbol('neo_eth)
         

        Note that the trading pairs are always referenced in the same manner. @@ -301,17 +437,17 @@ algorithm for live trading. The same algorithm should work in backtest and live execution mode without modification.

        What differs are the arguments provided to the catalyst client or run_algorithm() interface. Here is the same example in both interfaces:

        -
        catalyst live -f my_algo_code -x bitfinex -c btc -n my_algo_name
        +
        catalyst live -f my_algo_code -x bitfinex -c btc -n my_algo_name
         
        -
        run_algorithm(
        +
        run_algorithm(
             initialize=initialize,
             handle_data=handle_data,
             analyze=analyze,
        -    exchange_name='bitfinex',
        +    exchange_name='bitfinex',
             live=True,
        -    algo_namespace='my_algo_name',
        -    base_currency='btc'
        +    algo_namespace='my_algo_name',
        +    base_currency='btc'
         )
         
        @@ -340,19 +476,15 @@ simulated in Catalyst instead of processed on the exchange. It defaults to
        -
        -
        - -
        @@ -386,8 +517,7 @@ simulated in Catalyst instead of processed on the exchange. It defaults to VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/objects.inv b/objects.inv index e43090a3..ccad1251 100644 Binary files a/objects.inv and b/objects.inv differ diff --git a/release-process.html b/release-process.html index ce5fd64a..b9898331 100644 --- a/release-process.html +++ b/release-process.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -44,28 +39,21 @@ -
        - - - - - - - - - - - - - - - - -
        - +
        - -
        -
        -
        +

        Release Process

        @@ -166,25 +309,25 @@

        Updating the Release Notes

        -

        When we are ready to ship a new release of zipline, edit the Release Notes +

        When we are ready to ship a new release of zipline, edit the Release Notes page. We will have been maintaining a whatsnew file while working on the release with the new version. First, find that file in: docs/source/whatsnew/<version>.txt. It will be the highest version number. -Edit the release date field to be today’s date in the format:

        -
        <month> <day>, <year>
        +Edit the release date field to be today’s date in the format:

        +
        <month> <day>, <year>
         

        for example, November 6, 2015. Remove the active development warning from the whatsnew, since it will no longer be pending release. -Update the title of the release from “Development” to “Release x.x.x” and -update the underline of the title to match the title’s width.

        -

        If you are renaming the release at this point, you’ll need to git mv the file +Update the title of the release from “Development” to “Release x.x.x” and +update the underline of the title to match the title’s width.

        +

        If you are renaming the release at this point, you’ll need to git mv the file and also update releases.rst to reference the renamed file.

        To build and view the docs locally, run:

        -
        $ cd docs
        -$ make html
        -$ {BROWSER} build/html/index.html
        +
        $ cd docs
        +$ make html
        +$ {BROWSER} build/html/index.html
         
        @@ -196,7 +339,7 @@ namespace is populated at import time by decorators on TradingAlgorithm methods. Those functions are therefore hidden from static analysis tools, but we can generate static files to make them available. Under Python 3, run the following to generate any stub files:

        -
        $ python etc/gen_type_stubs.py
        +
        $ python etc/gen_type_stubs.py
         
        @@ -215,15 +358,15 @@ should be added to that header.

        Updating the __version__

        We use versioneer to manage the __version__ and setup.py version. This means that we pull -this information from our version control’s tags to ensure that they stay in +this information from our version control’s tags to ensure that they stay in sync and to have very fine grained version strings for development installs.

        To upgrade the version use the git tag command like:

        -
        $ git tag <major>.<minor>.<micro>
        -$ git push && git push --tags
        +
        $ git tag <major>.<minor>.<micro>
        +$ git push && git push --tags
         

        This will push the the code and the tag information.

        -

        Next, click the “Draft a new release” button on the zipline releases page. For the new release, +

        Next, click the “Draft a new release” button on the zipline releases page. For the new release, choose the tag you just pushed, and publish the release.

        @@ -231,15 +374,15 @@ choose the tag you just pushed, and publish the release.

        sdist

        To build the sdist (source distribution) run:

        -
        $ python setup.py sdist
        +
        $ python setup.py sdist
         

        from the zipline root. This will create a gzipped tarball that includes all the python, cython, and miscellaneous files needed to install zipline. To test that the source dist worked correctly, cd into an empty directory, create a new virtualenv and then run:

        -
        $ pip install <zipline-root>/dist/zipline-<major>.<minor>.<micro>.tar.gz
        -$ python -c 'import zipline;print(zipline.__version__)'
        +
        $ pip install <zipline-root>/dist/zipline-<major>.<minor>.<micro>.tar.gz
        +$ python -c 'import zipline;print(zipline.__version__)'
         

        This should print the version we are expecting to release.

        @@ -253,23 +396,23 @@ all the required packages.

        Now that we have tested the package locally, it should be tested using the test PyPI server.

        Edit your ~/.pypirc file to look like:

        -
        [distutils]
        -index-servers =
        -    pypi
        -    pypitest
        +
        [distutils]
        +index-servers =
        +    pypi
        +    pypitest
         
        -[pypi]
        -username:
        -password:
        +[pypi]
        +username:
        +password:
         
        -[pypitest]
        -repository: https://testpypi.python.org/pypi
        -username:
        -password:
        +[pypitest]
        +repository: https://testpypi.python.org/pypi
        +username:
        +password:
         

        after that, run:

        -
        $ python setup.py sdist upload -r pypitest
        +
        $ python setup.py sdist upload -r pypitest
         
        @@ -286,20 +429,20 @@ debugging packaging problems on the test server.

        This will upload zipline to the pypi test server. To test installing from pypi, create a new virtualenv, cd into a clean directory and then run:

        -
        $ pip install --extra-index-url https://testpypi.python.org/pypi zipline
        -$ python -c 'import zipline;print(zipline.__version__)'
        +
        $ pip install --extra-index-url https://testpypi.python.org/pypi zipline
        +$ python -c 'import zipline;print(zipline.__version__)'
         

        This should pull the package you just uploaded and then print the version number.

        Now that we have tested locally and on PyPI test, it is time to upload to PyPI:

        -
        $ python setup.py sdist upload
        +
        $ python setup.py sdist upload
         

        bdist

        -

        Because zipline now supports multiple versions of numpy, we’re not building +

        Because zipline now supports multiple versions of numpy, we’re not building binary wheels, since they are not tagged with the version of numpy with which they were compiled.

        @@ -308,7 +451,7 @@ they were compiled.

        Documentation

        To update zipline.io, checkout the latest master and run:

        -
        python <zipline_root>/docs/deploy.py
        +
        python <zipline_root>/docs/deploy.py
         

        This will build the documentation, checkout a fresh copy of the gh-pages @@ -323,9 +466,9 @@ correct arguments.

        Now, using our browser of choice, view the index.html page and verify that the docs look correct.

        Once we are happy, push the updated docs to the GitHub gh-pages branch.

        -
        $ git add .
        -$ git commit -m "DOC: update zipline.io"
        -$ git push origin gh-pages
        +
        $ git add .
        +$ git commit -m "DOC: update zipline.io"
        +$ git push origin gh-pages
         

        zipline.io will update in a few moments.

        @@ -334,20 +477,20 @@ $ git push origin gh-pages

        Uploading conda packages

        Travis and AppVeyor build zipline conda packages for us. Once they have built and uploaded to anaconda.org the packages (and their dependencies) for the -release commit to master, we should move those packages from the “ci” label to -the “main” label. You can do this from the anaconda.org web interface. This -is also a good time to remove all the old “ci” packages from anaconda.

        -

        Travis and AppVeyor only build and upload linux-64 and win-64 packages. We’ll +release commit to master, we should move those packages from the “ci” label to +the “main” label. You can do this from the anaconda.org web interface. This +is also a good time to remove all the old “ci” packages from anaconda.

        +

        Travis and AppVeyor only build and upload linux-64 and win-64 packages. We’ll need to build and upload osx-64 packages manually on an OSX machine.

        To build the conda packages for zipline locally, run:

        -
        $ python etc/conda_build_matrix.py
        +
        $ python etc/conda_build_matrix.py
         

        If all of the builds succeed, then this will not print anything and exit with EXIT_SUCCESS. If there are build issues, we must address them and decide what to do.

        Once all of the builds in the matrix pass, we can upload them to anaconda with:

        -
        $ python etc/conda_build_matrix.py --upload
        +
        $ python etc/conda_build_matrix.py --upload
         

        If you would like to test this command by uploading to a different user, this @@ -358,21 +501,17 @@ may be specified with the --use

        Push a new commit post-release that adds the whatsnew for the next release, which should be titled according to a micro version increment. If that next release turns out to be a major/minor version increment, the file can be -renamed when that’s decided. You can use docs/source/whatsnew/skeleton.txt +renamed when that’s decided. You can use docs/source/whatsnew/skeleton.txt as a template for the new file.

        Include the whatsnew file in docs/source/releases.rst. New releases should appear at the top. The syntax for this is:

        -
        .. include:: whatsnew/<version>.txt
        +
        .. include:: whatsnew/<version>.txt
         
        -
        -
        - -
        @@ -406,8 +544,7 @@ appear at the top. The syntax for this is:

        VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/releases.html b/releases.html index 2d3db3a4..32c61b69 100644 --- a/releases.html +++ b/releases.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -45,28 +40,21 @@ -
        - - - - - - - - - - - - - - - - -
        - +
        - -
        -
        -
        +

        Release Notes

        +
        +

        Version 0.5.3

        +

        Release Date: 2018-02-09

        +
        +

        Bug Fixes

        +
          +
        • Fixed an issue with last candle in backtesting #219
        • +
        +
        +

        Version 0.5.2

        Release Date: 2018-02-08

        -
        -

        Bug Fixes

        +
        +

        Bug Fixes

        • Fixed an issue with live candle values #216 and #199
        @@ -271,8 +327,8 @@

        Version 0.5.1

        Release Date: 2018-02-07

        -
        -

        Bug Fixes

        +
        +

        Bug Fixes

        • Fixed an issue with orders that stay open #211
        • Fixed Jupyter issues #179
        • @@ -290,14 +346,14 @@

          Version 0.4.7

          Release Date: 2018-01-19

          -
          -

          Bug Fixes

          +
          +

          Bug Fixes

          • Fixing issue #137 impacting the CLI
          -
          -

          Build

          +
          +

          Build

          • Implemented authentication aliases (#60)
          @@ -306,8 +362,8 @@

          Version 0.4.6

          Release Date: 2018-01-18

          -
          -

          Bug Fixes

          +
          +

          Bug Fixes

          • Fixed some Python3 issues
          • Reading the trade log to get executed order prices on exchanges like Binance (#151)
          • @@ -317,8 +373,8 @@
          • Using Bitfinex instead of Poloniex to fetch btc_usdt benchmark (#161)
          -
          -

          Build

          +
          +

          Build

          • Added a context.state dict to keep arbitrary state values between runs
          • Added ability to stop live algo at specified end date
          • @@ -328,8 +384,8 @@

            Version 0.4.5

            Release Date: 2018-01-12

            -
            -

            Bug Fixes

            +
            +

            Bug Fixes

            • Improved order execution for exchanges supporting trade lists (#151)
            • Fixed an issue where requesting history of multiple assets repeats values
            • @@ -341,8 +397,8 @@

              Version 0.4.4

              Release Date: 2018-01-09

              -
              -

              Bug Fixes

              +
              +

              Bug Fixes

              • Removed redundant capital_base validation (#142)
              • Fixed portfolio update issue with restored state (#111)
              • @@ -353,8 +409,8 @@

                Version 0.4.3

                Release Date: 2018-01-05

                -
                -

                Bug Fixes

                +
                +

                Bug Fixes

                • Fixed CLI issue (#137)
                • Upgraded CCXT
                • @@ -364,8 +420,8 @@

                  Version 0.4.2

                  Release Date: 2018-01-03

                  -
                  -

                  Bug Fixes

                  +
                  +

                  Bug Fixes

                  • Fixed cash synchronization issue (#133)
                  • Fixed positions synchronization issue (#132)
                  • @@ -375,8 +431,8 @@
                  • Fixed a poloniex specific issue in live trading (#103)
                  -
                  -

                  Build

                  +
                  +

                  Build

                  • Caching CCXT market info to limit round-trips (#99)
                  • Tentative support for Pipeline (#96)
                  • @@ -386,16 +442,16 @@

                    Version 0.4.0

                    Release Date: 2017-12-12

                    -
                    -

                    Bug Fixes

                    +
                    +

                    Bug Fixes

                    • Changed Poloniex interface (should solve #95 and #94)
                    • Solved issue with overriding commission and slippage (#87)
                    • Fixed inefficiency with Bittrex current prices (#76)
                    -
                    -

                    Build

                    +
                    +

                    Build

                    • Integrated with CCXT
                    • Added paper trading capability (simulate_orders=True param in live mode)
                    • @@ -407,8 +463,8 @@

                      Version 0.3.10

                      Release Date: 2017-11-28

                    -
                    -

                    Bug Fixes

                    +
                    +

                    Bug Fixes

                    • Fixed issue with fetching assets with daily frequency
                    @@ -417,15 +473,15 @@

                    Version 0.3.9

                    Release Date: 2017-11-28

                    -
                    -

                    Bug Fixes

                    +
                    +

                    Bug Fixes

                    • Fixed sortino warning issues (#77)
                    • Adjusted computation of last candle of data.history (#71)
                    -
                    -

                    Build

                    +
                    +

                    Build

                    • Added capital_base parameter to live mode to limit cash (#79)
                    • Added support for csv ingestion (#65)
                    • @@ -436,8 +492,8 @@

                      Version 0.3.8

                      Release Date: 2017-11-14

                      -
                      -

                      Bug Fixes

                      +
                      +

                      Bug Fixes

                      • Fixed a warning filter issue introduced with the latest release
                      @@ -446,8 +502,8 @@

                      Version 0.3.7

                      Release Date: 2017-11-14

                      -
                      -

                      Bug Fixes

                      +
                      +

                      Bug Fixes

                      • Fixed an SSL cert issue (#64)
                      • Fixed cumulative stats warnings (#63)
                      • @@ -455,8 +511,8 @@
                      • Standardized live-trading stats (#61)
                      -
                      -

                      Build

                      +
                      +

                      Build

                      • Added a mean-reversion sample algo
                      • Added minutely stats in the analyze() function (#62)
                      • @@ -467,8 +523,8 @@

                        Version 0.3.6

                        Release Date: 2017-11-4

                        -
                        -

                        Bug Fixes

                        +
                        +

                        Bug Fixes

                        • Fixed an issue with single bar data.history() (#55)
                        @@ -477,8 +533,8 @@

                        Version 0.3.5

                        Release Date: 2017-11-4

                        -
                        -

                        Bug Fixes

                        +
                        +

                        Bug Fixes

                        • Added workaround for: KeyError: Timestamp error (#53)
                        @@ -487,8 +543,8 @@

                        Version 0.3.4

                        Release Date: 2017-11-2

                        -
                        -

                        Bug Fixes

                        +
                        +

                        Bug Fixes

                        • Fixed issue with auto-ingestion of minute data (#47)
                        • Fixed issue with sell orders in backtesting
                        • @@ -498,8 +554,8 @@ transactions
                        -
                        -

                        Build

                        +
                        +

                        Build

                        • Added more unit tests
                        @@ -526,16 +582,16 @@ transactions

                        Version 0.3.3

                        Release Date: 2017-10-26

                        -
                        -

                        Bug Fixes

                        +
                        +

                        Bug Fixes

                        • Fix missing -x in ingest-exchange
                        • Fix issue with daily chunks end date (data bundles)
                        • Fix issue in the prepare_chunk logic (data bundles)
                        -
                        -

                        Build

                        +
                        +

                        Build

                        • Added data validation unit tests
                        @@ -544,8 +600,8 @@ transactions

                        Version 0.3.2

                        Release Date: 2017-10-25

                        -
                        -

                        Bug Fixes

                        +
                        +

                        Bug Fixes

                        • Fix to work with empty data bundles
                        • Fix Windows path of $HOME/.catalyst folder
                        • @@ -554,8 +610,8 @@ transactions
                        • Fix an issue with asset date in chunks
                        -
                        -

                        Build

                        +
                        +

                        Build

                        • Python3 adjustments
                        • Added method to clean bundle folders, and remove symbols.json
                        • @@ -566,8 +622,8 @@ transactions

                          Version 0.3.1

                          Release Date: 2017-10-22

                          -
                          -

                          Bug Fixes

                          +
                          +

                          Bug Fixes

                          • Fixed OS-dependent path issue in data bundle
                          • Changed handling of empty auth.json, instead of throwing an error for @@ -594,7 +650,7 @@ missing file
                          • Version 0.2.dev5

                            Release Date: 2017-10-03

                              -
                            • Fixes bug in data.history function that was formatting ‘volume’ data as +
                            • Fixes bug in data.history function that was formatting ‘volume’ data as integers, now they are returned as floats with up to 9 decimals of precision. Data bundles redone.
                            @@ -687,17 +743,13 @@ exchange directly
                          -
                          -
                          - -
                          @@ -731,8 +782,7 @@ exchange directly VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/resources.html b/resources.html index 8fce9b8f..045fdadf 100644 --- a/resources.html +++ b/resources.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
                          - - - - - - - - - - - - - - - - -
                          - +
                          - -
                          -
                          -
                          +

                          Resources

                          @@ -176,7 +316,7 @@ Trading Library, and the project Catalyst forked off in the spring of 2017.
                        • Quantopian provides a platform for freelance quantitative analysts develop, test, and use trading algorithms to buy and sell securities. They aim to create a crowd-sourced hedge fund by -fostering their community of freelance traders. Quantopian’s backtesting and +fostering their community of freelance traders. Quantopian’s backtesting and live-trading engine is powered by Zipline.
                        • Pandas is a Python library providing high-performance, easy-to-use data structures and data @@ -193,19 +333,15 @@ trading algorithms
                        • -
                          -
                          - -
                          @@ -239,8 +374,7 @@ trading algorithms VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/search.html b/search.html index 42ae0647..0754428e 100644 --- a/search.html +++ b/search.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -44,28 +39,21 @@ -
                          - - - - - - - - - - - - - - - - -
                          - +
                            - -
                          • Docs »
                          • - -
                          • Search
                          • - - +
                          • Docs »
                          • + +
                          • -
                          - -
                          -
                          -
                          +
                          -
                          - -
                          @@ -205,8 +343,7 @@ VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/searchindex.js b/searchindex.js index 3f36b39c..a8503046 100644 --- a/searchindex.js +++ b/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["appendix","beginner-tutorial","bundles","development-guidelines","example-algos","features","index","install","live-trading","release-process","releases","resources","unit-tests","utilities","videos"],envversion:53,filenames:["appendix.rst","beginner-tutorial.rst","bundles.rst","development-guidelines.rst","example-algos.rst","features.rst","index.rst","install.rst","live-trading.rst","release-process.rst","releases.rst","resources.rst","unit-tests.rst","utilities.rst","videos.rst"],objects:{"catalyst.api":{EODCancel:[0,0,1,""],NeverCancel:[0,0,1,""],cancel_order:[0,0,1,""],date_rules:[0,1,1,""],fetch_csv:[0,0,1,""],get_environment:[0,0,1,""],get_open_orders:[0,0,1,""],get_order:[0,0,1,""],order:[0,0,1,""],order_percent:[0,0,1,""],order_target:[0,0,1,""],order_target_percent:[0,0,1,""],order_target_value:[0,0,1,""],order_value:[0,0,1,""],record:[0,0,1,""],schedule_function:[0,0,1,""],set_benchmark:[0,0,1,""],set_cancel_policy:[0,0,1,""],set_commission:[0,0,1,""],set_do_not_order_list:[0,0,1,""],set_long_only:[0,0,1,""],set_max_leverage:[0,0,1,""],set_max_order_count:[0,0,1,""],set_max_order_size:[0,0,1,""],set_max_position_size:[0,0,1,""],set_slippage:[0,0,1,""],set_symbol_lookup_date:[0,0,1,""],sid:[0,0,1,""],symbol:[0,0,1,""],symbols:[0,0,1,""],time_rules:[0,1,1,""]},"catalyst.api.date_rules":{every_day:[0,2,1,""],month_end:[0,3,1,""],month_start:[0,3,1,""],week_end:[0,3,1,""],week_start:[0,3,1,""]},"catalyst.api.time_rules":{every_minute:[0,2,1,""],market_close:[0,2,1,""],market_open:[0,2,1,""]},"catalyst.assets":{Asset:[0,1,1,""],AssetConvertible:[0,1,1,""]},"catalyst.assets.Asset":{first_traded:[0,2,1,""],from_dict:[0,4,1,""],is_alive_for_session:[0,4,1,""],is_exchange_open:[0,4,1,""],to_dict:[0,4,1,""]},"catalyst.finance.cancel_policy":{CancelPolicy:[0,1,1,""]},"catalyst.finance.cancel_policy.CancelPolicy":{should_cancel:[0,4,1,""]},"catalyst.finance.commission":{CommissionModel:[0,1,1,""],PerDollar:[0,1,1,""],PerShare:[0,1,1,""],PerTrade:[0,1,1,""]},"catalyst.finance.commission.CommissionModel":{calculate:[0,4,1,""]},"catalyst.finance.execution":{ExecutionStyle:[0,1,1,""],LimitOrder:[0,1,1,""],MarketOrder:[0,1,1,""],StopLimitOrder:[0,1,1,""],StopOrder:[0,1,1,""]},"catalyst.finance.execution.ExecutionStyle":{exchange:[0,2,1,""],get_limit_price:[0,4,1,""],get_stop_price:[0,4,1,""]},"catalyst.finance.slippage":{FixedSlippage:[0,1,1,""],SlippageModel:[0,1,1,""],VolumeShareSlippage:[0,1,1,""]},"catalyst.finance.slippage.SlippageModel":{process_order:[0,4,1,""]},"catalyst.protocol":{BarData:[0,1,1,""]},"catalyst.protocol.BarData":{can_trade:[0,4,1,""],current:[0,4,1,""],history:[0,4,1,""],is_stale:[0,4,1,""]},"catalyst.utils.cache":{CachedObject:[0,1,1,""],ExpiringCache:[0,1,1,""],dataframe_cache:[0,1,1,""],working_dir:[0,1,1,""],working_file:[0,1,1,""]},"catalyst.utils.calendars":{TradingCalendar:[0,1,1,""],clear_calendars:[0,0,1,""],deregister_calendar:[0,0,1,""],get_calendar:[0,0,1,""],register_calendar:[0,0,1,""],register_calendar_type:[0,0,1,""]},"catalyst.utils.calendars.TradingCalendar":{is_open_on_minute:[0,4,1,""],is_session:[0,4,1,""],minute_index_to_session_labels:[0,4,1,""],minute_to_session_label:[0,4,1,""],minutes_count_for_sessions_in_range:[0,4,1,""],minutes_for_session:[0,4,1,""],minutes_for_sessions_in_range:[0,4,1,""],minutes_in_range:[0,4,1,""],next_close:[0,4,1,""],next_minute:[0,4,1,""],next_open:[0,4,1,""],next_session_label:[0,4,1,""],open_and_close_for_session:[0,4,1,""],previous_close:[0,4,1,""],previous_minute:[0,4,1,""],previous_open:[0,4,1,""],previous_session_label:[0,4,1,""],regular_holidays:[0,2,1,""],session_distance:[0,4,1,""],sessions_in_range:[0,4,1,""],sessions_window:[0,4,1,""],special_closes:[0,2,1,""],special_closes_adhoc:[0,2,1,""],special_opens:[0,2,1,""],special_opens_adhoc:[0,2,1,""]},"catalyst.utils.cli":{maybe_show_progress:[0,0,1,""]},catalyst:{run_algorithm:[0,0,1,""]}},objnames:{"0":["py","function","Python function"],"1":["py","class","Python class"],"2":["py","attribute","Python attribute"],"3":["py","staticmethod","Python static method"],"4":["py","method","Python method"]},objtypes:{"0":"py:function","1":"py:class","2":"py:attribute","3":"py:staticmethod","4":"py:method"},terms:{"000000e":1,"1000th":1,"15t":4,"1st":1,"30t":4,"328842e":1,"340mb":10,"380954e":1,"40mb":10,"460mb":10,"505275d6646a41f3856b22b16678d":1,"536708e":1,"5min":[1,4],"650729e":1,"7869f7828fa140328eb40477bb7d":1,"998236e":1,"998677e":1,"999120e":1,"999558e":1,"99mb":10,"abstract":0,"boolean":[0,2,8],"break":7,"case":[0,1,2,3,7,13],"class":[0,3,9],"default":[0,1,5,7,8,10,13],"enum":0,"export":9,"final":[1,2,3],"float":[0,1,10],"function":[1,2,3,4,6,7,9,10,11,13],"import":[0,1,2,4,9,13],"int":[0,2],"long":[1,2,4],"new":[0,1,3,7,8,9],"null":12,"public":10,"return":[0,1,4,8,9,10,11],"short":[0,1,3,4],"static":[0,9],"switch":8,"throw":10,"true":[0,1,4,8,10],"try":[3,4,7],"var":1,"while":[5,7,9,10],AWS:10,Added:10,And:1,For:[0,1,2,4,5,7,8,9,12],Not:[0,12],One:2,That:[1,7],The:[0,1,2,3,4,7,8,9,10,13],Then:[2,3,4,7],There:[1,3,7,8],These:[0,1,8,13],Use:[1,4,13],Using:[9,10],With:8,__del__:0,__exit__:0,__file__:[4,13],__future__:4,__getitem__:0,__main__:[1,4],__name__:[1,4],__setitem__:0,__wrapped__:9,_html_base:3,_tkinter:1,aapl:2,abc:0,abil:[2,10],abl:[1,2,7],abner:4,about:[0,1,2,6,7],abov:[0,1,3,4,5,7,8,9],absolut:0,abstractholidaycalendar:0,accept:[0,2,7,9],access:[0,5,6,7,8],accord:[0,9],accordingli:[1,4],account:[0,1,2,4,6,10],acevedo:4,acquir:[2,7],across:[5,6,10],activ:[7,8,9],actual:[0,1],add:[1,2,3,7,9,13],added:[0,1,2,5,6,7,9],adding:[1,3],addit:[0,1,3,5,6,7,10],addition:8,address:9,adjust:[0,2,4,10],administr:7,advantag:7,afford:[1,4],aforement:1,after:[0,1,2,4,7,9],afteropen:0,again:[1,3],against:[1,6,8,10,14],agre:4,ahead:1,aim:[4,11],algebra:[4,7],algo:[0,1,2,4,10],algo_namespac:[1,4,8],algo_volatil:1,algofil:[1,2],algorithm:[3,5,6,7,10,11,12,13,14],algorithm_period_return:[1,4],algotext:1,alia:[0,4],alias:[4,10],aliv:0,all:[0,1,2,3,4,5,6,7,8,9,10,12],alloc:0,allow:[0,1,2,5,6,7],almost:7,along:[0,2],alongsid:1,alpha:[1,4,7,8],alreadi:[0,1,2,3,7],also:[0,1,2,3,4,6,7,8,9],altern:[1,5,7],although:1,alwai:[0,2,5,8,9],amount:[0,1,4,8,10],amount_charg:0,amp_btc:5,ana:7,anaconda:[1,7,9],analog:1,analysi:[1,4,6,9,10,11],analyst:11,analyt:[6,7],analyz:[0,1,4,8,10,13],ani:[0,1,2,4,5,7,8,9,13],anonym:2,anoth:[1,2,4,5],anymor:1,anyth:[1,7,9],apach:4,api:[1,2,4,5,6,7,8,9,13],app:7,appar:1,appear:[0,2,9],append:9,appli:[0,1,4],applic:[1,4],appropri:[1,3,4],approxim:[1,4],appveyor:9,apt:[1,7],arang:[1,4],arbitrag:5,arbitrari:[8,10],arbitrarili:1,arch:7,architectur:1,ardr_btc:5,arena:0,arg:[0,1,9],argument:[0,1,2,8,9],argv:13,around:[6,9],arrai:[4,7],art:6,articl:[3,4],ask:[1,3],asmatrix:4,assert:[3,12],assertionerror:3,assess:1,asset:[1,2,4,5,6,8,10,13],asset_nam:[0,1,4],asset_restrict:0,assetconvert:0,assetdbwrit:2,assign:[1,8],assimil:1,assist:7,assum:[1,3,4,7],astyp:4,atla:7,attach:0,attempt:[0,2,8],attribut:[0,4,9],auth:[8,10],authent:10,auto:10,auto_close_d:0,automag:7,automat:0,avail:[0,1,4,5,7,8,9,10,12,13],averag:7,avoid:[1,2,4],awai:7,awar:[0,9],ax1:[1,4],ax2:[1,4],ax3:[1,4],ax4:[1,4],ax5:[1,4],ax6:[1,4],axhlin:4,axi:[0,4],ayala:4,back:[0,3,5,7],backbon:4,backend:7,backtest:[1,4,5,6,7,8,10,11],backward:0,bah:4,bar:[0,1,4,10],bar_count:[0,1,4],bar_templ:0,bardata:0,base:[0,1,2,4,5,6,7,8,14],base_curr:[1,4,5,8,13],base_pric:[1,4],basenam:[4,13],basi:[4,10],batch:7,batteri:1,battl:7,bch_btc:5,bch_eth:5,bch_usdt:5,bcn_btc:5,bcn_xmr:5,bcolz:2,bcolzdailybarread:2,bcolzdailybarwrit:2,bcolzminutebarread:2,bcolzminutebarwrit:2,bcy_btc:5,be62ff77760c4599abaac43be9cc9:1,bear:[1,4],beautifi:1,becaus:[0,1,7,9,10],been:[0,1,2,7,9],befor:[0,1,2,4,7,8,10],before_trading_start:[0,4],beforeclos:0,beggin:4,begin:[0,1,4,7],beginn:[4,6],behavior:0,being:[0,1,6],bela_btc:5,believ:1,below:[0,1,3,4,13],benchmark:[0,1,4,5,6,10],benchmark_period_return:[1,4],benchmark_volatil:1,benefit:1,best:[3,6,7],beta:[1,4],better:[0,1],between:[0,1,3,4,5,6,10,12],beyond:5,bfill:4,bia:1,big:7,bin:[4,7],binanc:[8,10],binari:[7,9],bit:[3,7],bitcoin:[1,4,5,6,8,13],bitcoin_usd_asset:8,bitfinex:[1,4,5,6,8,10],bitmex:8,bittrex:[1,4,5,6,8,10,14],blank:12,bld:3,blk_btc:5,blk_xmr:5,blockchain:5,blotter:13,blue:1,bodi:3,book:1,bool:0,both:[0,1,3,5,8,9,12],bought:[1,8],bound:[0,1],boundari:0,branch:9,breakdown:8,brew:7,brother:7,brows:7,browser:[1,3,9],btc:[1,8,10],btc_usd:[1,4,5,8],btc_usdt:[4,5,6,10,13],btcd_btc:5,btcd_xmr:5,btm_btc:5,bts_btc:5,bug:[0,2,3],bui:[0,1,8,11,12,14],build:[0,1,3,6,7,9],build_ext:3,built:[4,9,12],bundl:[0,1,5,10],bundle_timestamp:0,burst_btc:5,button:[7,9],buy_and_hodl:[4,10],buy_btc_simpl:[1,4],buy_btc_simple_out:[1,4],buy_df:[1,4],buy_low_sell_high:10,cach:[1,10],cachedobject:0,cal_nam:0,calcul:[0,1,3,4,8,12],calendar_typ:0,calendarnamecollis:0,call:[0,1,2,3,4,10],callabl:0,callback:0,can:[0,1,2,3,4,5,6,7,8,9,10,13],can_trad:[0,1,4,10],cancel:[1,4,12],cancel_ord:[0,1,4],cancel_polici:0,cancelpolici:0,candl:[1,5,10,12],candle_s:4,candlestick:4,cannot:[0,1,4,7],canon:3,capabl:10,capit:[0,1,4],capital_bas:[0,1,4,8,10,13],capital_us:1,captur:1,cash:[1,2,3,4,10],catalyst:[0,3,4,5,6,8,10,11,12,13,14],catalyst_dev:[1,6,7],catalyst_root:0,caus:[0,1,2,3],ccxt:[8,10],cell:1,cert:10,certian:0,chanc:1,chang:[0,1,3,4,6,7,9,10],channel:[1,6,7],charact:3,charg:[0,1],chart:[1,4,7],check:[0,1,2,3,4,5,7,8],checker:9,checkout:[3,9],choic:9,choos:[1,4,5,7,9,13],chosen:[1,13],chunk:[0,1,10],circumv:7,clam_btc:5,classic:[1,4],classifi:1,clean:[0,2,7,9,10,12],clean_on_failur:0,clear:2,clear_calendar:0,cli:[0,1,4,10,13],click:[0,7,9],client:8,clone:3,close:[0,1,4,5,13],cls:0,cmap:4,cmd:[1,7],cme:0,code:[0,1,4,7,9,10,13],codebas:3,codifi:0,coin:[1,4,10],collect:[1,2,4],collis:0,color:[1,4],colorbar:4,colour:4,column:[0,1,2,4],com:[1,2,3,8],combin:[0,7,8],come:[2,7],command:[2,4,7,9],comment:1,commiss:[1,5,10],commissionmodel:0,commit:0,common:[0,1],commonli:1,commun:[5,7,11],comp:4,compar:[1,4,5,6,7,12],comparison:10,compat:[0,6,10],compil:[7,9,10],complement:4,complet:8,complex:[1,7],complianc:4,complimentari:13,comprehens:10,compress:[1,10],comput:[1,4,7,10,11],concept:[0,1],conda:[1,10],conda_build_matrix:9,condit:[0,4],confid:8,config:7,configur:[1,7,10],congratul:7,consecut:0,consid:[0,1,4],consist:[1,5,12],constant:1,constraint:2,consum:9,contain:[0,1,2,3,4,7,12],content:[1,13],context:[0,1,3,4,10,13],contigu:0,continu:1,continuum:7,contract:0,contribut:5,control:[8,9],conveni:[0,1],convent:[4,8],convers:2,convert:[0,2,4],copi:[1,2,3,4,9],copy_tre:0,copyright:4,core:7,corr_m:4,correct:[2,7,8,9],correctli:[1,7,9],correctwai:7,correl:4,correspond:[0,1,7,8,13],cost:[0,1,4],could:[0,1,2,4,7,13],count:[0,2],counter:4,coupl:1,cov_m:4,covari:4,cover:[0,1,4,8,13],coverag:[5,6,8],cpython:7,crash:2,creat:[1,2,4,7,8,9,10,11,12,13],creation:10,credit:4,critic:5,cross:[0,5],crossov:1,crowd:11,crypto:[1,6,10],cryptoasset:[1,4,13,14],cryptocurr:[4,5,8],csv:[0,1,4,10],csv_data_sourc:0,csvfile:13,csvwriter:13,cumul:10,cumulative_capital_us:3,curat:[1,6],currenc:[1,4],current:[0,1,2,4,7,8,9,10,13],current_d:4,current_dai:4,current_dt:[4,13],current_valu:0,custom:[1,2,5,13],cvc_btc:5,cvc_eth:5,cython:9,d6dca79513214346a646079213526:1,dai:[0,1,2,4,7,9],daili:[0,1,2,4,5,6,10,13],darkgoldenrod:4,dash:8,dash_btc:5,dash_usdt:[4,5],dash_xmr:5,data:[4,5,6,7,8,10,11],data_frequ:[0,1,4,13],data_port:0,databas:2,datafram:[0,1,2,4,5,6,11,12,13],dataframe_cach:[0,2],dataport:0,dataset:[1,2,5],date:[0,1,2,4,7,9,10,12,13],date_column:0,date_format:0,date_rul:0,datetim:[0,4,13],datetimeindex:0,day_end:0,day_start:0,days_offset:0,dcr_btc:5,debian:[1,7],debug:9,decentr:5,decid:9,decim:[0,10],decor:9,decreas:4,def:[1,4,13],default_extens:0,defin:[0,1,4,8],delai:1,delet:[0,2],delist:0,demonstr:1,denomin:1,dep:3,depart_docu:3,depend:[0,1,3,7,9,10,13],deploi:9,deprec:3,deregist:0,deregister_calendar:0,deriv:7,describ:[0,5],descript:[3,7],desir:[0,1,4,12,13],desktop:5,detail:[4,5],determin:[0,4],dev1:7,dev2:7,dev3:7,dev4:7,dev5:7,dev6:7,dev8:7,dev9:7,dev:[3,5,7],devel:7,develop:[1,6,7,8,9,10,11,13],deviat:4,devis:1,dgb_btc:5,dict:[0,10],dict_:0,dictionari:[0,10],did:[6,7],didn:7,differ:[0,1,2,4,5,7,8,9,13],dimension:0,dir:7,dir_util:0,direct:0,directli:[1,2,7,10,13],directori:[0,1,2,3,4,7,8,9],disabl:10,disablemsi:7,discard:4,discord:[1,3,6,7],discuss:1,disk:[0,10],dismiss:1,displai:[1,4,7,9,10],dist:9,distanc:0,distinguish:0,distribut:[4,7,9],distutil:9,divid:[0,3],dividend:[0,2],divis:4,dma:1,dname:1,dnf:7,doc:[2,4,8,9],dockerfil:3,docstr:10,doctest:0,document:[3,4,5,6,7,8],docutil:3,doe:[0,1,2,4,5,7],doesn:[0,2],doge_btc:5,dollar:[0,5],don:[0,1,3,7,14],done:[1,4,9],door:5,dot:[0,4],down:[1,4,14],downgrad:3,download:[1,2,7,10],draft:9,drawback:2,drive:1,driven:[1,6,8],drop:0,dropbox:10,dt_minut:0,dual_moving_averag:[1,4],due:0,dure:0,dword:7,dynam:4,each:[0,1,2,3,4,5,6,7,8,10,12,13],earlier:[1,2,3,4],earliest:4,eas:6,easi:[1,2,4,11],easier:[1,2,4,5,7],easiest:7,easili:[1,6,7],eastern:0,echo:7,eco:6,ecosystem:5,edit:[3,4,7,9],editor:7,educ:1,educt:1,effect:7,either:[0,1,4,7],elaps:4,element:[0,4],elif:[1,4],els:[4,7],emc2_btc:5,empow:[1,6],empti:[1,2,3,4,8,9,10],empty_char:0,empyr:10,enabl:8,encapsul:0,encount:7,encourag:8,end:[0,1,4,10,12,13],end_daili:4,end_dat:[0,1,4],end_minut:0,end_sess:0,end_session_label:0,ending_cash:1,ending_exposur:1,enforc:0,engin:11,enh:3,enhanc:3,enigma:[1,4,5,6,7,10],enigmampc:[1,3],enough:[0,1,5,7],ensur:[0,4,7,8,9],ensure_directori:4,enter:[0,1,7],entir:3,entri:[1,7],env:[3,4,7],enviorn:2,environ:[0,1,4,7,10,13],environemnt:[1,7],eodcancel:0,equal:[0,1,2,4,8,13],equiti:[0,2],equival:[0,4,12],error:[0,1,3,4,5,7,8,10,12],especi:1,establish:6,estim:1,etc:[0,3,9,10],etc_btc:5,etc_eth:5,etc_usdt:5,eth:[1,8],eth_btc:[5,8],eth_usdt:[4,5],ethereum_bitcoin_asset:8,evalu:1,even:[0,2,7],event:[0,1],eventrul:0,eventu:1,everi:[0,1,4,7],every_dai:0,every_minut:0,everydai:4,everyth:[1,2],exact:[4,13],examin:1,exampl:[0,2,3,5,6,8,9,10,11,13],exceed:0,excel:7,except:[0,1,3,4],excess:4,exchang:[0,1,2,4,5,6,10,14],exchange_algorithm:1,exchange_ful:0,exchange_nam:[0,1,4,8,13],exchange_util:4,exclud:4,exclus:0,exe:1,execut:[0,1,4,7,8,10],execution_pric:0,execution_volum:0,executionstyl:0,exist:[0,2,3,4,5,6,7],exit:[0,1,4,9],exit_success:9,exp_btc:5,expect:[0,1,2,4,5,7,9],experi:7,experienc:7,expir:0,expiringcach:0,explain:[7,8],explan:0,explicitli:9,explictili:7,exposur:0,express:[1,4,6],extend:1,extens:[0,2,3,7,8],extern:[1,4,7],extra:9,extract_transact:[1,4],facto:1,fail:[0,1,2,7],failur:2,fairli:[1,3],fals:[0,1,4,8],familiar:3,fantast:1,faq:7,far:2,fast:2,fatal:7,fct_btc:5,featur:[1,4,6],fedora:7,fee:5,feedback:2,feel:1,fetch:[0,2,5,8,10,12],fetch_csv:0,few:[1,2,7,9],fewer:7,ffill:4,field:[0,2,4,9],file:[0,1,2,3,4,7,8,10,12],filenam:[1,4,13],fill:[0,1,4],fill_char:0,filter:[4,10],final_path:0,financ:[0,1],financi:[1,10],find:[1,2,7,9],finder:0,fine:9,finish:1,fire:0,firm:0,first:[0,2,3,4,7,8,9,14],first_trad:0,fix:[0,3,12],fixedslippag:0,flag:[1,4,7,8,9],flake8:3,flat:0,fldc_btc:5,flo_btc:5,floor:4,focu:[1,4,6],folder:[4,7,10],follow:[0,1,2,3,4,5,7,8,9,13],foo:0,footprint:7,forc:0,fork:11,form:[1,4,5],format:[0,1,2,4,9,10],fortran:7,forward:[0,2,12],foster:11,found:[0,1,3,5,7],fourth:[1,4],fraction:10,frame:[1,4],framework:7,free:[1,4],freelanc:11,freetyp:7,freq:[1,4],frequenc:[0,1,4,10,12],frequent:7,fresh:9,from:[0,1,2,3,4,5,7,8,9,10,12,13],from_dict:[0,4],full:[0,1,8,13],fulli:8,func:0,fund:11,fundament:11,further:[0,1,4],futur:[0,1,2,5],game_btc:5,gas_btc:5,gas_eth:5,gave:1,gcc:7,gcf:[1,4],gdax:8,gen:0,gen_type_stub:9,gener:[0,2,3,6,7,8,9,10,13],get:[0,1,2,3,4,5,6,8,10,13],get_calendar:0,get_environ:0,get_exchange_symbol:4,get_limit_pric:0,get_open_ord:[0,1,4],get_ord:0,get_spot_valu:0,get_stop_pric:0,get_ylim:[1,4],gettempdir:4,gfortran:7,git:9,github:[1,3,7,9],give:4,given:[0,1,2,4,5,13],global:1,gno_btc:5,gno_eth:5,gnt_btc:5,gnt_eth:5,goe:[4,8,14],going:[4,7,14],good:[1,9],goog:2,got:1,govern:4,gracefulli:10,grain:9,granular:[5,10],graph:1,grc_btc:5,greater:0,greatli:8,green:[1,4],group:[1,3],grow:2,guarante:0,guard:0,guid:[3,7,10],guidelin:[6,7,10],gzip:9,had:0,half:0,half_dai:0,hand:3,handi:[1,4,7],handl:[3,4,10],handle_data:[0,1,4,8,13],hang:7,happen:[0,1,2,8],happi:9,hard:1,has:[0,1,2,3,7,8,9,10],hash:10,have:[0,1,2,3,6,7,8,9,14],haven:1,head:[1,7],header:[7,9],heavi:[1,4],heavili:11,hedg:11,held:[0,5],help:[0,1,2],henc:1,here:[1,2,4,7,8],hidden:9,high:[0,1,4,8,11,13],highest:[4,9],highlight:4,hint:[7,9],histor:[1,4,5,6,8,10],histori:[0,2,4,10],hit:[1,10],hitchhik:7,hkey_local_machin:7,hold:[0,4,8],holidai:0,holidaycalendar:0,home:10,homebrew:7,hope:1,hopefulli:[4,14],hour:0,how:[0,1,2,4,7,8],howev:[7,8,9],html:[3,4,9],http:[1,4,8,9],huc_btc:5,idea:[1,2,3],ident:[0,7],identifi:0,idxmax:4,idxmin:4,ignore_exception_detail:0,illustr:8,iloc:4,imestamp:0,immedi:[1,4],impact:10,imper:3,implement:[1,2,4,10,14],impli:[0,4],implicitli:0,importerror:1,improv:[0,3,10],inadvert:7,inc:4,includ:[0,1,2,3,4,7,9,13],inclus:0,incomplet:2,inconsist:8,increas:[0,2,4,10],increment:[1,9],independ:[5,7],index:[0,1,3,4,9],indic:[0,2,4,7],individu:[1,8],ineffici:10,inf:4,infer:[0,2],infinit:4,influenc:1,info:[0,1,4,10],inform:[0,1,2,4,7,9],ingest:[4,5,10],initi:[0,1,4,8,10,13],inlin:1,inplac:3,input:[1,5,6],insert:4,insid:[1,4,7],insight:[1,6],inspect:[1,4],instal:[3,5,6,9,10],installt:7,instanc:[0,2,4,12],instanti:0,instead:[0,1,2,3,4,5,8,10],instruct:[1,3,7],integ:[0,2,10],integr:[0,5,6,8,10],intend:[1,3,9],interact:[1,8],interfac:[0,5,8,9,10,13],intern:[2,7],interpret:[1,4,13],interv:[4,12],introduc:[1,4,5,8,10],invalid:0,invest:[1,6],invok:[1,2],involv:[2,7],ipython:1,is_alive_for_sess:0,is_bui:[0,1,4],is_exchange_open:0,is_open_on_minut:0,is_sess:0,is_stal:0,isinst:4,isn:0,issu:[1,3,5,7,9,10],iter:[0,1,2,4,13],itercontext:0,its:[0,1,4,5,7,8],itself:[1,7],jan:1,join:[4,6,7],json:[8,10],json_symbol:4,juli:13,jump:7,jupyt:10,just:[0,1,2,4,5,9],keep:[1,2,4,7,10],kei:[0,2,6,7,8],kept:[1,8],keyerror:[0,10],keynam:0,kind:4,know:[0,1,7],knowledg:6,known:0,kpi:12,kwarg:[0,9],label:[0,1,4,8,9],lack:5,lambda:4,languag:4,lapack:7,larg:2,larger:10,last:[0,1,2,4,7,10,12],last_trad:0,later:[1,2,3,4],latest:[7,9,10],launch:[1,7],law:4,layer:5,lazi:2,lazili:0,lbc_btc:5,leak:2,learn:[1,4,6,7],least:[0,1,3,12],legend:[1,4],legend_:[1,4],len:[1,3,4],length:0,less:2,let:[1,4],level:[1,2,4],leverag:[0,1,4,11],lib:[3,4],libatla:7,libfreetype6:7,libgfortran:7,librari:[1,3,4,6,7,8,10,11],licens:4,lifetim:2,like:[0,1,2,3,5,6,7,9,10,12],limit:[0,1,4,5,10,12],limit_pric:[0,1,4],limitord:0,line:[3,4,5,13],linear:7,linter:9,linux:[1,5,9],list:[0,1,2,4,5,7,8,9,10,13],littl:[1,3],live:[0,1,4,5,6,7,10,11],live_algo:4,live_graph:4,load:[0,1,2,7],load_ext:1,loader:[1,2],loc:[1,4],local:[1,2,3,7,9],locat:[0,1,2,4,13],lock:0,log1p:10,log:[1,4,7,10],logbook:[1,4],logger:[1,4],logic:[1,4,10],long_mavg:[1,4],long_window:[1,4],longer:[1,3,9],look:[1,2,4,9,12,13],lookback:4,lookback_d:4,lookback_dai:4,lookup:[0,1],loop:2,loss:10,lot:[2,10],low:[0,1,4,8],lower:[4,8,10],lowercas:[5,8],lsk_btc:5,lsk_eth:5,ltc:8,ltc_btc:5,ltc_usd:[1,4],ltc_usdt:[4,5],ltc_xmr:5,mac:7,machin:[2,6,9],maco:[1,5],made:[0,2,3],magic:1,mai:[0,1,2,4,7,8,9],maid_btc:5,maid_xmr:5,main:[1,7,9],maint:3,maintain:[0,5,9],mainten:3,major:[0,9],make:[1,2,3,4,5,7,9],maker:0,manag:[0,1,4,7,9],mani:[0,1,2,4,7,9,11],manifest:9,manner:8,manual:[7,9],map:[0,2,5,10],marker:[1,4],markers:1,market:[0,1,4,5,6,8,10],market_clos:0,market_curr:[4,5],market_open:0,marketord:0,marketplac:[1,10],markowitz:4,mask:0,master:9,match:[1,7,8,9,12],matplotlib:[1,4,6,11],matplotlibrc:7,matrix:[4,9],matter:3,mavg:1,max:0,max_capital_us:3,max_count:0,max_leverag:[0,3],max_not:0,max_shar:0,max_sharpe_port:4,maxim:6,maximum:[0,4],maybe_show_progress:[0,2],mcoin:[1,4],mean:[0,1,2,7,9,10,14],mean_reversion_simpl:4,memori:[0,2],mention:[1,7,9],menu:7,merg:1,merger:[0,2],messag:[1,10],metadata:2,method:[0,1,2,4,7,9,10,12,13],metric:[1,10],micro:9,microsoft:7,midnight:[0,4],might:1,migrat:1,min:4,min_trade_cost:0,min_trade_s:0,min_vol_port:4,mind:[1,4],miniconda:7,minim:[4,6,10],minimum:[0,4,10],minor:[0,7,9],minut:[0,1,2,4,5,6,7,10,13],minute_end:0,minute_index_to_session_label:0,minute_to_session_label:0,minutes_count_for_sessions_in_rang:0,minutes_for_sess:0,minutes_for_sessions_in_rang:0,minutes_in_rang:0,miscellan:9,miss:[0,1,7,8,10],mix:7,mkdir:7,mkvirtualenv:3,mode:[0,1,4,5,6,10],model:[1,3,4,5],modif:[0,3,8],modifi:13,modul:[0,1],moment:[7,9],momentum:[1,4,14],mon:0,monei:0,month:[9,13],month_end:0,month_start:0,more:[0,1,2,4,6,7,8,10,13],most:[0,1,2,4,7,8,10],mostli:1,move:[0,2,9],movement:1,mpc:[1,4],msft:[0,2],msgpack:0,msi:7,msiexec:7,much:[0,1,2],multipl:[0,2,4,5,9,10],multiprocess:0,multithread:0,multupl:0,must:[1,2,8,9],mutabl:0,mutual:0,my_algo_cod:8,my_algo_nam:8,n_portfolio:4,name:[0,1,2,3,4,7,8,9,13],namedtemporaryfil:0,namespac:[1,4,9],nan:[0,1,4],nano:9,nanosecond:0,nasset:4,nat:0,nativ:7,naut_btc:5,nav_btc:5,navig:[3,7],nchang:4,ndarrai:[1,4],nearest:4,necessari:7,nee:7,need:[0,1,2,3,4,5,7,9,11,13],neg:[0,1],neo:4,neo_eth:[4,8],neo_ethereum_asset:8,neo_usd:4,neos_btc:5,never:[0,2,8],nevercancel:0,newer:[2,7],next:[0,2,7],next_clos:0,next_minut:0,next_open:0,next_session_label:0,nice:[5,6],nmc_btc:5,noebook:1,non:[0,7],none:[0,1,4,13],nor:4,normal:[0,10],note:[0,1,4,5,6,8,13],note_btc:5,notebook:10,noth:7,notic:4,notion:[0,4],novemb:9,now:[0,1,2,4,7,9,10,14],number:[0,1,2,4,7,9,10],numer:[0,7],numpi:[1,3,4,7,9,11],nvalu:4,nxc_btc:5,nxt_btc:5,nxt_usdt:5,nxt_xmr:5,nyse:0,obj:0,object:[1,2,3,4],observ:7,obtain:[1,4,8],occur:[1,3,8],off:11,offer:1,offset:[0,4],ohlc:1,ohlcv:[0,4,10,12],old:[0,9],older:[0,2],omg_btc:5,omg_eth:5,omni:5,omni_btc:5,on_error:0,onc:[0,1,2,4,7,8,9],one:[0,1,2,3,4,5,7,10,12,13],one_day_in_minut:4,ones:[0,4],onli:[0,1,2,3,4,6,7,9,13],open:[0,1,3,4,5,7,10,12,13],open_and_close_for_sess:0,open_ord:0,openssl:7,oper:7,operatbl:7,opportun:5,opt:4,optim:[1,11],option:[0,1,2,7,13],order:[1,4,5,7,8,9,10],order_id:[0,1],order_param:0,order_perc:0,order_target:0,order_target_perc:[0,1,4,8],order_target_valu:[0,1,4],order_valu:0,ordered_pip:3,org:[4,9],organ:1,origin:[1,4,9],osx:[7,9],other:[0,1,2,4,5,7,9,13],otherwis:7,our:[1,3,4,6,7,9,14],out:[0,1,2,3,4,6,7,9,12],outdat:7,outlin:7,output:[1,2,4,5,6],outsid:0,outstand:[1,4],over:[0,3,4,5,6,7],overcom:5,overfit:1,overrid:[7,9,10],overview:[1,5],overwhelm:1,overwritten:0,own:[2,4,7,8],p_r:4,p_std:4,packag:[1,3,7,11],packet:0,pacman:7,page:[3,5,7,9,10],pai:0,paid:0,pair:[0,1,4,5,8,10],pairon:4,panda:[0,1,2,4,5,6,11],pandasrequestscsv:0,panel:0,paper:[3,5,10],param:10,paramet:[1,4,8,9,10,13],parent:7,pares:0,pars:2,part:[0,1,2,4,7,8,14],partial:[7,12],particular:[6,7],pasc_btc:5,pass:[0,1,2,4,9],password:9,past:[1,4],patch:10,path:[0,2,4,7,10,13],pattern:12,pend:9,peopl:3,pep8:3,per:[0,1,2,4,5,10],percent:[0,1,4],percentag:[0,1,4],perdollar:0,perf:[0,1,3,4],perform:[0,1,3,4,5,6,7,10,11],perhap:7,period:[3,4],permiss:[4,7],pershar:0,persist:[1,4,10],pertrad:0,pickl:[0,1,4],piec:[2,7],pink_btc:5,pip:[1,3,9],pipelin:[5,10],pkg:7,place:[0,1,4,8,10],plan:5,platform:[0,7,10,11],pleas:[1,6,7,13],plot:[1,4,11],plt:[1,4],plu:13,point:[0,1,5,9],polici:7,poloniex:[1,4,5,6,8,10,13],popul:9,porfolio:0,portfolio:[0,1,10,13],portfolio_optim:4,portfolio_valu:[1,4],pos_amount:[1,4],posit:[0,1,4,10],positon:4,possibl:[0,2,3,7],post:9,post_func:0,postprocess:0,pot_btc:5,power:[1,4,11],ppc_btc:5,practic:[1,3],pre:[2,7],pre_func:0,precis:10,predict:[1,8],prefer:7,prefix:[3,7],preload:2,prepare_chunk:10,preprocess:[0,9],prerequisit:[1,7],present:[1,10],preserv:10,prevent:[2,7,9],previou:[0,7,14],previous:1,previous_clos:0,previous_minut:0,previous_open:0,previous_session_label:0,price:[0,2,4,5,6,8,10,13],price_chang:[1,4],price_impact:0,primari:7,print:[1,4,7,9],print_result:1,prior:[1,4],privileg:7,probabl:1,problem:[1,2,7,9],proce:7,proceed:7,process:[0,1,2,4,8],process_ord:0,produc:[2,4,7],profit:[1,6],program:7,progress:[0,2],project:[6,7,11],prompt:[1,7],proper:[7,8],properli:[1,4,7,13],protect:0,protocol:[0,1,5],provid:[0,1,2,4,5,6,7,8,10,11,13],publish:9,pull:[0,3,9],pun:1,purchas:[1,4],purpos:[1,5,8],push:9,put:[7,8],pycharm:9,pydata:[4,5,6],pyfolio:10,pypirc:9,pypitest:9,pyplot:[1,4],python2:[3,5,7,10],python3:[5,10],python:[0,1,3,4,6,7,10,11,13],pythonw:7,pytz:[4,13],quandl:0,quandl_api_kei:2,quandl_download_attempt:2,quantit:[1,11],quantopian:[0,4,11],queri:[0,2],queryabl:0,question:[1,3,6],quick:1,quickli:[4,14],quirk:7,quit:2,rads_btc:5,rais:[0,3,10],ran:2,random:[4,12],randomli:12,rang:[0,1,2,4,8,12],rate:[4,10],rather:[0,1,7],ratio:4,raw:[0,2,7],rdylgn:4,reach:[0,8],read:[0,1,2,7,10],read_csv:0,read_pickl:1,readi:9,real:[0,4,8],realist:[1,4],reason:[1,2,7],rebal:4,rebalanc:[1,4],rebalance_period:4,recal:1,receiv:[1,2],recent:[0,1,2,4,5,7],recogn:7,recommend:[2,7],reconcil:0,reconstruct:1,record:[0,1,4,13],red:[1,4],redhat:7,redon:10,redownload:[1,2],reduc:10,redund:10,refactor:3,refer:[1,3,4,5,7,8,9],referenc:[1,8],refus:1,regard:6,regardless:[1,7,8],regedit:7,regist:[0,1,2],register_calendar:0,register_calendar_typ:0,registri:7,regular:[0,7],regular_holidai:0,reinstal:7,reinvest:0,rel:3,relat:3,relationship:2,releas:[3,5,6,7],relev:0,reli:[7,11],remain:10,rememb:[1,7],remot:[0,2],remov:[1,3,4,7,9,10],renam:9,rep:7,rep_btc:5,rep_eth:5,rep_usdt:5,repeat:10,replac:[4,7],repo:7,report:[1,3,7],repositori:[7,9,10],repres:[0,2,8],represent:0,reproduc:2,req:10,request:[0,1,2,3,4,10],requests_csv:0,requir:[1,3,4,8,9],requirements_blaz:3,requirements_dev:3,requirements_doc:3,research:1,reserv:[1,4,5],reserve_ratio:[1,4],reserve_valu:[1,4],resolut:[1,4,5,6,10,13],resolv:[0,10],resourc:[2,6,10],respect:[3,9,13],respons:[0,2,7],rest:2,restart:10,restor:10,restrict:[0,7],restricted_list:0,restructuredtext:3,result:[0,1,2,4,7,8,12,13],results_arrai:4,results_fram:4,resum:4,retri:2,retriev:[0,1,4,10,12],rev:3,revers:[10,14],revert:3,review:[1,7],revis:1,rhel:7,ric_btc:5,ride:[4,14],right:7,risk:[1,4,10],roll:1,rollup:2,root:[3,9],round:10,rout:0,routin:7,row:[0,1,4],rsi:4,rsi_overbought:4,rsi_oversold:4,rst:[3,9],rule:0,run:[3,4,5,7,8,9,10,12,13],run_algo:[1,4,13],run_algorithm:[0,1,4,8,13],runtim:1,runtimeerror:7,safe:1,sai:0,said:1,same:[1,2,4,5,7,8,9,10,13],sampl:[4,10,12],satisfi:7,save:[1,2,3,4,7,13],sbd_btc:5,sc_btc:5,scalar:0,scale:[1,10],scatter:[1,4],schedule_funct:0,scientif:11,scikit:1,scipi:[4,6,7],scratch:7,script:[1,4,9,13],scriptnam:13,seamless:[5,6],search:7,second:[0,1,4,7,14],secret:8,section:[1,3,4,7,8,9,13],secur:[4,6,11],securitylist:0,see:[0,1,2,4,5,6,7,8,13],seek:7,seen:4,select:[4,7,12],self:[0,3],sell:[0,1,4,8,10,11,12,14],sell_df:[1,4],semant:0,sentinel:0,separ:[1,3,5,7,8],seper:8,seri:[0,1,4,14],serial:0,seriou:1,server:[1,2,9],servic:2,session:[0,7],session_dist:0,session_label:0,sessions_in_rang:0,sessions_window:0,set:[0,1,2,4,5,7,10],set_benchmark:[0,5],set_cancel_polici:0,set_commiss:0,set_do_not_order_list:0,set_long_onli:0,set_max_leverag:0,set_max_order_count:0,set_max_order_s:0,set_max_position_s:0,set_printopt:4,set_size_inch:[1,4],set_slippag:0,set_symbol_lookup_d:0,set_tick:[1,4],set_ylabel:[1,4],setup:[1,3,9],setuptool:7,seven:4,sever:[1,6,7],share:[0,1,5,6],sharex:[1,4],sharp:[1,4],ship:[2,7,9],short_exposur:1,short_mavg:[1,4],short_valu:1,short_window:[1,4],shorter:1,shorthand:0,shorts_count:1,should:[0,1,2,3,7,8,9,10],should_cancel:0,shourc:2,show:[0,1,2,4],show_progress:0,shown:[0,2],shutil:0,sid:[0,1,2,10],side:7,sidsnotfound:0,signal:[2,4],signatur:2,signific:4,sim_engin:0,similar:[1,7,8],similarli:0,simpl:[0,1,14],simple_univers:4,simpler:13,simplest:4,simpli:[1,3,4,7,13],simplic:4,simplifi:1,simul:[1,4,5,7,8],simulate_ord:[8,10],simulation_dt_func:0,simultan:10,sinc:[1,4,7,8,9,13],singl:[0,2,4,7,10],site:3,six:0,size:[0,4,7,10],sjcx_btc:5,skeleton:9,skim:1,skip:[1,4,10],sklearn:6,slighlti:4,slightli:7,slippag:[1,4,10],slippagemodel:0,smaller:[7,10],smoothli:14,snip:1,snippet:13,softwar:[4,7],sold:8,solut:7,solv:[1,2,7,10],some:[0,1,2,3,4,7,8,10,11],someon:7,someth:3,somewhat:1,sort:0,sortino:[1,10],sourc:[0,1,2,3,4,7,9,11],space:1,special:[0,8],special_clos:0,special_closes_adhoc:0,special_open:0,special_opens_adhoc:0,special_params_check:0,specif:[0,1,4,7,10],specifi:[0,1,2,4,5,8,9,10],spend:1,spent:5,sphinx:[3,9],split:[0,1,2,4],splitext:[4,13],spot:0,spread:0,spring:11,sqliteadjustmentwrit:2,sqrt:4,ssl:10,stabl:[4,7],stai:[9,10],standard:[0,2,3,4,5,10],star:4,start:[0,1,2,3,4,6,7,8,12,13],start_dat:[0,1,4],start_minut:0,start_sess:0,start_session_label:0,start_tim:4,starting_cash:[1,4],starting_exposur:1,starting_valu:1,stat:[4,10],state:[0,1,2,4,6,10],statist:[1,5,6,8,10],stats_util:[1,4],statsmodel:6,statu:4,std:4,stdev:4,stdout:1,steem_btc:5,steem_eth:5,step:[2,7],still:[1,2,4,5,7],stock:[1,2],stop:[0,1,4,10],stop_pric:0,stoplimitord:0,stopord:0,storag:[1,8,10],store:[0,1,2,4,5,13],str:[0,4],str_btc:5,str_usdt:5,straightforward:4,strat_btc:5,strategi:[1,4,6,8],stream:1,strftime:4,strict_extens:0,strictli:[0,2,7],string:[0,1,2,4,9],string_typ:0,strong:0,strongli:7,struct:0,structur:[5,6,8,11],sty:3,style:[0,3,4],subdirectori:2,subject:[0,3],submit:[3,4],subplot:[1,4],subset:4,substanti:1,subtract:0,succe:9,succeed:1,success:[2,3],successfulli:8,sudo:[1,7],suffici:7,suggest:3,sum:4,summar:7,summari:10,suppli:1,support:[0,1,4,5,6,7,9,10,12],suppos:1,suppress:4,sure:[4,7],surpris:1,suspect:3,symbol:[0,1,2,4,5,10,13],symbol_column:0,symbol_str:0,symbolnotfound:0,symbolnotfoundonexchang:5,sync:9,synchron:10,syntax:[0,9,10],sys:13,sys_btc:5,system:[0,1,3,6,7],t_price:4,t_val:4,tag:9,take:[0,1,2,7,10,14],taken:9,taker:0,talib:4,tar:9,tarbal:9,target:[0,1,8,12],target_hodl_ratio:[1,4],target_hodl_valu:[1,4],technic:[4,6],tell:0,tempfil:4,templat:9,temporari:[0,9],ten:1,tend:8,tens:3,tent:10,term:1,termin:[1,4,7],test:[0,1,3,7,8,9,10,11],testpypi:9,tether:5,text:1,than:[0,1,2,3,7,8,10],thank:4,thei:[0,1,2,9,10,11],them:[0,1,3,7,9],therefor:9,therein:7,thi:[0,1,2,3,4,5,7,8,9,13,14],thing:14,think:8,third:[1,4],thorough:7,those:[0,1,3,4,8,9],though:2,thread:0,three:[0,1,2,4,5,6,8],threshold:[1,4],through:[1,2,5,7],throughli:8,throughout:1,thu:[1,4,7],tick:4,tick_siz:1,ticker:[0,2,10],time:[0,1,2,4,6,7,8,9,13],time_rul:0,timedelta:[0,4],timefram:10,timeperiod:4,timeseri:4,timestamp:[0,1,2,10],timestr:4,timezon:0,titl:9,tkagg:7,tminus_pric:4,tminus_v:4,tmp_dir:0,to_csv:[4,13],to_datetim:[1,4],to_dict:0,to_pydatetim:[1,4],todai:[4,9],togeth:1,token:[4,8,13],tolist:4,tool:[2,3,7,9,11],top:[1,6,9],total:[0,2],toward:1,traceback:[0,5],track:[0,1,3,4,10],tracker:[1,5],trade:[1,4,5,6,7,10,11,13],traded_todai:4,trader:[1,11],trading_dai:1,tradingalgorithm:[0,9],tradingcalendar:[0,2],tradingcontrolexcept:0,tradingpair:12,tradingsimul:0,tradit:1,train:1,tran:[1,4],transact:[0,1,4,8,10],transaction:2,transaction_df:[1,4],transfer:5,transform:1,transit:[5,6],transpos:4,travi:9,treasuri:[1,4],treasury_period_return:[1,4],treat:0,trend:1,tri:[1,6],trigger:[0,4],trip:10,tst:3,tue:0,tupl:[0,2],turn:9,tutori:[4,6,7,8],tweak:1,twice:9,two:[0,1,4,5,6,7,8,12,13,14],twoargument:1,txt:[3,7,9],type:[0,4,7,9],typo:3,tzinfo:0,ubuntu:[1,7],uncompress:10,under:[1,2,4,7,8,9],underli:[0,1],underlin:9,underscor:5,understand:[1,7],undesir:0,unexpect:7,uninstal:7,uniqu:0,unit:[1,5,10],univers:[0,1,8],universe_func:0,unknown:1,unless:4,unlik:2,unpack:7,unresolv:10,unsupport:10,untar:2,until:[1,4,7],unus:3,unwrap:0,updat:[1,4,10],upgrad:[7,9,10],upper:[1,4],upward:1,url:[0,9],usag:1,usd:[1,4,5],usdt:[4,5,13],usdt_btc:1,usdt_btc_benchmark:1,use:[0,1,2,3,4,5,6,7,8,9,10,11,13],used:[0,1,2,3,4,7,8],useful:[0,7],user:[1,2,4,5,6,7,9],usernam:9,uses:[0,1,2,5,8],using:[2,3,4,5,7,8,9,10,12,13,14],usr:4,usual:[0,1],utc:[0,1,4,13],util:[1,2,3,4,6],utilit:13,val:0,valid:[0,10],valu:[0,1,4,7,8,10],valueerror:0,vari:[4,7,8,13],variabl:[1,2,4,8,13],varianc:4,varieti:13,variou:[1,2,4],varnam:1,vcforpython27:7,venv:7,veri:[0,1,2,4,7,9],verifi:[7,9],versatil:13,version:[0,1,3,4,5,7,8,9,13],via:[1,5,7],via_btc:5,viabl:5,victori:5,video:[4,6,10],view:[3,9],virtual:7,virtualenv:9,virtualenvwrapp:3,visit:[4,6],visual:[1,4,6,7],vix:0,volatil:4,volum:[0,1,4,5,6,10,12,13],volume_limit:0,volumeshareslippag:[0,1],vrc_btc:5,vtc_btc:5,wai:[1,2,4,6,7],wait:[1,4],want:[0,1,2,3,4,5,7],warn:[0,1,9,10],warn_on_cancel:0,warrant:0,warranti:4,wave:[4,14],web:[5,9],websit:6,wed:0,week_end:0,week_start:0,weekdai:0,weight:4,welcom:3,well:[1,2,6,7],were:[3,4,9],what:[0,1,3,4,5,7,8,9],whatev:2,whatsnew:9,wheel:[7,9],when:[0,1,2,3,4,7,8,9,14],where:[1,2,3,4,5,6,7,8,10,13,14],whether:0,which:[0,1,2,3,4,5,7,8,9,10,13],whitepap:11,whitespac:3,who:3,whole:1,whose:0,why:3,width:9,win:9,window:[0,1,4,5,10],within:[1,7,8],without:[1,2,4,7,8,10],work:[2,3,4,7,8,9,10],workaround:10,workflow:7,working_dir:0,working_fil:0,world:1,wors:1,worth:1,would:[0,1,2,4,7,9],wouldlik:1,wrap:[0,9],writ:4,write:[1,4,8,13],writer:[2,3,13],writerow:13,written:[0,1,2,5,6],wrong:5,www:4,xbc_btc:5,xbt:8,xcp_btc:5,xem_btc:5,xlabel:4,xmr_btc:5,xmr_usdt:[4,5],xpm_btc:5,xrang:4,xrp_btc:5,xrp_usdt:5,xvc_btc:5,yahoo_equ:2,yaxi:[1,4],year:9,yet:[0,1],ylabel:4,yml:[7,10],you:[1,2,3,4,5,6,7,8,9,13],your:[1,2,3,4,5,6,7,8,9,11,13],yourself:3,yum:7,zec_btc:5,zec_eth:5,zec_usdt:5,zec_xmr:5,zero:[3,4],ziplin:[0,2,3,6,9,11],zipline_root:[2,9],zlib:7,zrx_btc:5,zrx_eth:5},titles:["API Reference","Catalyst Beginner Tutorial","Data Bundles","Development Guidelines","Example Algorithms","Features","Overview","Install","Live Trading","Release Process","Release Notes","Resources","Unit Tests","Utilities","Videos"],titleterms:{"3rd":11,"default":2,"function":[0,5],"new":2,__version__:9,access:1,adjustment_writ:2,algo:12,algorithm:[0,1,4,8],amazon:7,ami:7,api:[0,11],asset:0,asset_db_writ:2,authent:[8,12],avail:2,averag:[1,4],backtest:[0,2,14],basic:1,bdist:9,beginn:1,branch:3,btc:4,bug:10,bui:4,build:10,bundl:[2,12],cach:[0,2],calendar:[0,2],cancel:0,catalyst:[1,7],command:[0,1],commiss:0,commit:[3,9],conda:[7,9],content:6,contribut:3,control:0,convent:5,creat:3,cross:1,crossov:4,csv:[12,13],currenc:8,current:[5,12],daily_bar_writ:2,data:[0,1,2,12,13],dev1:10,dev2:10,dev3:10,dev4:10,dev5:10,dev6:10,dev7:10,dev8:10,dev9:10,develop:3,discov:2,doc:3,docker:3,docstr:3,document:[9,10],dual:[1,4],end_sess:2,environ:[2,3],exampl:[1,4],exchang:[8,12],extract:13,factori:2,featur:5,file:[9,13],first:1,fix:10,format:3,get:7,git:3,gnu:7,guidelin:3,help:7,histor:12,histori:1,hodl:4,ingest:[1,2,12],instal:[1,7,14],interfac:1,jupyt:1,line:[0,1],linux:7,live:[8,14],maco:[7,14],market:[12,13],matplotlib:7,mean:4,messag:3,metadata:0,minute_bar_writ:2,mirror:2,miscellan:0,mode:8,model:0,move:[1,4],name:5,next:[1,9],note:[7,9,10],notebook:1,object:0,old:2,optim:4,order:[0,12],output:13,output_dir:2,over:1,overview:[4,6],packag:9,paper:8,paramet:0,parti:11,pip:7,pipelin:0,pipenv:7,polici:0,portfolio:4,previou:1,price:[1,12],process:9,pypi:9,python:9,quandl:2,quantopian:2,refer:0,relat:11,releas:[9,10],requir:7,resourc:11,revers:4,run:[0,1,2],schedul:0,sdist:9,show_progress:2,simpl:4,simul:0,slippag:0,start_sess:2,stat:12,step:1,strategi:14,structur:3,stub:9,support:8,symbol:8,tabl:6,test:12,ticker:12,trade:[0,8,14],troubleshoot:7,tutori:1,unit:12,univers:4,upcom:5,updat:[7,9],upload:9,using:1,util:[0,13],valid:12,version:10,video:14,virtualenv:7,wiki:2,window:[7,14],work:1,write:2,yahoo:2}}) \ No newline at end of file +Search.setIndex({envversion:47,filenames:["appendix","beginner-tutorial","bundles","development-guidelines","example-algos","features","index","install","live-trading","release-process","releases","resources","unit-tests","utilities","videos"],objects:{"catalyst.api":{EODCancel:[0,0,1,""],NeverCancel:[0,0,1,""],cancel_order:[0,0,1,""],date_rules:[0,1,1,""],fetch_csv:[0,0,1,""],get_environment:[0,0,1,""],get_open_orders:[0,0,1,""],get_order:[0,0,1,""],order:[0,0,1,""],order_percent:[0,0,1,""],order_target:[0,0,1,""],order_target_percent:[0,0,1,""],order_target_value:[0,0,1,""],order_value:[0,0,1,""],record:[0,0,1,""],schedule_function:[0,0,1,""],set_benchmark:[0,0,1,""],set_cancel_policy:[0,0,1,""],set_commission:[0,0,1,""],set_do_not_order_list:[0,0,1,""],set_long_only:[0,0,1,""],set_max_leverage:[0,0,1,""],set_max_order_count:[0,0,1,""],set_max_order_size:[0,0,1,""],set_max_position_size:[0,0,1,""],set_slippage:[0,0,1,""],set_symbol_lookup_date:[0,0,1,""],sid:[0,0,1,""],symbol:[0,0,1,""],symbols:[0,0,1,""],time_rules:[0,1,1,""]},"catalyst.api.date_rules":{every_day:[0,3,1,""],month_end:[0,4,1,""],month_start:[0,4,1,""],week_end:[0,4,1,""],week_start:[0,4,1,""]},"catalyst.api.time_rules":{every_minute:[0,3,1,""],market_close:[0,3,1,""],market_open:[0,3,1,""]},"catalyst.assets":{Asset:[0,1,1,""],AssetConvertible:[0,1,1,""]},"catalyst.assets.Asset":{first_traded:[0,3,1,""],from_dict:[0,2,1,""],is_alive_for_session:[0,2,1,""],is_exchange_open:[0,2,1,""],to_dict:[0,2,1,""]},"catalyst.finance.cancel_policy":{CancelPolicy:[0,1,1,""]},"catalyst.finance.cancel_policy.CancelPolicy":{should_cancel:[0,2,1,""]},"catalyst.finance.commission":{CommissionModel:[0,1,1,""],PerDollar:[0,1,1,""],PerShare:[0,1,1,""],PerTrade:[0,1,1,""]},"catalyst.finance.commission.CommissionModel":{calculate:[0,2,1,""]},"catalyst.finance.execution":{ExecutionStyle:[0,1,1,""],LimitOrder:[0,1,1,""],MarketOrder:[0,1,1,""],StopLimitOrder:[0,1,1,""],StopOrder:[0,1,1,""]},"catalyst.finance.execution.ExecutionStyle":{exchange:[0,3,1,""],get_limit_price:[0,2,1,""],get_stop_price:[0,2,1,""]},"catalyst.finance.slippage":{FixedSlippage:[0,1,1,""],SlippageModel:[0,1,1,""],VolumeShareSlippage:[0,1,1,""]},"catalyst.finance.slippage.SlippageModel":{process_order:[0,2,1,""]},"catalyst.protocol":{BarData:[0,1,1,""]},"catalyst.protocol.BarData":{can_trade:[0,2,1,""],current:[0,2,1,""],history:[0,2,1,""],is_stale:[0,2,1,""]},"catalyst.utils.cache":{CachedObject:[0,1,1,""],ExpiringCache:[0,1,1,""],dataframe_cache:[0,1,1,""],working_dir:[0,1,1,""],working_file:[0,1,1,""]},"catalyst.utils.calendars":{TradingCalendar:[0,1,1,""],clear_calendars:[0,0,1,""],deregister_calendar:[0,0,1,""],get_calendar:[0,0,1,""],register_calendar:[0,0,1,""],register_calendar_type:[0,0,1,""]},"catalyst.utils.calendars.TradingCalendar":{is_open_on_minute:[0,2,1,""],is_session:[0,2,1,""],minute_index_to_session_labels:[0,2,1,""],minute_to_session_label:[0,2,1,""],minutes_count_for_sessions_in_range:[0,2,1,""],minutes_for_session:[0,2,1,""],minutes_for_sessions_in_range:[0,2,1,""],minutes_in_range:[0,2,1,""],next_close:[0,2,1,""],next_minute:[0,2,1,""],next_open:[0,2,1,""],next_session_label:[0,2,1,""],open_and_close_for_session:[0,2,1,""],previous_close:[0,2,1,""],previous_minute:[0,2,1,""],previous_open:[0,2,1,""],previous_session_label:[0,2,1,""],regular_holidays:[0,3,1,""],session_distance:[0,2,1,""],sessions_in_range:[0,2,1,""],sessions_window:[0,2,1,""],special_closes:[0,3,1,""],special_closes_adhoc:[0,3,1,""],special_opens:[0,3,1,""],special_opens_adhoc:[0,3,1,""]},"catalyst.utils.cli":{maybe_show_progress:[0,0,1,""]},catalyst:{run_algorithm:[0,0,1,""]}},objnames:{"0":["py","function","Python function"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","staticmethod","Python static method"]},objtypes:{"0":"py:function","1":"py:class","2":"py:method","3":"py:attribute","4":"py:staticmethod"},terms:{"000000e":1,"1000th":1,"15t":4,"1st":1,"30t":4,"328842e":1,"340mb":10,"380954e":1,"40mb":10,"460mb":10,"505275d6646a41f3856b22b16678d":1,"536708e":1,"5min":[1,4],"650729e":1,"7869f7828fa140328eb40477bb7d":1,"998236e":1,"998677e":1,"999120e":1,"999558e":1,"99mb":10,"__del__":0,"__exit__":0,"__file__":[4,13],"__future__":4,"__getitem__":0,"__main__":[1,4],"__name__":[1,4],"__setitem__":0,"__wrapped__":9,"_html_base":3,"_tkinter":1,"abstract":0,"boolean":[0,2,8],"break":7,"case":[0,1,2,3,7,13],"class":[0,3,9],"default":[0,1],"enum":0,"export":9,"final":[1,2,3],"float":[0,1,10],"import":[0,1,2,4,9,13],"int":[0,2],"long":[1,2,4],"new":[0,1],"null":12,"public":10,"return":[0,1,4,8,9,10,11],"short":[0,1,3,4],"static":[0,9],"switch":8,"throw":10,"true":[0,1,4,8,10],"try":[3,4,7],"var":1,"while":[5,7,9,10],aapl:2,abc:0,abil:[2,10],abl:[1,2,7],abner:4,about:[0,1,2,6,7],abov:[0,1,3,4,5,7,8,9],absolut:0,abstractholidaycalendar:0,accept:[0,2,7,9],access:0,accord:[0,9],accordingli:[1,4],account:[0,1,2,4,6,10],acevedo:4,acquir:[2,7],across:[5,6,10],activ:[7,8,9],actual:[0,1],add:[1,2,3,7,9,13],addit:[0,1,3,5,6,7,10],addition:8,address:9,adjust:[0,2,4,10],administr:7,advantag:7,afford:[1,4],aforement:1,after:[0,1,2,4,7,9],afteropen:0,again:[1,3],against:[1,6,8,10,14],agre:4,ahead:1,aim:[4,11],algebra:[4,7],algo:[0,1,2,4,10],algo_namespac:[1,4,8],algo_volatil:1,algofil:[1,2],algorithm_period_return:[1,4],algotext:1,alia:[0,4],alias:[4,10],aliv:0,all:[0,1,2,3,4,5,6,7,8,9,10,12],alloc:0,allow:[0,1,2,5,6,7],almost:7,along:[0,2],alongsid:1,alpha:[1,4,7,8],alreadi:[0,1,2,3,7],also:[0,1,2,3,4,6,7,8,9],altern:[1,5,7],although:1,alwai:[0,2,5,8,9],amount:[0,1,4,8,10],amount_charg:0,amp_btc:5,ana:7,anaconda:[1,7,9],analog:1,analysi:[1,4,6,9,10,11],analyst:11,analyt:[6,7],analyz:[0,1,4,8,10,13],ani:[0,1,2,4,5,7,8,9,13],anonym:2,anoth:[1,2,4,5],anymor:1,anyth:[1,7,9],apach:4,app:7,appar:1,appear:[0,2,9],append:9,appli:[0,1,4],applic:[1,4],appropri:[1,3,4],approxim:[1,4],appveyor:9,apt:[1,7],arang:[1,4],arbitrag:5,arbitrari:[8,10],arbitrarili:1,arch:7,architectur:1,ardr_btc:5,arena:0,arg:[0,1,9],argument:[0,1,2,8,9],argv:13,around:[6,9],arrai:[4,7],art:6,articl:[3,4],ask:[1,3],asmatrix:4,assert:[3,12],assertionerror:3,assess:1,asset_nam:[0,1,4],asset_restrict:0,assetconvert:0,assetdbwrit:2,assign:[1,8],assimil:1,assist:7,assum:[1,3,4,7],astyp:4,atla:7,attach:0,attempt:[0,2,8],attribut:[0,4,9],auth:[8,10],auto:10,auto_close_d:0,automag:7,automat:0,avail:[0,1],avoid:[1,2,4],awai:7,awar:[0,9],ax1:[1,4],ax2:[1,4],ax3:[1,4],ax4:[1,4],ax5:[1,4],ax6:[1,4],axhlin:4,axi:[0,4],ayala:4,back:[0,3,5,7],backbon:4,backend:7,backward:0,bah:4,bar:[0,1,4,10],bar_count:[0,1,4],bar_templ:0,bardata:0,base:[0,1,2,4,5,6,7,8,14],base_curr:[1,4,5,8,13],base_pric:[1,4],basenam:[4,13],basi:[4,10],batch:7,batteri:1,battl:7,bch_btc:5,bch_eth:5,bch_usdt:5,bcn_btc:5,bcn_xmr:5,bcolz:2,bcolzdailybarread:2,bcolzdailybarwrit:2,bcolzminutebarread:2,bcolzminutebarwrit:2,bcy_btc:5,be62ff77760c4599abaac43be9cc9:1,bear:[1,4],beautifi:1,becaus:[0,1,7,9,10],been:[0,1,2,7,9],befor:[0,1,2,4,7,8,10],before_trading_start:[0,4],beforeclos:0,beggin:4,begin:[0,1,4,7],behavior:0,bela_btc:5,believ:1,below:[0,1,3,4,13],benchmark:[0,1,4,5,6,10],benchmark_period_return:[1,4],benchmark_volatil:1,benefit:1,best:[3,6,7],beta:[1,4],better:[0,1],between:[0,1,3,4,5,6,10,12],beyond:5,bfill:4,bia:1,big:7,bin:[4,7],binanc:[8,10],binari:[7,9],bit:[3,7],bitcoin:[1,4,5,6,8,13],bitcoin_usd_asset:8,bitfinex:[1,4,5,6,8,10],bitmex:8,bittrex:[1,4,5,6,8,10,14],blank:12,bld:3,blk_btc:5,blk_xmr:5,blockchain:5,blotter:13,blue:1,bodi:3,book:1,bool:0,both:[0,1,3,5,8,9,12],bought:[1,8],bound:[0,1],boundari:0,breakdown:8,brew:7,brother:7,brows:7,browser:[1,3,9],btc:1,btc_usd:[1,4,5,8],btc_usdt:[4,5,6,10,13],btcd_btc:5,btcd_xmr:5,btm_btc:5,bts_btc:5,bug:[0,2,3],bui:[0,1],build:[0,1,3,6,7,9],build_ext:3,built:[4,9,12],bundl:[0,1],bundle_timestamp:0,burst_btc:5,button:[7,9],buy_and_hodl:[4,10],buy_btc_simpl:[1,4],buy_btc_simple_out:[1,4],buy_df:[1,4],buy_low_sell_high:10,cachedobject:0,cal_nam:0,calcul:[0,1,3,4,8,12],calendar_typ:0,calendarnamecollis:0,call:[0,1,2,3,4,10],callabl:0,callback:0,can:[0,1,2,3,4,5,6,7,8,9,10,13],can_trad:[0,1,4,10],cancel_ord:[0,1,4],cancel_polici:0,cancelpolici:0,candl:[1,5,10,12],candle_s:4,candlestick:4,cannot:[0,1,4,7],canon:3,capabl:10,capit:[0,1,4],capital_bas:[0,1,4,8,10,13],capital_us:1,captur:1,cash:[1,2,3,4,10],catalyst:0,catalyst_dev:[1,6,7],catalyst_root:0,caus:[0,1,2,3],ccxt:[8,10],cell:1,cert:10,certian:0,chanc:1,chang:[0,1,3,4,6,7,9,10],channel:[1,6,7],charact:3,charg:[0,1],chart:[1,4,7],check:[0,1,2,3,4,5,7,8],checker:9,checkout:[3,9],choic:9,choos:[1,4,5,7,9,13],chosen:[1,13],chunk:[0,1,10],circumv:7,clam_btc:5,classic:[1,4],classifi:1,clean:[0,2,7,9,10,12],clean_on_failur:0,clear:2,clear_calendar:0,cli:[0,1,4,10,13],click:[0,7,9],client:8,clone:3,close:[0,1,4,5,13],cmap:4,cmd:[1,7],cme:0,code:[0,1,4,7,9,10,13],codebas:3,codifi:0,coin:[1,4,10],collect:[1,2,4],collis:0,color:[1,4],colorbar:4,colour:4,column:[0,1,2,4],com:[1,2,3,8],combin:[0,7,8],come:[2,7],comment:1,commissionmodel:0,commit:0,common:[0,1],commonli:1,commun:[5,7,11],comp:4,compar:[1,4,5,6,7,12],comparison:10,compat:[0,6,10],compil:[7,9,10],complement:4,complet:8,complex:[1,7],complianc:4,complimentari:13,comprehens:10,compress:[1,10],comput:[1,4,7,10,11],concept:[0,1],conda:1,conda_build_matrix:9,condit:[0,4],confid:8,config:7,configur:[1,7,10],congratul:7,consecut:0,consid:[0,1,4],consist:[1,5,12],constant:1,constraint:2,consum:9,contain:[0,1,2,3,4,7,12],content:1,context:[0,1,3,4,10,13],contigu:0,continu:1,continuum:7,contract:0,conveni:[0,1],convent:4,convers:2,convert:[0,2,4],copi:[1,2,3,4,9],copy_tre:0,copyright:4,core:7,corr_m:4,correct:[2,7,8,9],correctli:[1,7,9],correctwai:7,correl:4,correspond:[0,1,7,8,13],cost:[0,1,4],could:[0,1,2,4,7,13],count:[0,2],counter:4,coupl:1,cov_m:4,covari:4,cover:[0,1,4,8,13],coverag:[5,6,8],cpython:7,crash:2,creat:[1,2],creation:10,credit:4,critic:5,cross:0,crossov:1,crowd:11,crypto:[1,6,10],cryptoasset:[1,4,13,14],cryptocurr:[4,5,8],csv:[0,1,4,10],csv_data_sourc:0,csvfile:13,csvwriter:13,cumul:10,cumulative_capital_us:3,curat:[1,6],currenc:[1,4],current:[0,1,2,4],current_d:4,current_dai:4,current_dt:[4,13],current_valu:0,custom:[1,2,5,13],cvc_btc:5,cvc_eth:5,cython:9,d6dca79513214346a646079213526:1,dai:[0,1,2,4,7,9],daili:[0,1,2,4,5,6,10,13],darkgoldenrod:4,dash:8,dash_btc:5,dash_usdt:[4,5],dash_xmr:5,data_frequ:[0,1,4,13],data_port:0,databas:2,datafram:[0,1,2,4,5,6,11,12,13],dataframe_cach:[0,2],dataport:0,dataset:[1,2,5],date:[0,1,2,4,7,9,10,12,13],date_column:0,date_format:0,date_rul:0,datetim:[0,4,13],datetimeindex:0,day_end:0,day_start:0,days_offset:0,dcr_btc:5,debian:[1,7],debug:9,decentr:5,decid:9,decim:[0,10],decor:9,decreas:4,def:[1,4,13],default_extens:0,defin:[0,1,4,8],delai:1,delet:[0,2],delist:0,demonstr:1,denomin:1,dep:3,depart_docu:3,depend:[0,1,3,7,9,10,13],deploi:9,deprec:3,deregist:0,deregister_calendar:0,deriv:7,describ:[0,5],descript:[3,7],desir:[0,1,4,12,13],desktop:5,detail:[4,5],determin:[0,4],dev1:7,dev2:7,dev3:7,dev4:7,dev5:7,dev6:7,dev8:7,dev9:7,dev:[3,5,7],devel:7,develop:1,deviat:4,devis:1,dgb_btc:5,dict:[0,10],dict_:0,dictionari:[0,10],did:[6,7],didn:7,differ:[0,1,2,4,5,7,8,9,13],dimension:0,dir:7,dir_util:0,direct:0,directli:[1,2,7,10,13],directori:[0,1,2,3,4,7,8,9],disabl:10,disablemsi:7,discard:4,discord:[1,3,6,7],discuss:1,disk:[0,10],dismiss:1,displai:[1,4,7,9,10],dist:9,distanc:0,distinguish:0,distribut:[4,7,9],distutil:9,divid:[0,3],dividend:[0,2],divis:4,dma:1,dname:1,dnf:7,doc:2,dockerfil:3,doctest:0,document:[3,4,5,6,7,8],docutil:3,doe:[0,1,2,4,5,7],doesn:[0,2],doge_btc:5,dollar:[0,5],don:[0,1,3,7,14],done:[1,4,9],door:5,dot:[0,4],down:[1,4,14],downgrad:3,download:[1,2,7,10],draft:9,drawback:2,drive:1,driven:[1,6,8],drop:0,dropbox:10,dt_minut:0,dual_moving_averag:[1,4],due:0,dure:0,dword:7,dynam:4,each:[0,1,2,3,4,5,6,7,8,10,12,13],earlier:[1,2,3,4],earliest:4,eas:6,easi:[1,2,4,11],easier:[1,2,4,5,7],easiest:7,easili:[1,6,7],eastern:0,echo:7,eco:6,ecosystem:5,edit:[3,4,7,9],editor:7,educ:1,educt:1,effect:7,either:[0,1,4,7],elaps:4,element:[0,4],elif:[1,4],els:[4,7],emc2_btc:5,empow:[1,6],empti:[1,2,3,4,8,9,10],empty_char:0,empyr:10,enabl:8,encapsul:0,encount:7,encourag:8,end:[0,1,4,10,12,13],end_daili:4,end_dat:[0,1,4],end_minut:0,end_sess:0,end_session_label:0,ending_cash:1,ending_exposur:1,enforc:0,engin:11,enh:3,enhanc:3,enigma:[1,4,5,6,7,10],enigmampc:[1,3],enough:[0,1,5,7],ensur:[0,4,7,8,9],ensure_directori:4,enter:[0,1,7],entir:3,entri:[1,7],env:[3,4,7],enviorn:2,environ:[0,1],environemnt:[1,7],eodcancel:0,equal:[0,1,2,4,8,13],equiti:[0,2],equival:[0,4,12],error:[0,1,3,4,5,7,8,10,12],especi:1,establish:6,estim:1,etc:[0,3,9,10],etc_btc:5,etc_eth:5,etc_usdt:5,eth:[1,8],eth_btc:[5,8],eth_usdt:[4,5],ethereum_bitcoin_asset:8,evalu:1,even:[0,2,7],event:[0,1],eventrul:0,eventu:1,everi:[0,1,4,7],every_dai:0,every_minut:0,everydai:4,everyth:[1,2],exact:[4,13],examin:1,exampl:0,exceed:0,excel:7,except:[0,1,3,4],excess:4,exchang:[0,1,2,4,5,6],exchange_algorithm:1,exchange_ful:0,exchange_nam:[0,1,4,8,13],exchange_util:4,exclud:4,exclus:0,execut:[0,1,4,7,8,10],execution_pric:0,execution_volum:0,executionstyl:0,exist:[0,2,3,4,5,6,7],exit:[0,1,4,9],exit_success:9,exp_btc:5,expect:[0,1,2,4,5,7,9],experi:7,experienc:7,expir:0,expiringcach:0,explain:[7,8],explan:0,explicitli:9,explictili:7,exposur:0,express:[1,4,6],extend:1,extens:[0,2,3,7,8],extern:[1,4,7],extra:9,extract_transact:[1,4],facto:1,fail:[0,1,2,7],failur:2,fairli:[1,3],fals:[0,1,4,8],familiar:3,fantast:1,faq:7,far:2,fast:2,fatal:7,fct_btc:5,featur:[1,4],fedora:7,fee:5,feedback:2,feel:1,fetch:[0,2,5,8,10,12],fetch_csv:0,few:[1,2,7,9],fewer:7,ffill:4,field:[0,2,4,9],file:[0,1,2,3,4,7,8],filenam:[1,4,13],fill:[0,1,4],fill_char:0,filter:[4,10],final_path:0,financ:[0,1],financi:[1,10],find:[1,2,7,9],finder:0,fine:9,finish:1,fire:0,firm:0,first:0,first_trad:0,fix:[0,3],fixedslippag:0,flag:[1,4,7,8,9],flake8:3,flat:0,fldc_btc:5,flo_btc:5,floor:4,focu:[1,4,6],folder:[4,7,10],follow:[0,1,2,3,4,5,7,8,9,13],foo:0,footprint:7,forc:0,fork:11,form:[1,4,5],format:[0,1,2],fortran:7,forward:[0,2,12],foster:11,found:[0,1,3,5,7],fourth:[1,4],fraction:10,frame:[1,4],framework:7,free:[1,4],freelanc:11,freetyp:7,freq:[1,4],frequenc:[0,1,4,10,12],frequent:7,fresh:9,from:[0,1,2,3,4,5,7,8,9,10,12,13],from_dict:[0,4],full:[0,1,8,13],fulli:8,func:0,fund:11,fundament:11,further:[0,1,4],futur:[0,1,2,5],game_btc:5,gas_btc:5,gas_eth:5,gave:1,gcc:7,gcf:[1,4],gdax:8,gen:0,gen_type_stub:9,gener:[0,2,3,6,7,8,9,10,13],get:[0,1,2,3,4,5,6],get_calendar:0,get_environ:0,get_exchange_symbol:4,get_limit_pric:0,get_open_ord:[0,1,4],get_ord:0,get_spot_valu:0,get_stop_pric:0,get_ylim:[1,4],gettempdir:4,gfortran:7,github:[1,3,7,9],give:4,given:[0,1,2,4,5,13],global:1,gno_btc:5,gno_eth:5,gnt_btc:5,gnt_eth:5,goe:[4,8,14],good:[1,9],goog:2,got:1,govern:4,gracefulli:10,grain:9,granular:[5,10],graph:1,grc_btc:5,greater:0,greatli:8,green:[1,4],group:[1,3],grow:2,guarante:0,guard:0,guid:[3,7,10],gzip:9,had:0,half:0,half_dai:0,hand:3,handi:[1,4,7],handl:[3,4,10],handle_data:[0,1,4,8,13],hang:7,happen:[0,1,2,8],happi:9,hard:1,hash:10,have:[0,1,2,3,6,7,8,9,14],haven:1,head:[1,7],header:[7,9],heavi:[1,4],heavili:11,hedg:11,held:[0,5],help:[0,1,2],henc:1,here:[1,2,4,7,8],hidden:9,high:[0,1,4,8,11,13],highest:[4,9],highlight:4,hint:[7,9],histor:[1,4,5,6,8,10],histori:0,hit:[1,10],hitchhik:7,hkey_local_machin:7,hold:[0,4,8],holidai:0,holidaycalendar:0,home:10,homebrew:7,hope:1,hopefulli:[4,14],hour:0,how:[0,1,2,4,7,8],howev:[7,8,9],html:[3,4,9],http:[1,4,8,9],huc_btc:5,idea:[1,2,3],ident:[0,7],identifi:0,idxmax:4,idxmin:4,ignore_exception_detail:0,illustr:8,iloc:4,imestamp:0,immedi:[1,4],impact:10,imper:3,implement:[1,2,4,10,14],impli:[0,4],implicitli:0,importerror:1,improv:[0,3,10],inadvert:7,inc:4,includ:[0,1,2,3,4,7,9,13],inclus:0,incomplet:2,inconsist:8,increas:[0,2,4,10],increment:[1,9],independ:[5,7],index:[0,1,3,4,9],indic:[0,2,4,7],individu:[1,8],ineffici:10,inf:4,infer:[0,2],infinit:4,influenc:1,info:[0,1,4,10],inform:[0,1,2,4,7,9],initi:[0,1,4,8,10,13],inlin:1,inplac:3,input:[1,5,6],insert:4,insid:[1,4,7],insight:[1,6],inspect:[1,4],installt:7,instanc:[0,2,4,12],instanti:0,instead:[0,1,2,3,4,5,8,10],instruct:[1,3,7],integ:[0,2,10],integr:[0,5,6,8,10],intend:[1,3,9],interact:[1,8],interfac:0,intern:[2,7],interpret:[1,4,13],interv:[4,12],introduc:[1,4,5,8,10],invalid:0,invest:[1,6],invok:[1,2],involv:[2,7],ipython:1,is_alive_for_sess:0,is_bui:[0,1,4],is_exchange_open:0,is_open_on_minut:0,is_sess:0,is_stal:0,isinst:4,isn:0,issu:[1,3,5,7,9,10],iter:[0,1,2,4,13],itercontext:0,itself:[1,7],jan:1,join:[4,6,7],json:[8,10],json_symbol:4,juli:13,jump:7,just:[0,1,2,4,5,9],keep:[1,2,4,7,10],kei:[0,2,6,7,8],kept:[1,8],keyerror:[0,10],keynam:0,kind:4,know:[0,1,7],knowledg:6,known:0,kpi:12,kwarg:[0,9],label:[0,1,4,8,9],lack:5,lambda:4,languag:4,lapack:7,larg:2,larger:10,last:[0,1,2,4,7,10,12],last_trad:0,later:[1,2,3,4],latest:[7,9,10],launch:[1,7],law:4,layer:5,lazi:2,lazili:0,lbc_btc:5,leak:2,learn:[1,4,6,7],least:[0,1,3,12],legend:[1,4],legend_:[1,4],len:[1,3,4],length:0,less:2,let:[1,4],level:[1,2,4],leverag:[0,1,4,11],lib:[3,4],libatla:7,libfreetype6:7,libgfortran:7,librari:[1,3,4,6,7,8,10,11],licens:4,lifetim:2,like:[0,1,2,3,5,6,7,9,10,12],limit:[0,1,4,5,10,12],limit_pric:[0,1,4],limitord:0,linear:7,linter:9,linux:[1,5],list:[0,1,2,4,5,7,8,9,10,13],littl:[1,3],live:[0,1,4,5,6,7],live_algo:4,live_graph:4,load:[0,1,2,7],load_ext:1,loader:[1,2],loc:[1,4],local:[1,2,3,7,9],locat:[0,1,2,4,13],lock:0,log1p:10,log:[1,4,7,10],logbook:[1,4],logger:[1,4],logic:[1,4,10],long_mavg:[1,4],long_window:[1,4],longer:[1,3,9],look:[1,2,4,9,12,13],lookback:4,lookback_d:4,lookback_dai:4,lookup:[0,1],loop:2,loss:10,lot:[2,10],low:[0,1,4,8],lower:[4,8,10],lowercas:[5,8],lsk_btc:5,lsk_eth:5,ltc:8,ltc_btc:5,ltc_usd:[1,4],ltc_usdt:[4,5],ltc_xmr:5,mac:7,machin:[2,6,9],maco:[1,5],made:[0,2,3],magic:1,mai:[0,1,2,4,7,8,9],maid_btc:5,maid_xmr:5,main:[1,7,9],maint:3,maintain:[0,5,9],mainten:3,major:[0,9],make:[1,2,3,4,5,7,9],maker:0,manag:[0,1,4,7,9],mani:[0,1,2,4,7,9,11],manifest:9,manner:8,manual:[7,9],map:[0,2,5,10],marker:[1,4],markers:1,market:[0,1,4,5,6,8,10],market_clos:0,market_curr:[4,5],market_open:0,marketord:0,marketplac:[1,10],markowitz:4,mask:0,master:9,match:[1,7,8,9,12],matplotlib:[1,4,6],matplotlibrc:7,matrix:[4,9],matter:3,mavg:1,max:0,max_capital_us:3,max_count:0,max_leverag:[0,3],max_not:0,max_shar:0,max_sharpe_port:4,maxim:6,maximum:[0,4],maybe_show_progress:[0,2],mcoin:[1,4],mean:[0,1,2],mean_reversion_simpl:4,memori:[0,2],mention:[1,7,9],menu:7,merg:1,merger:[0,2],messag:1,method:[0,1,2,4,7,9,10,12,13],metric:[1,10],micro:9,microsoft:7,midnight:[0,4],might:1,migrat:1,min:4,min_trade_cost:0,min_trade_s:0,min_vol_port:4,mind:[1,4],miniconda:7,minim:[4,6,10],minimum:[0,4,10],minor:[0,7,9],minut:[0,1,2,4,5,6,7,10,13],minute_end:0,minute_index_to_session_label:0,minute_to_session_label:0,minutes_count_for_sessions_in_rang:0,minutes_for_sess:0,minutes_for_sessions_in_rang:0,minutes_in_rang:0,miss:[0,1,7,8,10],mix:7,mkdir:7,mkvirtualenv:3,mode:[0,1,4,5,6],modif:[0,3,8],modifi:13,modul:[0,1],moment:[7,9],momentum:[1,4,14],mon:0,monei:0,month:[9,13],month_end:0,month_start:0,more:[0,1,2,4,6,7,8,10,13],most:[0,1,2,4,7,8,10],mostli:1,move:0,movement:1,mpc:[1,4],msft:[0,2],msgpack:0,msi:7,msiexec:7,much:[0,1,2],multipl:[0,2,4,5,9,10],multiprocess:0,multithread:0,multupl:0,must:[1,2,8,9],mutabl:0,mutual:0,my_algo_cod:8,my_algo_nam:8,n_portfolio:4,name:[0,1,2,3,4],namedtemporaryfil:0,namespac:[1,4,9],nan:[0,1,4],nano:9,nanosecond:0,nasset:4,nat:0,nativ:7,naut_btc:5,nav_btc:5,navig:[3,7],nchang:4,ndarrai:[1,4],nearest:4,necessari:7,nee:7,need:[0,1,2,3,4,5,7,9,11,13],neg:[0,1],neo:4,neo_eth:[4,8],neo_ethereum_asset:8,neo_usd:4,neos_btc:5,never:[0,2,8],nevercancel:0,newer:[2,7],next:0,next_clos:0,next_minut:0,next_open:0,next_session_label:0,nice:[5,6],nmc_btc:5,noebook:1,non:[0,7],none:[0,1,4,13],nor:4,normal:[0,10],note:[0,1,4,5,6],note_btc:5,noth:7,notic:4,notion:[0,4],novemb:9,now:[0,1,2,4,7,9,10,14],number:[0,1,2,4,7,9,10],numer:[0,7],numpi:[1,3,4,7,9,11],nvalu:4,nxc_btc:5,nxt_btc:5,nxt_usdt:5,nxt_xmr:5,nyse:0,obj:0,observ:7,obtain:[1,4,8],occur:[1,3,8],off:11,offer:1,offset:[0,4],ohlc:1,ohlcv:[0,4,10,12],old:0,older:[0,2],omg_btc:5,omg_eth:5,omni:5,omni_btc:5,on_error:0,onc:[0,1,2,4,7,8,9],one_day_in_minut:4,onli:[0,1,2,3,4,6,7,9,13],open:[0,1,3,4,5,7,10,12,13],open_and_close_for_sess:0,open_ord:0,openssl:7,oper:7,operatbl:7,opportun:5,opt:4,optim:1,option:[0,1,2,7,13],order_id:[0,1],order_param:0,order_perc:0,order_target:0,order_target_perc:[0,1,4,8],order_target_valu:[0,1,4],order_valu:0,ordered_pip:3,org:[4,9],organ:1,origin:[1,4,9],osx:[7,9],other:[0,1,2,4,5,7,9,13],otherwis:7,our:[1,3,4,6,7,9,14],out:[0,1,2,3,4,6,7,9,12],outdat:7,outlin:7,output:[1,2,4,5,6],outsid:0,outstand:[1,4],over:0,overcom:5,overfit:1,overrid:[7,9,10],overview:1,overwhelm:1,overwritten:0,own:[2,4,7,8],p_r:4,p_std:4,packag:[1,3,7],packet:0,pacman:7,page:[3,5,7,9,10],pai:0,paid:0,pair:[0,1,4,5,8,10],pairon:4,panda:[0,1,2,4,5,6,11],pandasrequestscsv:0,panel:0,paper:[3,5],param:10,parent:7,pares:0,pars:2,part:[0,1,2,4,7,8,14],partial:[7,12],particular:[6,7],pasc_btc:5,pass:[0,1,2,4,9],password:9,past:[1,4],patch:10,path:[0,2,4,7,10,13],pattern:12,pend:9,peopl:3,pep8:3,per:[0,1,2,4,5,10],percent:[0,1,4],percentag:[0,1,4],perdollar:0,perf:[0,1,3,4],perform:[0,1,3,4,5,6,7,10,11],perhap:7,period:[3,4],permiss:[4,7],pershar:0,persist:[1,4,10],pertrad:0,pickl:[0,1,4],piec:[2,7],pink_btc:5,pip:[1,3],pkg:7,place:[0,1,4,8,10],plan:5,platform:[0,7,10,11],pleas:[1,6,7,13],plot:[1,4,11],plt:[1,4],plu:13,point:[0,1,5,9],poloniex:[1,4,5,6,8,10,13],popul:9,porfolio:0,portfolio:[0,1],portfolio_optim:4,portfolio_valu:[1,4],pos_amount:[1,4],posit:[0,1,4,10],positon:4,possibl:[0,2,3,7],post:9,post_func:0,postprocess:0,pot_btc:5,power:[1,4,11],ppc_btc:5,practic:[1,3],pre:[2,7],pre_func:0,precis:10,predict:[1,8],prefer:7,prefix:[3,7],preload:2,prepare_chunk:10,preprocess:[0,9],prerequisit:[1,7],present:[1,10],preserv:10,prevent:[2,7,9],previou:0,previous:1,previous_clos:0,previous_minut:0,previous_open:0,previous_session_label:0,price:0,price_chang:[1,4],price_impact:0,primari:7,print:[1,4,7,9],print_result:1,prior:[1,4],privileg:7,probabl:1,problem:[1,2,7,9],proce:7,proceed:7,process:[0,1,2,4,8],process_ord:0,produc:[2,4,7],profit:[1,6],program:7,progress:[0,2],project:[6,7,11],prompt:[1,7],proper:[7,8],properli:[1,4,7,13],protect:0,protocol:[0,1,5],provid:[0,1,2,4,5,6,7,8,10,11,13],publish:9,pull:[0,3,9],pun:1,purchas:[1,4],purpos:[1,5,8],push:9,put:[7,8],pycharm:9,pydata:[4,5,6],pyfolio:10,pypirc:9,pypitest:9,pyplot:[1,4],python2:[3,5,7,10],python3:[5,10],python:[0,1,3,4,6,7],pythonw:7,pytz:[4,13],quandl:0,quandl_api_kei:2,quandl_download_attempt:2,quantit:[1,11],quantopian:0,queri:[0,2],queryabl:0,question:[1,3,6],quick:1,quickli:[4,14],quirk:7,quit:2,rads_btc:5,rais:[0,3,10],ran:2,random:[4,12],randomli:12,rang:[0,1,2,4,8,12],rate:[4,10],rather:[0,1,7],ratio:4,raw:[0,2,7],rdylgn:4,reach:[0,8],read:[0,1,2,7,10],read_csv:0,read_pickl:1,readi:9,real:[0,4,8],realist:[1,4],reason:[1,2,7],rebal:4,rebalanc:[1,4],rebalance_period:4,recal:1,receiv:[1,2],recent:[0,1,2,4,5,7],recogn:7,recommend:[2,7],reconcil:0,reconstruct:1,record:[0,1,4,13],red:[1,4],redhat:7,redon:10,redownload:[1,2],reduc:10,redund:10,refactor:3,referenc:[1,8],refus:1,regard:6,regardless:[1,7,8],regedit:7,regist:[0,1,2],register_calendar:0,register_calendar_typ:0,registri:7,regular:[0,7],regular_holidai:0,reinstal:7,reinvest:0,rel:3,relat:3,relationship:2,releas:[3,5,6,7],relev:0,reli:[7,11],remain:10,rememb:[1,7],remot:[0,2],remov:[1,3,4,7,9,10],renam:9,rep:7,rep_btc:5,rep_eth:5,rep_usdt:5,repeat:10,replac:[4,7],repo:7,report:[1,3,7],repositori:[7,9,10],repres:[0,2,8],represent:0,reproduc:2,req:10,request:[0,1,2,3,4,10],requests_csv:0,requir:[1,3,4],requirements_blaz:3,requirements_dev:3,requirements_doc:3,research:1,reserv:[1,4,5],reserve_ratio:[1,4],reserve_valu:[1,4],resolut:[1,4,5,6,10,13],resolv:[0,10],resourc:[2,6,10],respect:[3,9,13],respons:[0,2,7],rest:2,restart:10,restor:10,restrict:[0,7],restricted_list:0,restructuredtext:3,result:[0,1,2,4,7,8,12,13],results_arrai:4,results_fram:4,resum:4,retri:2,retriev:[0,1,4,10,12],rev:3,revert:3,review:[1,7],revis:1,rhel:7,ric_btc:5,ride:[4,14],right:7,risk:[1,4,10],roll:1,rollup:2,root:[3,9],round:10,rout:0,routin:7,row:[0,1,4],rsi:4,rsi_overbought:4,rsi_oversold:4,rst:[3,9],rule:0,run_algo:[1,4,13],run_algorithm:[0,1,4,8,13],runtim:1,runtimeerror:7,safe:1,sai:0,said:1,same:[1,2,4,5,7,8,9,10,13],sampl:[4,10,12],satisfi:7,save:[1,2,3,4,7,13],sbd_btc:5,sc_btc:5,scalar:0,scale:[1,10],scatter:[1,4],schedule_funct:0,scientif:11,scikit:1,scipi:[4,6,7],scratch:7,script:[1,4,9,13],scriptnam:13,seamless:[5,6],search:7,second:[0,1,4,7,14],secret:8,section:[1,3,4,7,8,9,13],secur:[4,6,11],securitylist:0,see:[0,1,2,4,5,6,7,8,13],seek:7,seen:4,select:[4,7,12],self:[0,3],sell:[0,1,4,8,10,11,12,14],sell_df:[1,4],semant:0,sentinel:0,separ:[1,3,5,7,8],seper:8,seri:[0,1,4,14],serial:0,seriou:1,server:[1,2,9],servic:2,session:[0,7],session_dist:0,session_label:0,sessions_in_rang:0,sessions_window:0,set:[0,1,2,4,5,7,10],set_benchmark:[0,5],set_cancel_polici:0,set_commiss:0,set_do_not_order_list:0,set_long_onli:0,set_max_leverag:0,set_max_order_count:0,set_max_order_s:0,set_max_position_s:0,set_printopt:4,set_size_inch:[1,4],set_slippag:0,set_symbol_lookup_d:0,set_tick:[1,4],set_ylabel:[1,4],setup:[1,3,9],setuptool:7,seven:4,sever:[1,6,7],share:[0,1,5,6],sharex:[1,4],sharp:[1,4],ship:[2,7,9],short_exposur:1,short_mavg:[1,4],short_valu:1,short_window:[1,4],shorter:1,shorthand:0,shorts_count:1,should:[0,1,2,3,7,8,9,10],should_cancel:0,shourc:2,show:[0,1,2,4],show_progress:0,shown:[0,2],shutil:0,sid:[0,1,2,10],side:7,sidsnotfound:0,signal:[2,4],signatur:2,signific:4,sim_engin:0,similar:[1,7,8],similarli:0,simpl:[0,1],simple_univers:4,simpler:13,simplest:4,simpli:[1,3,4,7,13],simplic:4,simplifi:1,simulate_ord:[8,10],simulation_dt_func:0,simultan:10,sinc:[1,4,7,8,9,13],singl:[0,2,4,7,10],site:3,six:0,size:[0,4,7,10],sjcx_btc:5,skeleton:9,skim:1,skip:[1,4,10],sklearn:6,slighlti:4,slightli:7,slippagemodel:0,smaller:[7,10],smoothli:14,snip:1,snippet:13,softwar:[4,7],sold:8,solut:7,solv:[1,2,7,10],some:[0,1,2,3,4,7,8,10,11],someon:7,someth:3,somewhat:1,sort:0,sortino:[1,10],sourc:[0,1,2,3,4,7,9,11],space:1,special:[0,8],special_clos:0,special_closes_adhoc:0,special_open:0,special_opens_adhoc:0,special_params_check:0,specif:[0,1,4,7,10],specifi:[0,1,2,4,5,8,9,10],spend:1,spent:5,sphinx:[3,9],split:[0,1,2,4],splitext:[4,13],spot:0,spread:0,spring:11,sqliteadjustmentwrit:2,sqrt:4,ssl:10,stabl:[4,7],stai:[9,10],standard:[0,2,3,4,5,10],star:4,start:[0,1,2,3,4,6,7,8,12,13],start_dat:[0,1,4],start_minut:0,start_sess:0,start_session_label:0,start_tim:4,starting_cash:[1,4],starting_exposur:1,starting_valu:1,stat:[4,10],state:[0,1,2,4,6,10],statist:[1,5,6,8,10],stats_util:[1,4],statsmodel:6,statu:4,std:4,stdev:4,stdout:1,steem_btc:5,steem_eth:5,still:[1,2,4,5,7],stock:[1,2],stop:[0,1,4,10],stop_pric:0,stoplimitord:0,stopord:0,storag:[1,8,10],store:[0,1,2,4,5,13],str:[0,4],str_btc:5,str_usdt:5,straightforward:4,strat_btc:5,strategi:[1,4,6,8],stream:1,strftime:4,strict_extens:0,strictli:[0,2,7],string:[0,1,2,4,9],string_typ:0,strong:0,strongli:7,struct:0,sty:3,style:[0,3,4],subdirectori:2,subject:[0,3],submit:[3,4],subplot:[1,4],subset:4,substanti:1,subtract:0,succe:9,succeed:1,success:[2,3],successfulli:8,sudo:[1,7],suffici:7,suggest:3,sum:4,summar:7,summari:10,suppli:1,support:[0,1,4,5,6,7],suppos:1,suppress:4,sure:[4,7],surpris:1,suspect:3,symbol:[0,1,2,4,5],symbol_column:0,symbol_str:0,symbolnotfound:0,symbolnotfoundonexchang:5,sync:9,synchron:10,syntax:[0,9,10],sys_btc:5,system:[0,1,3,6,7],t_price:4,t_val:4,tag:9,take:[0,1,2,7,10,14],taken:9,taker:0,talib:4,tar:9,tarbal:9,target:[0,1,8,12],target_hodl_ratio:[1,4],target_hodl_valu:[1,4],technic:[4,6],tell:0,tempfil:4,templat:9,temporari:[0,9],ten:1,tend:8,tens:3,tent:10,term:1,termin:[1,4,7],test:[0,1,3,7,8,9,10,11],testpypi:9,tether:5,text:1,than:[0,1,2,3,7,8,10],thank:4,thei:[0,1,2,9,10,11],them:[0,1,3,7,9],therefor:9,therein:7,thi:[0,1,2,3,4,5,7,8,9,13,14],thing:14,think:8,third:[1,4],thorough:7,those:[0,1,3,4,8,9],though:2,thread:0,three:[0,1,2,4,5,6,8],threshold:[1,4],through:[1,2,5,7],throughli:8,throughout:1,thu:[1,4,7],tick:4,tick_siz:1,ticker:[0,2,10],time:[0,1,2,4,6,7,8,9,13],time_rul:0,timedelta:[0,4],timefram:10,timeperiod:4,timeseri:4,timestamp:[0,1,2,10],timestr:4,timezon:0,titl:9,tkagg:7,tminus_pric:4,tminus_v:4,tmp_dir:0,to_csv:[4,13],to_datetim:[1,4],to_dict:0,to_pydatetim:[1,4],todai:[4,9],togeth:1,token:[4,8,13],tolist:4,tool:[2,3,7,9,11],top:[1,6,9],total:[0,2],toward:1,traceback:[0,5],track:[0,1,3,4,10],tracker:[1,5],traded_todai:4,trader:[1,11],trading_dai:1,tradingalgorithm:[0,9],tradingcalendar:[0,2],tradingcontrolexcept:0,tradingpair:12,tradingsimul:0,tradit:1,train:1,tran:[1,4],transact:[0,1,4,8,10],transaction:2,transaction_df:[1,4],transfer:5,transform:1,transit:[5,6],transpos:4,travi:9,treasuri:[1,4],treasury_period_return:[1,4],treat:0,trend:1,tri:[1,6],trigger:[0,4],trip:10,tst:3,tue:0,tupl:[0,2],turn:9,tweak:1,twice:9,two:[0,1,4,5,6,7,8,12,13,14],twoargument:1,txt:[3,7,9],type:[0,4,7,9],typo:3,tzinfo:0,ubuntu:[1,7],uncompress:10,under:[1,2,4,7,8,9],underli:[0,1],underlin:9,underscor:5,understand:[1,7],undesir:0,unexpect:7,uninstal:7,uniqu:0,unit:[1,5,10],univers:[0,1],universe_func:0,unknown:1,unless:4,unlik:2,unpack:7,unresolv:10,unsupport:10,untar:2,until:[1,4,7],unus:3,unwrap:0,updat:[1,4],upgrad:[7,9,10],upper:[1,4],upward:1,url:[0,9],usag:1,usd:[1,4,5],usdt:[4,5,13],usdt_btc:1,usdt_btc_benchmark:1,user:[1,2,4,5,6,7,9],usernam:9,usr:4,usual:[0,1],utc:[0,1,4,13],utilit:13,val:0,valid:[0,10],valu:[0,1,4,7,8,10],valueerror:0,vari:[4,7,8,13],variabl:[1,2,4,8,13],varianc:4,varieti:13,variou:[1,2,4],varnam:1,vcforpython27:7,venv:7,veri:[0,1,2,4,7,9],verifi:[7,9],versatil:13,version:[0,1,3,4,5,7,8,9],via:[1,5,7],via_btc:5,viabl:5,victori:5,video:[4,6,10],view:[3,9],virtual:7,virtualenvwrapp:3,visit:[4,6],visual:[1,4,6,7],vix:0,volatil:4,volum:[0,1,4,5,6,10,12,13],volume_limit:0,volumeshareslippag:[0,1],vrc_btc:5,vtc_btc:5,wai:[1,2,4,6,7],wait:[1,4],want:[0,1,2,3,4,5,7],warn:[0,1,9,10],warn_on_cancel:0,warrant:0,warranti:4,wave:[4,14],web:[5,9],websit:6,wed:0,week_end:0,week_start:0,weekdai:0,weight:4,welcom:3,well:[1,2,6,7],were:[3,4,9],what:[0,1,3,4,5,7,8,9],whatev:2,whatsnew:9,wheel:[7,9],when:[0,1,2,3,4,7,8,9,14],where:[1,2,3,4,5,6,7,8,10,13,14],whether:0,which:[0,1,2,3,4,5,7,8,9,10,13],whitepap:11,whitespac:3,who:3,whole:1,whose:0,why:3,width:9,win:9,window:[0,1,4,5],within:[1,7,8],without:[1,2,4,7,8,10],workaround:10,workflow:7,working_dir:0,working_fil:0,world:1,wors:1,worth:1,would:[0,1,2,4,7,9],wouldlik:1,wrap:[0,9],writ:4,write:1,writer:[2,3,13],writerow:13,written:[0,1,2,5,6],wrong:5,www:4,xbc_btc:5,xbt:8,xcp_btc:5,xem_btc:5,xlabel:4,xmr_btc:5,xmr_usdt:[4,5],xpm_btc:5,xrang:4,xrp_btc:5,xrp_usdt:5,xvc_btc:5,yahoo_equ:2,yaxi:[1,4],year:9,yet:[0,1],ylabel:4,yml:[7,10],you:[1,2,3,4,5,6,7,8,9,13],your:[1,2,3,4,5,6,7,8,9,11,13],yourself:3,yum:7,zec_btc:5,zec_eth:5,zec_usdt:5,zec_xmr:5,zero:[3,4],ziplin:[0,2,3,6,9,11],zipline_root:[2,9],zlib:7,zrx_btc:5,zrx_eth:5},titles:["API Reference","Catalyst Beginner Tutorial","Data Bundles","Development Guidelines","Example Algorithms","Features","Overview","Install","Live Trading","Release Process","Release Notes","Resources","Unit Tests","Utilities","Videos"],titleterms:{"3rd":11,"__version__":9,"default":2,"function":[0,5],"new":2,access:1,adjustment_writ:2,algo:12,algorithm:[0,1,4,8],amazon:7,ami:7,api:[0,11],asset:0,asset_db_writ:2,authent:[8,12],avail:2,averag:[1,4],backtest:[0,2,14],basic:1,bdist:9,beginn:1,branch:3,btc:4,bug:10,bui:4,build:10,bundl:[2,12],cach:[0,2],calendar:[0,2],cancel:0,catalyst:[1,7],command:[0,1],commiss:0,commit:[3,9],conda:[7,9],content:6,contribut:3,control:0,convent:5,creat:3,cross:1,crossov:4,csv:[12,13],currenc:8,current:[5,12],daily_bar_writ:2,data:[0,1,2,12,13],dev1:10,dev2:10,dev3:10,dev4:10,dev5:10,dev6:10,dev7:10,dev8:10,dev9:10,develop:3,discov:2,doc:3,docker:3,docstr:3,document:[9,10],dual:[1,4],end_sess:2,environ:[2,3],exampl:[1,4],exchang:[8,12],extract:13,factori:2,featur:5,file:[9,13],first:1,fix:10,format:3,get:7,git:3,gnu:7,guidelin:3,help:7,histor:12,histori:1,hodl:4,ingest:[1,2,12],instal:[1,7,14],interfac:1,jupyt:1,line:[0,1],linux:7,live:[8,14],maco:[7,14],market:[12,13],matplotlib:7,mean:4,messag:3,metadata:0,minute_bar_writ:2,mirror:2,miscellan:0,mode:8,model:0,move:[1,4],name:5,next:[1,9],note:[7,9,10],notebook:1,object:0,old:2,optim:4,order:[0,12],output:13,output_dir:2,over:1,overview:[4,6],packag:9,paper:8,paramet:0,parti:11,pip:7,pipelin:0,pipenv:7,polici:0,portfolio:4,previou:1,price:[1,12],process:9,pypi:9,python:9,quandl:2,quantopian:2,refer:0,relat:11,releas:[9,10],requir:7,resourc:11,revers:4,run:[0,1,2],schedul:0,sdist:9,show_progress:2,simpl:4,simul:0,slippag:0,start_sess:2,stat:12,step:1,strategi:14,structur:3,stub:9,support:8,symbol:8,tabl:6,test:12,ticker:12,trade:[0,8,14],troubleshoot:7,tutori:1,unit:12,univers:4,upcom:5,updat:[7,9],upload:9,util:[0,13],valid:12,version:10,video:14,virtualenv:7,wiki:2,window:[7,14],work:1,write:2,yahoo:2}}) \ No newline at end of file diff --git a/utilities.html b/utilities.html index 2c826593..0d9ea686 100644 --- a/utilities.html +++ b/utilities.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
                          - - - - - - - - - - - - - - - - -
                          - +
                          - -
                          -
                          -
                          +

                          Utilities

                          @@ -180,25 +319,25 @@ script that you need to use depends on the interface that you are using to run your trading algorithm, which could be the CLI or a Python Interpreter.

                          1. Script to use with CLI:

                            -
                            def analyze(context=None, results=None):
                            +
                            def analyze(context=None, results=None):
                                 import sys
                                 import os
                                 from os.path import basename
                             
                            -    # Save results in CSV file
                            +    # Save results in CSV file
                                 filename = os.path.splitext(basename(sys.argv[3]))[0]
                            -    results.to_csv(filename + '.csv')
                            +    results.to_csv(filename + '.csv')
                             
                          2. Script to use with Python Interpreter:

                            -
                            def analyze(context=None, results=None):
                            +
                            def analyze(context=None, results=None):
                                 import os
                                 from os.path import basename
                             
                            -    # Save results in CSV file
                            -    filename = os.path.splitext(os.path.basename(__file__))[0]
                            -    results.to_csv(filename + '.csv')
                            +    # Save results in CSV file
                            +    filename = os.path.splitext(os.path.basename(__file__))[0]
                            +    results.to_csv(filename + '.csv')
                             
                          3. @@ -208,12 +347,12 @@ your trading algorithm, which could be the CLI or a Python Interpreter.

                            Extracting market data

                            Use this script to save the price and volume data of one cryptoasset in a CSV file, which will be saved in the same location and with the same name as your -Python file. To get custom data, simply modify the asset’s symbol and the dates. +Python file. To get custom data, simply modify the asset’s symbol and the dates. Run this script directly from your development environment: python scriptname.py, -where the contents of ‘scriptname.py’ are as follows. Two different version are +where the contents of ‘scriptname.py’ are as follows. Two different version are provided as an example for daily- and minute-resolution data respectively:

                            Simpler case for daily data

                            -
                            import os
                            +
                            import os
                             import pytz
                             from datetime import datetime
                             
                            @@ -221,23 +360,23 @@ provided as an example for daily- and minute-resolution data respectively:

                            from catalyst.utils.run_algo import run_algorithm def initialize(context): - # Portfolio assets list - context.asset = symbol('btc_usdt') # Bitcoin on Poloniex + # Portfolio assets list + context.asset = symbol('btc_usdt') # Bitcoin on Poloniex def handle_data(context, data): - # Variables to record for a given asset: price and volume - price = data.current(context.asset, 'price') - volume = data.current(context.asset, 'volume') + # Variables to record for a given asset: price and volume + price = data.current(context.asset, 'price') + volume = data.current(context.asset, 'volume') record(price=price, volume=volume) def analyze(context=None, results=None): - # Generate DataFrame with Price and Volume only - data = results[['price','volume']] + # Generate DataFrame with Price and Volume only + data = results[['price','volume']] - # Save results in CSV file - filename = os.path.splitext(os.path.basename(__file__))[0] - data.to_csv(filename + '.csv') + # Save results in CSV file + filename = os.path.splitext(os.path.basename(__file__))[0] + data.to_csv(filename + '.csv') ''' Bitcoin data is available on Poloniex since 2015-3-1. Dates vary for other tokens. In the example below, we choose the @@ -250,13 +389,13 @@ provided as an example for daily- and minute-resolution data respectively:

                            analyze=analyze, start=start, end=end, - exchange_name='poloniex', + exchange_name='poloniex', capital_base=10000, - base_currency = 'usdt') + base_currency = 'usdt')

                            More versatile case for minute data

                            -
                            import os
                            +
                            import os
                             import csv
                             import pytz
                             from datetime import datetime
                            @@ -266,31 +405,31 @@ provided as an example for daily- and minute-resolution data respectively:

                            def initialize(context): -# Portfolio assets list -context.asset = symbol('btc_usdt') # Bitcoin on Poloniex +# Portfolio assets list +context.asset = symbol('btc_usdt') # Bitcoin on Poloniex -# Creates a .CSV file with the same name as this script to store results +# Creates a .CSV file with the same name as this script to store results context.csvfile = open(os.path.splitext( - os.path.basename(__file__))[0]+'.csv', 'w+') + os.path.basename(__file__))[0]+'.csv', 'w+') context.csvwriter = csv.writer(context.csvfile) def handle_data(context, data): -# Variables to record for a given asset: price and volume -# Other options include 'open', 'high', 'open', 'close' -# Please note that 'price' equals 'close' -date = context.blotter.current_dt # current time in each iteration -price = data.current(context.asset, 'price') -volume = data.current(context.asset, 'volume') +# Variables to record for a given asset: price and volume +# Other options include 'open', 'high', 'open', 'close' +# Please note that 'price' equals 'close' +date = context.blotter.current_dt # current time in each iteration +price = data.current(context.asset, 'price') +volume = data.current(context.asset, 'volume') -# Writes one line to CSV on each iteration with the chosen variables +# Writes one line to CSV on each iteration with the chosen variables context.csvwriter.writerow([date,price,volume]) def analyze(context=None, results=None): -# Close open file properly at the end +# Close open file properly at the end context.csvfile.close() -# Bitcoin data is available from 2015-3-2. Dates vary for other tokens. +# Bitcoin data is available from 2015-3-2. Dates vary for other tokens. start = datetime(2017, 7, 30, 0, 0, 0, 0, pytz.utc) end = datetime(2017, 7, 31, 0, 0, 0, 0, pytz.utc) results = run_algorithm(initialize=initialize, @@ -298,9 +437,9 @@ provided as an example for daily- and minute-resolution data respectively:

                            analyze=analyze, start=start, end=end, - exchange_name='poloniex', - data_frequency='minute', - base_currency ='usdt', + exchange_name='poloniex', + data_frequency='minute', + base_currency ='usdt', capital_base=10000 )
                            @@ -308,19 +447,15 @@ provided as an example for daily- and minute-resolution data respectively:

                            -
                            -
                            - -
                            @@ -354,8 +488,7 @@ provided as an example for daily- and minute-resolution data respectively:

                            VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true }; diff --git a/videos.html b/videos.html index 89b15c9a..0fb02af8 100644 --- a/videos.html +++ b/videos.html @@ -13,8 +13,6 @@ - - @@ -32,9 +30,6 @@ - - @@ -46,28 +41,21 @@ -
                            - - - - - - - - - - - - - - - - -
                            - +
                            - -
                            -
                            -
                            +

                            Videos

                            @@ -181,7 +318,7 @@

                            -

                            Where things don’t:

                            +

                            Where things don’t:



                            @@ -212,19 +349,15 @@ in the previous video, we now take it to trade live against the Bittrex exchange
                            -
                            -
                            - -
                            @@ -258,8 +390,7 @@ in the previous video, we now take it to trade live against the Bittrex exchange VERSION:'0.4', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', - HAS_SOURCE: true, - SOURCELINK_SUFFIX: '.txt' + HAS_SOURCE: true };