Files
catalyst/zipline/optimize/factory.py
T
2012-10-08 17:32:41 -04:00

155 lines
5.1 KiB
Python

#
# Copyright 2012 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.
"""
Factory functions to prepare useful data for optimize tests.
Author: Thomas V. Wiecki (thomas.wiecki@gmail.com), 2012
"""
from datetime import timedelta
import zipline.protocol as zp
from zipline.utils.factory import (
get_next_trading_dt,
create_trading_environment
)
from zipline.gens.tradegens import SpecificEquityTrades
from zipline.optimize.algorithms import BuySellAlgorithm
from zipline.finance.slippage import FixedSlippage
from copy import copy
from itertools import cycle
def create_updown_trade_source(sid, trade_count, trading_environment,
base_price, amplitude):
"""Create the updown trade source. This source emits events with
the price going up and down by the same amount in each
iteration. The trade source is thus perfectly predictable. This is
used for a test case for the optimization code.
:Arguments:
sid : int
SID of stock to create.
trade_count : int
How many trade events to create (will also influence order count)
trading_environment : TradeEnvironment object
The trading environment to use
(see zipline.factory.create_trading_environment)
base_price : int
The average price that each iteration will hover around.
amplitude : int
How much the price will go up and down each iteration.
:Returns:
source : SpecificEquityTrades
The trade source emitting up down events.
"""
volume = 1000
events = []
price = base_price - amplitude / 2.
cur = trading_environment.first_open
one_day = timedelta(minutes=1)
#create iterator to cycle through up and down phases
change = cycle([1, -1])
for i in xrange(trade_count + 2):
cur = get_next_trading_dt(cur, one_day, trading_environment)
event = zp.ndict({
"type": zp.DATASOURCE_TYPE.TRADE,
"sid": sid,
"price": price,
"volume": volume,
"dt": cur,
})
events.append(event)
price += change.next() * amplitude
trading_environment.period_end = cur
source = SpecificEquityTrades(events)
return source
def create_predictable_zipline(config, offset=0, simulate=True):
"""Create a test zipline object as specified by config. The
zipline will use the UpDown tradesource which is perfectly
predictable.
Trade source parameters can be specified inside the config object.
:Trade source arguments:
config['sid'] : int
SID of stock to create.
config['amplitude'] : int (default 10)
How much the price will go up and down each iteration.
config['base_price'] : int (default 50)
The average price that each iteration will hover around.
config['trade_count'] : int (default 3)
How many trade events to create (will also influence order count)
If not specified, the BuySellAlgorithm is used by default. This
can be changed by setting config['algorithm'].
:Arguments:
offset : int (default 0)
The offset parameter specifies how much the BuySellAlgorithm will
order each iteration and is a negative quadratic centered around
0. Thus, any deviations from 0 will lead to less buy and sell
orders each iteration and ultimately to less compound returns.
simulate : bool (default True)
Whether to call .simulate(blocking=True) on the created zipline
argument.
:Returns:
zipline : class zipline
created zipline object
config : dict
the config dict used to create the zipline
"""
config = copy(config)
sid = config['sid']
# remove
amplitude = config.pop('amplitude', 10)
base_price = config.pop('base_price', 50)
trade_count = config.pop('trade_count', 3)
trading_environment = create_trading_environment()
source = create_updown_trade_source(sid,
trade_count,
trading_environment,
base_price,
amplitude)
if 'algorithm' not in config:
algorithm = BuySellAlgorithm(sids=[sid], amount=100, offset=offset)
config['order_count'] = trade_count - 1
config['trade_count'] = trade_count
config['trade_source'] = source
config['environment'] = trading_environment
config['slippage'] = FixedSlippage()
config['devel'] = True
return algorithm, config