From 1d9953255a21783ce96ae7006ce0b204e05b980b Mon Sep 17 00:00:00 2001 From: fawce Date: Fri, 20 Apr 2012 23:41:23 -0400 Subject: [PATCH] added stop out for max drawdown. --- zipline/finance/performance.py | 20 ++++++++++++++++---- zipline/finance/trading.py | 4 ++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/zipline/finance/performance.py b/zipline/finance/performance.py index 351466a8..e90d4e0d 100644 --- a/zipline/finance/performance.py +++ b/zipline/finance/performance.py @@ -154,6 +154,7 @@ class PerformanceTracker(): self.result_stream = None self.last_dict = None self.order_log = [] + self.exceeded_max_loss = False # this performance period will span the entire simulation. self.cumulative_performance = PerformancePeriod( @@ -267,7 +268,17 @@ class PerformanceTracker(): if self.result_stream: msg = zp.PERF_FRAME(self.to_dict()) self.result_stream.send(msg) - + + # check the day's returns versus the max drawdown + max_dd = -1 * self.trading_environment.max_drawdown + if self.todays_performance.returns < max_dd: + qutil.LOGGER.info("Exceeded max drawdown.") + # TODO: any other information we need to relay on the + # result socket? + self.exceeded_max_loss = True + self.handle_simulation_end(skip_close=True) + return + #move the market day markers forward self.market_open = self.market_open + self.calendar_day @@ -288,7 +299,7 @@ class PerformanceTracker(): keep_transactions = True ) - def handle_simulation_end(self): + def handle_simulation_end(self, skip_close=False): """ When the simulation is complete, run the full period risk report and send it out on the result_stream. @@ -300,8 +311,9 @@ class PerformanceTracker(): # the stream will end on the last trading day, but will not trigger # an end of day, so we trigger the final market close here. - self.handle_market_close() - + # In the case of errors, we needn't close again. + if not skip_close: + self.handle_market_close() self.risk_report = risk.RiskReport( self.returns, diff --git a/zipline/finance/trading.py b/zipline/finance/trading.py index 9c815156..b503e501 100644 --- a/zipline/finance/trading.py +++ b/zipline/finance/trading.py @@ -99,6 +99,10 @@ class TradeSimulationClient(qmsg.Component): def process_event(self, event): + if self.perf.exceeded_max_loss: + self.control_out.send(str(zp.CONTROL_PROTOCOL.SHUTDOWN)) + return + # generate transactions, if applicable txn = self.txn_sim.apply_trade_to_open_orders(event) if txn: