mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-13 17:42:42 +08:00
updated based on PR feedback.
This commit is contained in:
@@ -303,10 +303,6 @@ class BatchTransformTestCase(TestCase):
|
||||
|
||||
# test overloaded class
|
||||
for test_history in [algo.history_return_price_class, algo.history_return_price_decorator]:
|
||||
self.assertTrue(np.all(test_history[2].values.flatten() == range(4, 10)))
|
||||
self.assertTrue(np.all(test_history[3].values.flatten() == range(4, 10)))
|
||||
self.assertTrue(np.all(test_history[4].values.flatten() == range(6, 14)))
|
||||
|
||||
np.testing.assert_array_equal(
|
||||
range(4, 10),
|
||||
test_history[2].values.flatten()
|
||||
|
||||
@@ -5,7 +5,7 @@ from zipline.gens.tradegens import DataFrameSource
|
||||
from zipline.utils.factory import create_trading_environment
|
||||
from zipline.gens.transform import StatefulTransform
|
||||
from zipline.lines import SimulatedTrading
|
||||
from zipline.finance.slippage import FixedSlippage, simulate_method_factory
|
||||
from zipline.finance.slippage import FixedSlippage, transact_partial
|
||||
from zipline.finance.commission import PerShare
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class TradingAlgorithm(object):
|
||||
transforms,
|
||||
self,
|
||||
environment,
|
||||
simulate_method_factory(FixedSlippage(), PerShare(0.0))
|
||||
transact_partial(FixedSlippage(), PerShare(0.0))
|
||||
)
|
||||
|
||||
def run(self, source, start=None, end=None):
|
||||
@@ -180,5 +180,5 @@ class TradingAlgorithm(object):
|
||||
def initialize(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def set_simulate_override(self, slippage_callable):
|
||||
def set_transact_setter(self, transact_setter):
|
||||
pass
|
||||
|
||||
@@ -1,18 +1,44 @@
|
||||
class PerShare(object):
|
||||
"""
|
||||
Calculates a commission for a transaction based on a per
|
||||
share cost.
|
||||
"""
|
||||
|
||||
def __init__(self, cost=0.03):
|
||||
"""
|
||||
Cost parameter is the cost of a trade per-share. $0.03
|
||||
means three cents per share, which is a very conservative
|
||||
(quite high) for per share costs.
|
||||
"""
|
||||
self.cost = cost
|
||||
|
||||
|
||||
def calculate(self, transaction):
|
||||
"""
|
||||
returns a tuple of:
|
||||
(per share commission, total transaction commission)
|
||||
"""
|
||||
return self.cost, abs(transaction.amount * self.cost)
|
||||
|
||||
class PerTrade(object):
|
||||
"""
|
||||
Calculates a commission for a transaction based on a per
|
||||
trade cost.
|
||||
"""
|
||||
|
||||
def __init__(self, cost=5.0):
|
||||
"""
|
||||
Cost parameter is the cost of a trade, regardless of
|
||||
share count. $5.00 per trade is fairly typical of
|
||||
discount brokers.
|
||||
"""
|
||||
self.cost = cost
|
||||
|
||||
def calculate(self, transaction):
|
||||
"""
|
||||
returns a tuple of:
|
||||
(per share commission, total transaction commission)
|
||||
"""
|
||||
if transaction.amount == 0:
|
||||
return 0.0, 0.0
|
||||
|
||||
|
||||
+15
-10
@@ -1,20 +1,25 @@
|
||||
import pytz
|
||||
import math
|
||||
|
||||
from functools import partial
|
||||
|
||||
import zipline.protocol as zp
|
||||
|
||||
def transact_stub(slippage, commission, open_orders, events):
|
||||
"""
|
||||
This is intended to be wrapped in a partial, so that the
|
||||
slippage and commission models can be enclosed.
|
||||
"""
|
||||
transaction = slippage.simulate(open_orders, events)
|
||||
if transaction:
|
||||
per_share, total_commission = commission.calculate(transaction)
|
||||
transaction.price = transaction.price + per_share
|
||||
transaction.commission = total_commission
|
||||
return transaction
|
||||
|
||||
def simulate_method_factory(slippage, commission):
|
||||
|
||||
def simulate(open_orders, events):
|
||||
transaction = slippage.simulate(open_orders, events)
|
||||
if transaction:
|
||||
per_share, total_commission = commission.calculate(transaction)
|
||||
transaction.price = transaction.price + per_share
|
||||
transaction.commission = total_commission
|
||||
return transaction
|
||||
|
||||
return simulate
|
||||
def transact_partial(slippage, commission):
|
||||
return partial(transact_stub, slippage, commission)
|
||||
|
||||
def create_transaction(sid, amount, price, dt):
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from collections import defaultdict
|
||||
import zipline.protocol as zp
|
||||
from zipline.finance.slippage import (
|
||||
VolumeShareSlippage,
|
||||
simulate_method_factory
|
||||
transact_partial
|
||||
)
|
||||
from zipline.finance.commission import PerShare
|
||||
|
||||
@@ -15,11 +15,11 @@ log = logbook.Logger('Transaction Simulator')
|
||||
|
||||
class TransactionSimulator(object):
|
||||
|
||||
def __init__(self, simulate=None):
|
||||
if simulate:
|
||||
self.simulate = simulate
|
||||
def __init__(self, transact=None):
|
||||
if transact != None:
|
||||
self.transact = transact
|
||||
else:
|
||||
self.simulate = simulate_method_factory(
|
||||
self.transact = transact_partial(
|
||||
VolumeShareSlippage(),
|
||||
PerShare()
|
||||
)
|
||||
@@ -43,7 +43,7 @@ class TransactionSimulator(object):
|
||||
event.TRANSACTION = None
|
||||
# We only fill transactions on trade events.
|
||||
if event.type == zp.DATASOURCE_TYPE.TRADE:
|
||||
event.TRANSACTION = self.simulate(event, self.open_orders)
|
||||
event.TRANSACTION = self.transact(event, self.open_orders)
|
||||
return event
|
||||
|
||||
|
||||
|
||||
@@ -52,14 +52,14 @@ class TradeSimulationClient(object):
|
||||
is sent to the algo.
|
||||
"""
|
||||
|
||||
def __init__(self, algo, environment, txn_sim):
|
||||
def __init__(self, algo, environment, transact):
|
||||
|
||||
self.algo = algo
|
||||
self.sids = algo.get_sid_filter()
|
||||
self.environment = environment
|
||||
self.txn_sim = txn_sim
|
||||
self.transact = transact
|
||||
|
||||
self.ordering_client = TransactionSimulator(self.txn_sim)
|
||||
self.ordering_client = TransactionSimulator(self.transact)
|
||||
self.perf_tracker = PerformanceTracker(self.environment, self.sids)
|
||||
|
||||
self.algo_start = self.environment.first_open
|
||||
@@ -130,8 +130,10 @@ class AlgorithmSimulator(object):
|
||||
self.algolog = Logger("AlgoLog")
|
||||
self.algo.set_logger(self.algolog)
|
||||
|
||||
# Porived user algorithm with slippage override.
|
||||
self.algo.set_simulate_override(self.simulate_override)
|
||||
# Provide user algorithm with a setter for the transact
|
||||
# method (method that constructs transactions based on
|
||||
# open orders and trade events).
|
||||
self.algo.set_transact_setter(self.set_transact)
|
||||
|
||||
# Handler for heartbeats during calls to handle_data.
|
||||
def log_heartbeats(beat_count, stackframe):
|
||||
@@ -173,13 +175,17 @@ class AlgorithmSimulator(object):
|
||||
record.extra['algo_dt'] = self.snapshot_dt
|
||||
self.processor = Processor(inject_algo_dt)
|
||||
|
||||
def simulate_override(self, slippage):
|
||||
self.order_book.slippage = slippage
|
||||
def set_transact(self, transact):
|
||||
"""
|
||||
Set the method that will be called to create a
|
||||
transaction from open orders and trade events.
|
||||
"""
|
||||
self.order_book.transact = transact
|
||||
|
||||
def order(self, sid, amount):
|
||||
"""
|
||||
Closure to pass into the user's algo to allow placing orders
|
||||
into the txn_sim's dict of open orders.
|
||||
into the transaction simulator's dict of open orders.
|
||||
"""
|
||||
assert sid in self.sids, "Order on invalid sid: %i" % sid
|
||||
order = ndict({
|
||||
@@ -230,7 +236,7 @@ class AlgorithmSimulator(object):
|
||||
if date == 'DONE':
|
||||
for event in snapshot:
|
||||
yield event.perf_message
|
||||
raise StopIteration()
|
||||
raise StopIteration
|
||||
|
||||
# We're still in the warmup period. Use the event to
|
||||
# update our universe, but don't yield any perf messages,
|
||||
|
||||
+12
-12
@@ -44,8 +44,8 @@ The algorithm must expose methods:
|
||||
|
||||
self.Portfolio[sid(133)]['cost_basis']
|
||||
|
||||
- set_simulate_override: method that accepts a callable. Will
|
||||
be set as the value of the set_simulate_override method of
|
||||
- set_transact_setter: method that accepts a callable. Will
|
||||
be set as the value of the set_transact_setter method of
|
||||
the trading_client. This allows an algorithm to change the
|
||||
slippage model used to predict transactions based on orders
|
||||
and trade events.
|
||||
@@ -97,7 +97,7 @@ class TestAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return self.sid_filter
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ class HeavyBuyAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class NoopAlgorithm(object):
|
||||
@@ -164,7 +164,7 @@ class NoopAlgorithm(object):
|
||||
def get_sid_filter(self):
|
||||
return []
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class ExceptionAlgorithm(object):
|
||||
@@ -210,7 +210,7 @@ class ExceptionAlgorithm(object):
|
||||
else:
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class DivByZeroAlgorithm():
|
||||
@@ -240,7 +240,7 @@ class DivByZeroAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class InitializeTimeoutAlgorithm():
|
||||
@@ -269,7 +269,7 @@ class InitializeTimeoutAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class TooMuchProcessingAlgorithm():
|
||||
@@ -297,7 +297,7 @@ class TooMuchProcessingAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class TimeoutAlgorithm():
|
||||
@@ -327,7 +327,7 @@ class TimeoutAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class TestPrintAlgorithm():
|
||||
@@ -354,7 +354,7 @@ class TestPrintAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
class TestLoggingAlgorithm():
|
||||
@@ -381,7 +381,7 @@ class TestLoggingAlgorithm():
|
||||
def get_sid_filter(self):
|
||||
return [self.sid]
|
||||
|
||||
def set_simulate_override(self, txn_sim_callable):
|
||||
def set_transact_setter(self, txn_sim_callable):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import zipline.utils.factory as factory
|
||||
|
||||
from zipline.test_algorithms import TestAlgorithm
|
||||
from zipline.lines import SimulatedTrading
|
||||
from zipline.finance.slippage import FixedSlippage, simulate_method_factory
|
||||
from zipline.finance.slippage import FixedSlippage, transact_partial
|
||||
from zipline.finance.commission import PerShare
|
||||
|
||||
def create_test_zipline(**config):
|
||||
@@ -65,7 +65,7 @@ def create_test_zipline(**config):
|
||||
|
||||
slippage = config.get('slippage', FixedSlippage())
|
||||
commission = PerShare()
|
||||
sim_method = simulate_method_factory(slippage, commission)
|
||||
transact_method = transact_partial(slippage, commission)
|
||||
|
||||
#-------------------
|
||||
# Trade Source
|
||||
@@ -106,7 +106,7 @@ def create_test_zipline(**config):
|
||||
transforms,
|
||||
test_algo,
|
||||
trading_environment,
|
||||
sim_method
|
||||
transact_method
|
||||
)
|
||||
#-------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user