mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-18 12:20:12 +08:00
Merge pull request #510 from quantopian/move-serialization-methods-into-zipline
MAINT: Added pickle protocol methods into zipline.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
#
|
||||
# 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 datetime
|
||||
import os
|
||||
import pickle
|
||||
import pytz
|
||||
|
||||
import sys
|
||||
sys.path.insert(0, '.')
|
||||
|
||||
from zipline.finance.blotter import Blotter, Order
|
||||
from zipline.finance.commission import PerShare, PerTrade, PerDollar
|
||||
from zipline.finance.performance.period import PerformancePeriod
|
||||
from zipline.finance.performance.position import Position
|
||||
from zipline.finance.performance.tracker import PerformanceTracker
|
||||
from zipline.finance.risk.cumulative import RiskMetricsCumulative
|
||||
from zipline.finance.risk.period import RiskMetricsPeriod
|
||||
from zipline.finance.risk.report import RiskReport
|
||||
from zipline.finance.slippage import (
|
||||
FixedSlippage,
|
||||
Transaction,
|
||||
VolumeShareSlippage
|
||||
)
|
||||
from zipline.protocol import Account
|
||||
from zipline.protocol import Portfolio
|
||||
from zipline.protocol import Position as ProtocolPosition
|
||||
|
||||
|
||||
from zipline.finance.trading import SimulationParameters
|
||||
|
||||
from zipline.utils import factory
|
||||
from zipline.utils.serialization_utils import VERSION_LABEL
|
||||
|
||||
base_state_dir = 'tests/resources/saved_state_archive'
|
||||
if not os.path.exists(base_state_dir):
|
||||
os.makedirs(base_state_dir)
|
||||
|
||||
|
||||
sim_params_daily = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='daily')
|
||||
|
||||
|
||||
sim_params_minute = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='minute')
|
||||
|
||||
|
||||
returns = factory.create_returns_from_list(
|
||||
[1.0], sim_params_daily)
|
||||
|
||||
|
||||
argument_list = [
|
||||
(Blotter, ()),
|
||||
(Order, (datetime.datetime(2013, 6, 19), 8554, 100)),
|
||||
(PerShare, ()),
|
||||
(PerTrade, ()),
|
||||
(PerDollar, ()),
|
||||
(PerformancePeriod, (10000,)),
|
||||
(Position, (8554,)),
|
||||
(PerformanceTracker, (sim_params_minute,)),
|
||||
(RiskMetricsCumulative, (sim_params_minute,)),
|
||||
(RiskMetricsPeriod, (returns.index[0], returns.index[0], returns)),
|
||||
(RiskReport, (returns, sim_params_minute)),
|
||||
(FixedSlippage, ()),
|
||||
(Transaction, (8554, 10, datetime.datetime(2013, 6, 19), 100, "0000")),
|
||||
(VolumeShareSlippage, ()),
|
||||
(Account, ()),
|
||||
(Portfolio, ()),
|
||||
(ProtocolPosition, (8554,))
|
||||
]
|
||||
|
||||
|
||||
def write_state_to_disk(cls, state, emission_rate=None):
|
||||
state_dir = cls.__module__ + '.' + cls.__name__
|
||||
|
||||
full_dir = base_state_dir + '/' + state_dir
|
||||
|
||||
if not os.path.exists(full_dir):
|
||||
os.makedirs(full_dir)
|
||||
|
||||
if emission_rate is not None:
|
||||
name = 'State_Version_' + emission_rate + \
|
||||
str(state['obj_state'][VERSION_LABEL])
|
||||
else:
|
||||
name = 'State_Version_' + str(state['obj_state'][VERSION_LABEL])
|
||||
|
||||
full_path = full_dir + '/' + name
|
||||
|
||||
f = open(full_path, 'w')
|
||||
|
||||
pickle.dump(state, f)
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
def generate_object_state(cls, initargs):
|
||||
|
||||
obj = cls(*initargs)
|
||||
state = obj.__getstate__()
|
||||
if hasattr(obj, '__getinitargs__'):
|
||||
initargs = obj.__getinitargs__()
|
||||
else:
|
||||
initargs = None
|
||||
if hasattr(obj, '__getnewargs__'):
|
||||
newargs = obj.__getnewargs__()
|
||||
else:
|
||||
newargs = None
|
||||
|
||||
on_disk_state = {
|
||||
'obj_state': state,
|
||||
'initargs': initargs,
|
||||
'newargs': newargs
|
||||
}
|
||||
|
||||
write_state_to_disk(cls, on_disk_state)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
for args in argument_list:
|
||||
generate_object_state(*args)
|
||||
@@ -0,0 +1,21 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'_stateversion_'
|
||||
p3
|
||||
I1
|
||||
sS'new_orders'
|
||||
p4
|
||||
(lp5
|
||||
sS'orders'
|
||||
p6
|
||||
(dp7
|
||||
sS'open_orders'
|
||||
p8
|
||||
(dp9
|
||||
ssS'initargs'
|
||||
p10
|
||||
NsS'newargs'
|
||||
p11
|
||||
Ns.
|
||||
@@ -0,0 +1,60 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'direction'
|
||||
p3
|
||||
F1.0
|
||||
sS'_stateversion_'
|
||||
p4
|
||||
I1
|
||||
sS'_status'
|
||||
p5
|
||||
I0
|
||||
sS'created'
|
||||
p6
|
||||
cdatetime
|
||||
datetime
|
||||
p7
|
||||
(S'\x07\xdd\x06\x13\x00\x00\x00\x00\x00\x00'
|
||||
p8
|
||||
tp9
|
||||
Rp10
|
||||
sS'limit_reached'
|
||||
p11
|
||||
I00
|
||||
sS'stop'
|
||||
p12
|
||||
NsS'reason'
|
||||
p13
|
||||
NsS'stop_reached'
|
||||
p14
|
||||
I00
|
||||
sS'commission'
|
||||
p15
|
||||
NsS'amount'
|
||||
p16
|
||||
I100
|
||||
sS'limit'
|
||||
p17
|
||||
NsS'sid'
|
||||
p18
|
||||
I8554
|
||||
sS'dt'
|
||||
p19
|
||||
g10
|
||||
sS'type'
|
||||
p20
|
||||
I6
|
||||
sS'id'
|
||||
p21
|
||||
S'ca467b999ff148f4b4fa89aa2cd899a9'
|
||||
p22
|
||||
sS'filled'
|
||||
p23
|
||||
I0
|
||||
ssS'initargs'
|
||||
p24
|
||||
NsS'newargs'
|
||||
p25
|
||||
Ns.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'cost'
|
||||
p3
|
||||
F0.0015
|
||||
sS'_stateversion_'
|
||||
p4
|
||||
I1
|
||||
ssS'initargs'
|
||||
p5
|
||||
NsS'newargs'
|
||||
p6
|
||||
Ns.
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'min_trade_cost'
|
||||
p3
|
||||
NsS'cost'
|
||||
p4
|
||||
F0.03
|
||||
sS'_stateversion_'
|
||||
p5
|
||||
I1
|
||||
ssS'initargs'
|
||||
p6
|
||||
NsS'newargs'
|
||||
p7
|
||||
Ns.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'cost'
|
||||
p3
|
||||
F5.0
|
||||
sS'_stateversion_'
|
||||
p4
|
||||
I1
|
||||
ssS'initargs'
|
||||
p5
|
||||
NsS'newargs'
|
||||
p6
|
||||
Ns.
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'_account_store'
|
||||
p3
|
||||
ccopy_reg
|
||||
_reconstructor
|
||||
p4
|
||||
(czipline.protocol
|
||||
Account
|
||||
p5
|
||||
c__builtin__
|
||||
object
|
||||
p6
|
||||
Ntp7
|
||||
Rp8
|
||||
(dp9
|
||||
S'regt_margin'
|
||||
p10
|
||||
Finf
|
||||
sS'maintenance_margin_requirement'
|
||||
p11
|
||||
F0.0
|
||||
sS'day_trades_remaining'
|
||||
p12
|
||||
Finf
|
||||
sS'buying_power'
|
||||
p13
|
||||
Finf
|
||||
sS'net_leverage'
|
||||
p14
|
||||
F0.0
|
||||
sS'settled_cash'
|
||||
p15
|
||||
F0.0
|
||||
sS'cushion'
|
||||
p16
|
||||
F0.0
|
||||
sS'_stateversion_'
|
||||
p17
|
||||
I1
|
||||
sS'leverage'
|
||||
p18
|
||||
F0.0
|
||||
sS'regt_equity'
|
||||
p19
|
||||
F0.0
|
||||
sS'excess_liquidity'
|
||||
p20
|
||||
F0.0
|
||||
sS'available_funds'
|
||||
p21
|
||||
F0.0
|
||||
sS'equity_with_loan'
|
||||
p22
|
||||
F0.0
|
||||
sS'initial_margin_requirement'
|
||||
p23
|
||||
F0.0
|
||||
sS'net_liquidation'
|
||||
p24
|
||||
F0.0
|
||||
sS'total_positions_value'
|
||||
p25
|
||||
F0.0
|
||||
sS'accrued_interest'
|
||||
p26
|
||||
F0.0
|
||||
sbsS'orders_by_modified'
|
||||
p27
|
||||
(dp28
|
||||
sS'keep_transactions'
|
||||
p29
|
||||
I01
|
||||
sS'ending_cash'
|
||||
p30
|
||||
F10000.0
|
||||
sS'_positions_store'
|
||||
p31
|
||||
(dp32
|
||||
sS'positions'
|
||||
p33
|
||||
(dp34
|
||||
sS'processed_transactions'
|
||||
p35
|
||||
(dp36
|
||||
sS'ending_value'
|
||||
p37
|
||||
cnumpy.core.multiarray
|
||||
scalar
|
||||
p38
|
||||
(cnumpy
|
||||
dtype
|
||||
p39
|
||||
(S'f8'
|
||||
p40
|
||||
I0
|
||||
I1
|
||||
tp41
|
||||
Rp42
|
||||
(I3
|
||||
S'<'
|
||||
p43
|
||||
NNNI-1
|
||||
I-1
|
||||
I0
|
||||
tp44
|
||||
bS'\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
p45
|
||||
tp46
|
||||
Rp47
|
||||
sS'loc_map'
|
||||
p48
|
||||
(dp49
|
||||
sS'starting_cash'
|
||||
p50
|
||||
I10000
|
||||
sS'returns'
|
||||
p51
|
||||
g38
|
||||
(g42
|
||||
S'\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
p52
|
||||
tp53
|
||||
Rp54
|
||||
sg17
|
||||
I1
|
||||
sS'pnl'
|
||||
p55
|
||||
g38
|
||||
(g42
|
||||
S'\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
p56
|
||||
tp57
|
||||
Rp58
|
||||
sS'period_cash_flow'
|
||||
p59
|
||||
F0.0
|
||||
sS'serialize_positions'
|
||||
p60
|
||||
I01
|
||||
sS'keep_orders'
|
||||
p61
|
||||
I00
|
||||
sS'_portfolio_store'
|
||||
p62
|
||||
g4
|
||||
(czipline.protocol
|
||||
Portfolio
|
||||
p63
|
||||
g6
|
||||
Ntp64
|
||||
Rp65
|
||||
(dp66
|
||||
g17
|
||||
I1
|
||||
sS'portfolio_value'
|
||||
p67
|
||||
F0.0
|
||||
sS'cash'
|
||||
p68
|
||||
F0.0
|
||||
sg50
|
||||
F0.0
|
||||
sg51
|
||||
F0.0
|
||||
sS'capital_used'
|
||||
p69
|
||||
F0.0
|
||||
sg55
|
||||
F0.0
|
||||
sg33
|
||||
(dp70
|
||||
sS'positions_value'
|
||||
p71
|
||||
F0.0
|
||||
sS'start_date'
|
||||
p72
|
||||
NsbsS'starting_value'
|
||||
p73
|
||||
F0.0
|
||||
sS'period_open'
|
||||
p74
|
||||
NsS'period_close'
|
||||
p75
|
||||
NsS'orders_by_id'
|
||||
p76
|
||||
(dp77
|
||||
ssS'initargs'
|
||||
p78
|
||||
NsS'newargs'
|
||||
p79
|
||||
Ns.
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'_stateversion_'
|
||||
p3
|
||||
I1
|
||||
sS'cost_basis'
|
||||
p4
|
||||
F0.0
|
||||
sS'amount'
|
||||
p5
|
||||
I0
|
||||
sS'last_sale_price'
|
||||
p6
|
||||
F0.0
|
||||
sS'sid'
|
||||
p7
|
||||
I8554
|
||||
sS'last_sale_date'
|
||||
p8
|
||||
NssS'initargs'
|
||||
p9
|
||||
NsS'newargs'
|
||||
p10
|
||||
Ns.
|
||||
+89172
File diff suppressed because one or more lines are too long
+88221
File diff suppressed because one or more lines are too long
+87885
File diff suppressed because it is too large
Load Diff
+88025
File diff suppressed because it is too large
Load Diff
+15
@@ -0,0 +1,15 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'spread'
|
||||
p3
|
||||
F0.0
|
||||
sS'_stateversion_'
|
||||
p4
|
||||
I1
|
||||
ssS'initargs'
|
||||
p5
|
||||
NsS'newargs'
|
||||
p6
|
||||
Ns.
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'commission'
|
||||
p3
|
||||
NsS'amount'
|
||||
p4
|
||||
I10
|
||||
sS'_stateversion_'
|
||||
p5
|
||||
I1
|
||||
sS'sid'
|
||||
p6
|
||||
I8554
|
||||
sS'order_id'
|
||||
p7
|
||||
S'0000'
|
||||
p8
|
||||
sS'price'
|
||||
p9
|
||||
I100
|
||||
sS'type'
|
||||
p10
|
||||
I5
|
||||
sS'dt'
|
||||
p11
|
||||
cdatetime
|
||||
datetime
|
||||
p12
|
||||
(S'\x07\xdd\x06\x13\x00\x00\x00\x00\x00\x00'
|
||||
p13
|
||||
tp14
|
||||
Rp15
|
||||
ssS'initargs'
|
||||
p16
|
||||
NsS'newargs'
|
||||
p17
|
||||
Ns.
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'price_impact'
|
||||
p3
|
||||
F0.1
|
||||
sS'volume_limit'
|
||||
p4
|
||||
F0.25
|
||||
sS'_stateversion_'
|
||||
p5
|
||||
I1
|
||||
ssS'initargs'
|
||||
p6
|
||||
NsS'newargs'
|
||||
p7
|
||||
Ns.
|
||||
@@ -0,0 +1,60 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'regt_margin'
|
||||
p3
|
||||
Finf
|
||||
sS'maintenance_margin_requirement'
|
||||
p4
|
||||
F0.0
|
||||
sS'day_trades_remaining'
|
||||
p5
|
||||
Finf
|
||||
sS'buying_power'
|
||||
p6
|
||||
Finf
|
||||
sS'net_leverage'
|
||||
p7
|
||||
F0.0
|
||||
sS'settled_cash'
|
||||
p8
|
||||
F0.0
|
||||
sS'cushion'
|
||||
p9
|
||||
F0.0
|
||||
sS'_stateversion_'
|
||||
p10
|
||||
I1
|
||||
sS'leverage'
|
||||
p11
|
||||
F0.0
|
||||
sS'regt_equity'
|
||||
p12
|
||||
F0.0
|
||||
sS'excess_liquidity'
|
||||
p13
|
||||
F0.0
|
||||
sS'available_funds'
|
||||
p14
|
||||
F0.0
|
||||
sS'equity_with_loan'
|
||||
p15
|
||||
F0.0
|
||||
sS'initial_margin_requirement'
|
||||
p16
|
||||
F0.0
|
||||
sS'net_liquidation'
|
||||
p17
|
||||
F0.0
|
||||
sS'total_positions_value'
|
||||
p18
|
||||
F0.0
|
||||
sS'accrued_interest'
|
||||
p19
|
||||
F0.0
|
||||
ssS'initargs'
|
||||
p20
|
||||
NsS'newargs'
|
||||
p21
|
||||
Ns.
|
||||
@@ -0,0 +1,38 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'_stateversion_'
|
||||
p3
|
||||
I1
|
||||
sS'portfolio_value'
|
||||
p4
|
||||
F0.0
|
||||
sS'cash'
|
||||
p5
|
||||
F0.0
|
||||
sS'starting_cash'
|
||||
p6
|
||||
F0.0
|
||||
sS'returns'
|
||||
p7
|
||||
F0.0
|
||||
sS'capital_used'
|
||||
p8
|
||||
F0.0
|
||||
sS'pnl'
|
||||
p9
|
||||
F0.0
|
||||
sS'positions'
|
||||
p10
|
||||
(dp11
|
||||
sS'positions_value'
|
||||
p12
|
||||
F0.0
|
||||
sS'start_date'
|
||||
p13
|
||||
NssS'initargs'
|
||||
p14
|
||||
NsS'newargs'
|
||||
p15
|
||||
Ns.
|
||||
@@ -0,0 +1,24 @@
|
||||
(dp0
|
||||
S'obj_state'
|
||||
p1
|
||||
(dp2
|
||||
S'_stateversion_'
|
||||
p3
|
||||
I1
|
||||
sS'amount'
|
||||
p4
|
||||
I0
|
||||
sS'last_sale_price'
|
||||
p5
|
||||
F0.0
|
||||
sS'cost_basis'
|
||||
p6
|
||||
F0.0
|
||||
sS'sid'
|
||||
p7
|
||||
I8554
|
||||
ssS'initargs'
|
||||
p8
|
||||
NsS'newargs'
|
||||
p9
|
||||
Ns.
|
||||
@@ -0,0 +1,100 @@
|
||||
#
|
||||
# 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 datetime
|
||||
import pickle
|
||||
import pytz
|
||||
|
||||
from nose_parameterized import parameterized
|
||||
from unittest import TestCase
|
||||
|
||||
from zipline.finance.blotter import Blotter, Order
|
||||
from zipline.finance.commission import PerShare, PerTrade, PerDollar
|
||||
from zipline.finance.performance.period import PerformancePeriod
|
||||
from zipline.finance.performance.position import Position
|
||||
from zipline.finance.performance.tracker import PerformanceTracker
|
||||
from zipline.finance.risk.cumulative import RiskMetricsCumulative
|
||||
from zipline.finance.risk.period import RiskMetricsPeriod
|
||||
from zipline.finance.risk.report import RiskReport
|
||||
from zipline.finance.slippage import (
|
||||
FixedSlippage,
|
||||
Transaction,
|
||||
VolumeShareSlippage
|
||||
)
|
||||
from zipline.protocol import Account
|
||||
from zipline.protocol import Portfolio
|
||||
from zipline.protocol import Position as ProtocolPosition
|
||||
|
||||
|
||||
from zipline.finance.trading import SimulationParameters
|
||||
|
||||
from zipline.utils import factory
|
||||
|
||||
sim_params_daily = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='daily')
|
||||
sim_params_minute = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='minute')
|
||||
returns = factory.create_returns_from_list(
|
||||
[1.0], sim_params_daily)
|
||||
|
||||
|
||||
class PickleSerializationTestCase(TestCase):
|
||||
|
||||
@parameterized.expand([
|
||||
(Blotter, (), 'repr'),
|
||||
(Order, (datetime.datetime(2013, 6, 19), 8554, 100), 'dict'),
|
||||
(PerShare, (), 'dict'),
|
||||
(PerTrade, (), 'dict'),
|
||||
(PerDollar, (), 'dict'),
|
||||
(PerformancePeriod, (10000,), 'to_dict'),
|
||||
(Position, (8554,), 'dict'),
|
||||
(PerformanceTracker, (sim_params_daily,), 'to_dict'),
|
||||
(PerformanceTracker, (sim_params_minute,), 'to_dict'),
|
||||
(RiskMetricsCumulative, (sim_params_daily,), 'to_dict'),
|
||||
(RiskMetricsCumulative, (sim_params_minute,), 'to_dict'),
|
||||
(RiskMetricsPeriod,
|
||||
(returns.index[0], returns.index[0], returns), 'to_dict'),
|
||||
(RiskReport, (returns, sim_params_daily), 'to_dict'),
|
||||
(RiskReport, (returns, sim_params_minute), 'to_dict'),
|
||||
(FixedSlippage, (), 'dict'),
|
||||
(Transaction,
|
||||
(8554, 10, datetime.datetime(2013, 6, 19), 100, "0000"), 'dict'),
|
||||
(VolumeShareSlippage, (), 'dict'),
|
||||
(Account, (), 'dict'),
|
||||
(Portfolio, (), 'dict'),
|
||||
(ProtocolPosition, (8554,), 'dict')
|
||||
])
|
||||
def test_object_serialization(self,
|
||||
cls,
|
||||
initargs,
|
||||
comparison_method='dict'):
|
||||
|
||||
obj = cls(*initargs)
|
||||
state = pickle.dumps(obj)
|
||||
|
||||
obj2 = pickle.loads(state)
|
||||
|
||||
if comparison_method == 'repr':
|
||||
self.assertEqual(obj.__repr__(), obj2.__repr__())
|
||||
elif comparison_method == 'to_dict':
|
||||
self.assertEqual(obj.to_dict(), obj2.to_dict())
|
||||
else:
|
||||
self.assertEqual(obj.__dict__, obj2.__dict__)
|
||||
@@ -0,0 +1,150 @@
|
||||
#
|
||||
# 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 datetime
|
||||
import pytz
|
||||
|
||||
from nose_parameterized import parameterized
|
||||
from unittest import TestCase
|
||||
|
||||
from zipline.finance.blotter import Blotter, Order
|
||||
from zipline.finance.commission import PerShare, PerTrade, PerDollar
|
||||
from zipline.finance.performance.period import PerformancePeriod
|
||||
from zipline.finance.performance.position import Position
|
||||
from zipline.finance.performance.tracker import PerformanceTracker
|
||||
from zipline.finance.risk.cumulative import RiskMetricsCumulative
|
||||
from zipline.finance.risk.period import RiskMetricsPeriod
|
||||
from zipline.finance.risk.report import RiskReport
|
||||
from zipline.finance.slippage import (
|
||||
FixedSlippage,
|
||||
Transaction,
|
||||
VolumeShareSlippage
|
||||
)
|
||||
from zipline.protocol import Account
|
||||
from zipline.protocol import Portfolio
|
||||
from zipline.protocol import Position as ProtocolPosition
|
||||
|
||||
|
||||
from zipline.finance.trading import SimulationParameters
|
||||
|
||||
from zipline.utils import factory
|
||||
|
||||
from six import iteritems
|
||||
|
||||
sim_params_daily = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='daily')
|
||||
sim_params_minute = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='minute')
|
||||
returns = factory.create_returns_from_list(
|
||||
[1.0], sim_params_daily)
|
||||
|
||||
|
||||
def gather_bad_dicts(state):
|
||||
bad = []
|
||||
for k, v in iteritems(state):
|
||||
if not isinstance(v, dict):
|
||||
continue
|
||||
if type(v) != dict:
|
||||
bad.append((k, v))
|
||||
bad.extend(gather_bad_dicts(v))
|
||||
return bad
|
||||
|
||||
|
||||
def stringify_cases(cases, func=None):
|
||||
# get better test case names
|
||||
results = []
|
||||
if func is None:
|
||||
func = lambda case: case[0].__name__
|
||||
for case in cases:
|
||||
new_case = list(case)
|
||||
key = func(case)
|
||||
new_case.insert(0, key)
|
||||
results.append(new_case)
|
||||
return results
|
||||
|
||||
|
||||
class SerializationTestCase(TestCase):
|
||||
|
||||
object_serialization_cases = stringify_cases([
|
||||
(Blotter, (), 'repr'),
|
||||
(Order, (datetime.datetime(2013, 6, 19), 8554, 100), 'dict'),
|
||||
(PerShare, (), 'dict'),
|
||||
(PerTrade, (), 'dict'),
|
||||
(PerDollar, (), 'dict'),
|
||||
(PerformancePeriod, (10000,), 'to_dict'),
|
||||
(Position, (8554,), 'dict'),
|
||||
(PerformanceTracker, (sim_params_daily,), 'to_dict'),
|
||||
(PerformanceTracker, (sim_params_minute,), 'to_dict'),
|
||||
(RiskMetricsCumulative, (sim_params_daily,), 'to_dict'),
|
||||
(RiskMetricsCumulative, (sim_params_minute,), 'to_dict'),
|
||||
(RiskMetricsPeriod,
|
||||
(returns.index[0], returns.index[0], returns), 'to_dict'),
|
||||
(RiskReport, (returns, sim_params_daily), 'to_dict'),
|
||||
(RiskReport, (returns, sim_params_minute), 'to_dict'),
|
||||
(FixedSlippage, (), 'dict'),
|
||||
(Transaction,
|
||||
(8554, 10, datetime.datetime(2013, 6, 19), 100, "0000"), 'dict'),
|
||||
(VolumeShareSlippage, (), 'dict'),
|
||||
(Account, (), 'dict'),
|
||||
(Portfolio, (), 'dict'),
|
||||
(ProtocolPosition, (8554,), 'dict')
|
||||
])
|
||||
|
||||
@parameterized.expand(object_serialization_cases)
|
||||
def test_object_serialization(self,
|
||||
_,
|
||||
cls,
|
||||
initargs,
|
||||
comparison_method='dict'):
|
||||
|
||||
obj = cls(*initargs)
|
||||
state = obj.__getstate__()
|
||||
|
||||
bad_dicts = gather_bad_dicts(state)
|
||||
bad_template = "type({0}) == {1}".format
|
||||
bad_msgs = [bad_template(k, type(v)) for k, v in bad_dicts]
|
||||
msg = "Only support bare dicts. " + ', '.join(bad_msgs)
|
||||
self.assertEqual(len(bad_dicts), 0, msg)
|
||||
# no state should have a dict subclass. Only regular PyDict
|
||||
|
||||
if hasattr(obj, '__getinitargs__'):
|
||||
initargs = obj.__getinitargs__()
|
||||
else:
|
||||
initargs = None
|
||||
if hasattr(obj, '__getnewargs__'):
|
||||
newargs = obj.__getnewargs__()
|
||||
else:
|
||||
newargs = None
|
||||
|
||||
if newargs is not None:
|
||||
obj2 = cls.__new__(cls, *newargs)
|
||||
else:
|
||||
obj2 = cls.__new__(cls)
|
||||
if initargs is not None:
|
||||
obj2.__init__(*initargs)
|
||||
obj2.__setstate__(state)
|
||||
|
||||
if comparison_method == 'repr':
|
||||
self.assertEqual(obj.__repr__(), obj2.__repr__())
|
||||
elif comparison_method == 'to_dict':
|
||||
self.assertEqual(obj.to_dict(), obj2.to_dict())
|
||||
else:
|
||||
self.assertEqual(obj.__dict__, obj2.__dict__)
|
||||
@@ -0,0 +1,150 @@
|
||||
#
|
||||
# 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 datetime
|
||||
import os
|
||||
import pandas
|
||||
import pickle
|
||||
import pytz
|
||||
|
||||
from nose_parameterized import parameterized
|
||||
from unittest import TestCase
|
||||
|
||||
from zipline.finance.blotter import Blotter, Order
|
||||
from zipline.finance.commission import PerShare, PerTrade, PerDollar
|
||||
from zipline.finance.performance.period import PerformancePeriod
|
||||
from zipline.finance.performance.position import Position
|
||||
from zipline.finance.performance.tracker import PerformanceTracker
|
||||
from zipline.finance.risk.cumulative import RiskMetricsCumulative
|
||||
from zipline.finance.risk.period import RiskMetricsPeriod
|
||||
from zipline.finance.risk.report import RiskReport
|
||||
from zipline.finance.slippage import (
|
||||
FixedSlippage,
|
||||
Transaction,
|
||||
VolumeShareSlippage
|
||||
)
|
||||
from zipline.protocol import Account
|
||||
from zipline.protocol import Portfolio
|
||||
from zipline.protocol import Position as ProtocolPosition
|
||||
|
||||
|
||||
from zipline.finance.trading import SimulationParameters
|
||||
|
||||
from zipline.utils import factory
|
||||
|
||||
sim_params_daily = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='daily')
|
||||
sim_params_minute = SimulationParameters(
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
datetime.datetime(2013, 6, 19, tzinfo=pytz.UTC),
|
||||
10000,
|
||||
emission_rate='minute')
|
||||
returns = factory.create_returns_from_list(
|
||||
[1.0], sim_params_daily)
|
||||
|
||||
base_state_dir = 'tests/resources/saved_state_archive'
|
||||
|
||||
BASE_STATE_DIR = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'resources',
|
||||
'saved_state_archive')
|
||||
|
||||
|
||||
class VersioningTestCase(TestCase):
|
||||
|
||||
def load_state_from_disk(self, cls):
|
||||
state_dir = cls.__module__ + '.' + cls.__name__
|
||||
|
||||
full_dir = BASE_STATE_DIR + '/' + state_dir
|
||||
|
||||
state_files = \
|
||||
[f for f in os.listdir(full_dir) if 'State_Version_' in f]
|
||||
|
||||
for f_name in state_files:
|
||||
f = open(full_dir + '/' + f_name, 'r')
|
||||
yield pickle.load(f)
|
||||
|
||||
# Only test versioning in minutely mode right now
|
||||
@parameterized.expand([
|
||||
(Blotter, (), 'repr'),
|
||||
(Order, (datetime.datetime(2013, 6, 19), 8554, 100), 'dict'),
|
||||
(PerShare, (), 'dict'),
|
||||
(PerTrade, (), 'dict'),
|
||||
(PerDollar, (), 'dict'),
|
||||
(PerformancePeriod, (10000,), 'to_dict'),
|
||||
(Position, (8554,), 'dict'),
|
||||
(PerformanceTracker, (sim_params_minute,), 'to_dict'),
|
||||
(RiskMetricsCumulative, (sim_params_minute,), 'to_dict'),
|
||||
(RiskMetricsPeriod,
|
||||
(returns.index[0], returns.index[0], returns), 'to_dict'),
|
||||
(RiskReport, (returns, sim_params_minute), 'to_dict'),
|
||||
(FixedSlippage, (), 'dict'),
|
||||
(Transaction,
|
||||
(8554, 10, datetime.datetime(2013, 6, 19), 100, "0000"), 'dict'),
|
||||
(VolumeShareSlippage, (), 'dict'),
|
||||
(Account, (), 'dict'),
|
||||
(Portfolio, (), 'dict'),
|
||||
(ProtocolPosition, (8554,), 'dict')
|
||||
])
|
||||
def test_object_serialization(self,
|
||||
cls,
|
||||
initargs,
|
||||
comparison_method='dict'):
|
||||
|
||||
# The state generated under one version of pandas may not be
|
||||
# compatible with another. To ensure that tests pass under the travis
|
||||
# pandas version matrix, we only run versioning tests under the
|
||||
# current version of pandas. This will need to be updated once we
|
||||
# change the pandas version on prod.
|
||||
if pandas.__version__ != '0.12.0':
|
||||
return
|
||||
|
||||
# Make reference object
|
||||
obj = cls(*initargs)
|
||||
|
||||
# Fetch state
|
||||
state_versions = self.load_state_from_disk(cls)
|
||||
|
||||
for version in state_versions:
|
||||
|
||||
# For each version inflate a new object and ensure that it
|
||||
# matches the original.
|
||||
|
||||
newargs = version['newargs']
|
||||
initargs = version['initargs']
|
||||
state = version['obj_state']
|
||||
|
||||
if newargs is not None:
|
||||
obj2 = cls.__new__(cls, *newargs)
|
||||
else:
|
||||
obj2 = cls.__new__(cls)
|
||||
if initargs is not None:
|
||||
obj2.__init__(*initargs)
|
||||
obj2.__setstate__(state)
|
||||
|
||||
# The ObjectId generated on instantiation of Order will
|
||||
# not be the same as the one loaded from saved state.
|
||||
if cls == Order:
|
||||
obj.__dict__['id'] = obj2.__dict__['id']
|
||||
|
||||
if comparison_method == 'repr':
|
||||
self.assertEqual(obj.__repr__(), obj2.__repr__())
|
||||
elif comparison_method == 'to_dict':
|
||||
self.assertEqual(obj.to_dict(), obj2.to_dict())
|
||||
else:
|
||||
self.assertEqual(obj.__dict__, obj2.__dict__)
|
||||
@@ -19,7 +19,7 @@ from copy import copy
|
||||
from logbook import Logger
|
||||
from collections import defaultdict
|
||||
|
||||
from six import text_type
|
||||
from six import text_type, iteritems
|
||||
from six.moves import filter
|
||||
|
||||
import zipline.errors
|
||||
@@ -35,6 +35,9 @@ from zipline.finance.commission import PerShare
|
||||
log = Logger('Blotter')
|
||||
|
||||
from zipline.utils.protocol_utils import Enum
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
ORDER_STATUS = Enum(
|
||||
'OPEN',
|
||||
@@ -247,6 +250,37 @@ class Blotter(object):
|
||||
|
||||
yield txn, order
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_to_save = ['new_orders', 'orders', '_status']
|
||||
|
||||
state_dict = {k: self.__dict__[k] for k in state_to_save
|
||||
if k in self.__dict__}
|
||||
|
||||
# Have to handle defaultdicts specially
|
||||
state_dict['open_orders'] = dict(self.open_orders)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
self.__init__()
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Blotter saved is state too old.")
|
||||
|
||||
open_orders = defaultdict(list)
|
||||
open_orders.update(state.pop('open_orders'))
|
||||
self.open_orders = open_orders
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class Order(object):
|
||||
def __init__(self, dt, sid, amount, stop=None, limit=None, filled=0,
|
||||
@@ -385,3 +419,26 @@ class Order(object):
|
||||
Unicode representation for this object.
|
||||
"""
|
||||
return text_type(repr(self))
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
state_dict['_status'] = self._status
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Order saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from six import iteritems
|
||||
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
|
||||
class PerShare(object):
|
||||
"""
|
||||
@@ -50,6 +56,27 @@ class PerShare(object):
|
||||
commission = max(commission, self.min_trade_cost)
|
||||
return abs(commission / transaction.amount), commission
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("PerShare saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class PerTrade(object):
|
||||
"""
|
||||
@@ -77,6 +104,27 @@ class PerTrade(object):
|
||||
|
||||
return abs(self.cost / transaction.amount), self.cost
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("PerTrade saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class PerDollar(object):
|
||||
"""
|
||||
@@ -103,3 +151,24 @@ class PerDollar(object):
|
||||
"""
|
||||
cost_per_share = transaction.price * self.cost
|
||||
return cost_per_share, abs(transaction.amount) * cost_per_share
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("PerDollar saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
@@ -92,6 +92,10 @@ from six import iteritems, itervalues
|
||||
import zipline.protocol as zp
|
||||
from . position import positiondict
|
||||
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
log = logbook.Logger('Performance')
|
||||
TRADE_TYPE = zp.DATASOURCE_TYPE.TRADE
|
||||
|
||||
@@ -574,3 +578,63 @@ class PerformancePeriod(object):
|
||||
if pos.amount != 0:
|
||||
positions.append(pos.to_dict())
|
||||
return positions
|
||||
|
||||
def __getstate__(self):
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
state_dict['_portfolio_store'] = self._portfolio_store
|
||||
state_dict['_account_store'] = self._account_store
|
||||
|
||||
# We need to handle the defaultdict specially, otherwise
|
||||
# msgpack will unpack it as a dict, causing KeyError
|
||||
# nastiness.
|
||||
state_dict['processed_transactions'] = \
|
||||
dict(self.processed_transactions)
|
||||
state_dict['orders_by_id'] = \
|
||||
dict(self.orders_by_id)
|
||||
state_dict['orders_by_modified'] = \
|
||||
dict(self.orders_by_modified)
|
||||
state_dict['positions'] = \
|
||||
dict(self.positions)
|
||||
state_dict['_positions_store'] = \
|
||||
dict(self._positions_store)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("PerformancePeriod saved state is too old.")
|
||||
|
||||
processed_transactions = defaultdict(list)
|
||||
processed_transactions.update(state.pop('processed_transactions'))
|
||||
|
||||
orders_by_id = OrderedDict()
|
||||
orders_by_id.update(state.pop('orders_by_id'))
|
||||
|
||||
orders_by_modified = defaultdict(OrderedDict)
|
||||
orders_by_modified.update(state.pop('orders_by_modified'))
|
||||
|
||||
positions = positiondict()
|
||||
positions.update(state.pop('positions'))
|
||||
|
||||
_positions_store = zp.Positions()
|
||||
_positions_store.update(state.pop('_positions_store'))
|
||||
|
||||
self.processed_transactions = processed_transactions
|
||||
self.orders_by_id = orders_by_id
|
||||
self.orders_by_modified = orders_by_modified
|
||||
self.positions = positions
|
||||
self._positions_store = _positions_store
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
self.initialize_position_calc_arrays()
|
||||
|
||||
@@ -38,9 +38,15 @@ from math import (
|
||||
floor,
|
||||
)
|
||||
|
||||
from copy import copy
|
||||
|
||||
import logbook
|
||||
import zipline.protocol as zp
|
||||
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
log = logbook.Logger('Performance')
|
||||
|
||||
|
||||
@@ -207,6 +213,25 @@ last_sale_price: {last_sale_price}"
|
||||
'last_sale_price': self.last_sale_price
|
||||
}
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Position saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class positiondict(dict):
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ Performance Tracking
|
||||
|
||||
from __future__ import division
|
||||
import logbook
|
||||
import pickle
|
||||
from six import iteritems
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
@@ -70,6 +72,9 @@ from zipline.finance import trading
|
||||
from . period import PerformancePeriod
|
||||
|
||||
from zipline.finance.trading import with_environment
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
log = logbook.Logger('Performance')
|
||||
|
||||
@@ -483,3 +488,38 @@ class PerformanceTracker(object):
|
||||
|
||||
risk_dict = self.risk_report.to_dict()
|
||||
return risk_dict
|
||||
|
||||
def __getstate__(self):
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
state_dict['dividend_frame'] = pickle.dumps(self.dividend_frame)
|
||||
|
||||
state_dict['_dividend_count'] = self._dividend_count
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("PerformanceTracker saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
# Handle the dividend frame specially
|
||||
self.dividend_frame = pickle.loads(state['dividend_frame'])
|
||||
|
||||
# We have to restore the references to the objects,
|
||||
# as the perf periods have been reconstructed as different objects
|
||||
# with the same values.
|
||||
self.perf_periods[0] = self.cumulative_performance
|
||||
self.perf_periods[1] = self.todays_performance
|
||||
if self.sim_params.emission_rate == 'minute':
|
||||
self.perf_periods[2] = self.minute_performance
|
||||
|
||||
@@ -35,6 +35,10 @@ from . risk import (
|
||||
sortino_ratio,
|
||||
)
|
||||
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
log = logbook.Logger('Risk Cumulative')
|
||||
|
||||
|
||||
@@ -454,3 +458,28 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
|
||||
beta = algorithm_covariance / benchmark_variance
|
||||
|
||||
return beta
|
||||
|
||||
def __getstate__(self):
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__) if
|
||||
(not k.startswith('_') and not k == 'treasury_curves')}
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("RiskMetricsCumulative \
|
||||
saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
# This are big and we don't need to serialize them
|
||||
# pop them back in now
|
||||
self.treasury_curves = trading.environment.treasury_curves
|
||||
|
||||
@@ -36,6 +36,10 @@ from . risk import (
|
||||
sortino_ratio,
|
||||
)
|
||||
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
log = logbook.Logger('Risk Period')
|
||||
|
||||
choose_treasury = functools.partial(risk.choose_treasury,
|
||||
@@ -304,3 +308,26 @@ class RiskMetricsPeriod(object):
|
||||
return 0.0
|
||||
|
||||
return 1.0 - math.exp(max_drawdown)
|
||||
|
||||
def __getstate__(self):
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__) if
|
||||
(not k.startswith('_') and not k == 'treasury_curves')}
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("RiskMetricsPeriod saved state \
|
||||
is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
self.treasury_curves = trading.environment.treasury_curves
|
||||
|
||||
@@ -58,9 +58,14 @@ Risk Report
|
||||
import logbook
|
||||
import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from six import iteritems
|
||||
|
||||
from . period import RiskMetricsPeriod
|
||||
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
log = logbook.Logger('Risk Report')
|
||||
|
||||
|
||||
@@ -138,3 +143,26 @@ class RiskReport(object):
|
||||
cur_start = cur_start + relativedelta(months=1)
|
||||
|
||||
return ends
|
||||
|
||||
def __getstate__(self):
|
||||
state_dict = \
|
||||
{k: v for k, v in iteritems(self.__dict__)
|
||||
if not k.startswith('_')}
|
||||
|
||||
if '_dividend_count' in dir(self):
|
||||
state_dict['_dividend_count'] = self._dividend_count
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("RiskReport saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
@@ -24,6 +24,9 @@ from functools import partial
|
||||
from six import with_metaclass
|
||||
|
||||
from zipline.protocol import DATASOURCE_TYPE
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
SELL = 1 << 0
|
||||
BUY = 1 << 1
|
||||
@@ -128,6 +131,25 @@ class Transaction(object):
|
||||
del py['type']
|
||||
return py
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Transaction saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
def create_transaction(event, order, price, amount):
|
||||
|
||||
@@ -246,6 +268,25 @@ class VolumeShareSlippage(SlippageModel):
|
||||
math.copysign(cur_volume, order.direction)
|
||||
)
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("VolumeShareSlippage saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class FixedSlippage(SlippageModel):
|
||||
|
||||
@@ -264,3 +305,22 @@ class FixedSlippage(SlippageModel):
|
||||
event.price + (self.spread / 2.0 * order.direction),
|
||||
order.amount,
|
||||
)
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("FixedSlippage saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
+66
-4
@@ -13,6 +13,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from copy import copy
|
||||
|
||||
from six import iteritems, iterkeys
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
@@ -22,6 +24,9 @@ from . utils.math_utils import nanstd, nanmean, nansum
|
||||
|
||||
from zipline.finance.trading import with_environment
|
||||
from zipline.utils.algo_instance import get_algo_instance
|
||||
from zipline.utils.serialization_utils import (
|
||||
VERSION_LABEL
|
||||
)
|
||||
|
||||
# Datasource type should completely determine the other fields of a
|
||||
# message with its type.
|
||||
@@ -138,6 +143,31 @@ class Portfolio(object):
|
||||
def __repr__(self):
|
||||
return "Portfolio({0})".format(self.__dict__)
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
# Have to convert to primitive dict
|
||||
state_dict['positions'] = dict(self.positions)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Portfolio saved state is too old.")
|
||||
|
||||
self.positions = Positions()
|
||||
self.positions.update(state.pop('positions'))
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class Account(object):
|
||||
'''
|
||||
@@ -171,11 +201,24 @@ class Account(object):
|
||||
def __repr__(self):
|
||||
return "Account({0})".format(self.__dict__)
|
||||
|
||||
def _get_state(self):
|
||||
return 'Account', self.__dict__
|
||||
def __getstate__(self):
|
||||
|
||||
def _set_state(self, saved_state):
|
||||
self.__dict__.update(saved_state)
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Account saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class Position(object):
|
||||
@@ -192,6 +235,25 @@ class Position(object):
|
||||
def __repr__(self):
|
||||
return "Position({0})".format(self.__dict__)
|
||||
|
||||
def __getstate__(self):
|
||||
|
||||
state_dict = copy(self.__dict__)
|
||||
|
||||
STATE_VERSION = 1
|
||||
state_dict[VERSION_LABEL] = STATE_VERSION
|
||||
|
||||
return state_dict
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
||||
OLDEST_SUPPORTED_STATE = 1
|
||||
version = state.pop(VERSION_LABEL)
|
||||
|
||||
if version < OLDEST_SUPPORTED_STATE:
|
||||
raise BaseException("Protocol Position saved state is too old.")
|
||||
|
||||
self.__dict__.update(state)
|
||||
|
||||
|
||||
class Positions(dict):
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Label for the serialization version field in the state returned by
|
||||
# __getstate__.
|
||||
VERSION_LABEL = '_stateversion_'
|
||||
Reference in New Issue
Block a user