Mariner Backtesting - Strategy.on_save()

save event -

on_save() is called when the strategy needs to temporarily stop executing (e.g. needs to hibernate). This method should store data in the given state_dict dictionary that will be saved until the next simulation day.

on_save() and on_restore() are only allowed for backtests that check the "Use Specific Symbols" box and specify a list of symbols. If the is_symbol_qualified() function is used to determine which symbols to backtest, on_save() and on_restore() will not be called.

Interface:
 on_save(state_dict)
Parameters:
Name Type Default Information
state_dict dictionary required This method will be called after service.hibernate() is used. service.hibernate() stops the strategy from executing until the next simulation day. Any data that needs to be saved for the next simulation day should be saved in this dictionary. Any data put into this dictionary will be saved until on_restore() is called. This dictionary will be given to on_restore() when it is called. on_save() will not be called if the is_symbol_qualified() function is used to determine which symbols to backtest.
Remarks:
  • Populates a dictionary of data to save.
  • This method does not have access to market data, orders, or account data.
  • Used in combination with the on_restore() method that takes previously saved data and uses it.
Working Example:

Backtest as a single multiday job. Backtest for at least 2 days.

 from cloudquant.interfaces import Strategy


class RestoreData(Strategy):
    # called at the beginning of each instance
    def on_start(self, md, order, service, account):
        print 'in on_start\t' + service.time_to_string(service.system_time) + '\n'

        # initialize data to be save in on_save()
        self.entry_price = 0
        self.shares = 0
        self.entry_time = service.system_time

        # enter a position if no position is held
        if account[self.symbol].position.capital_long == 0:
            order.algo_buy(self.symbol, 'market', 'init', order_quantity=100)
        # otherwise, exit the position and terminate
        else:
            print 'exit order sent, terminating\n'
            order.algo_sell(self.symbol, 'market', 'exit')
            service.terminate()

        # 3:55 PM.
        self.end_time = md.market_close_time - service.time_interval(minutes=5)

    def on_save(self, state_dict):
        # Add data values to state_dict to be saved
        state_dict['entry_time'] = self.entry_time
        state_dict['entry_price'] = self.entry_price
        state_dict['shares'] = self.shares

        print 'saving data', state_dict

    def on_restore(self, state_dict):
        # print the previously saved data
        print 'restoring data ', state_dict

    def on_finish(self, md, order, service, account):
        print '\nScript Ending at ' + service.time_to_string(service.system_time)

    def on_minute_bar(self, event, md, order, service, account, bar):
        # if the current time is after the end time for the script, set data values and hibernate
        if service.system_time > self.end_time:
            self.entry_price= account[self.symbol].position.entry_price
            self.shares = account[self.symbol].position.shares
            service.hibernate()

Day 1 Console

in on_start 2017-02-07 09:30:00.000000

saving data {'entry_price': 45.439998626708984, 'entry_time': 1486477800000000, 'shares': 100}

Script Ending at 2017-02-07 15:55:00.603000

Day 2 Console

in on_start 2017-02-08 09:30:00.000000

exit order sent, terminating

restoring data  {'entry_price': 45.439998626708984, 'entry_time': 1486477800000000, 'shares': 100}

Script Ending at 2017-02-08 09:30:00.001000