Mariner Backtesting - Market on Close

MOC Guid Examples using order.algo_sell() and order.algo_buy()

see also: MOC GUIDs

Working Example:

# Copyright Cloudquant, LLC. All right reserved.
from cloudquant.interfaces import Strategy

class MarketOnClose(Strategy):

    @classmethod
    def is_symbol_qualified(cls, symbol, md, service, account):
        return symbol in ["SPY", "AAPL", "GDX", "NUGT", "XLF", "JNUG"]

    def on_start(self, md, order, service, account):
        # print start time and symbol
        print(self.symbol + "\t" + service.time_to_string(service.system_time) + "\tin on_start()")

        # add a timer to enter a position at 3:59
        service.add_time_trigger(service.time(15, 59))

    def on_fill(self, event, md, order, service, account):
        if event.shares > 0:
            print('BUY\t' + self.symbol + '\t' + service.time_to_string(event.timestamp) + "\tin on_fill()")

            # if shares have been bought, place the market on close order
            # algorithm: Sell Market ARCA MOC
            # Sell Arca Market On Close
            order.algo_sell(self.symbol, "28bfb89c-93f9-45b1-b414-f79aa16865c5", intent='exit')

        elif event.shares < 0:
            print('SELL\t' + self.symbol + '\t' + service.time_to_string(event.timestamp) + "\tin on_fill()")

        # print statement when an order fills
        print(event, '\n')

    def on_timer(self, event, md, order, service, account):

        # Send Order, algorithm: Buy Market ARCA
        order_id = order.algo_buy(self.symbol, "2b4fdc55-ff01-416e-a5ea-e1f1d4524c7d",
                                  intent="init", order_quantity=100)

        # print the symbol, time, and the order_id
        print(self.symbol + "\t" + service.time_to_string(event.timestamp) + "\torder number: " + order_id + "\n")

    def on_reject(self, event, md, order, service, account):
        print(service.time_to_string(event.timestamp))
        print(event)

Console

GDX 2017-01-31 09:25:00.000000  in on_start()
JNUG    2017-01-31 09:25:00.000000  in on_start()
NUGT    2017-01-31 09:25:00.000000  in on_start()
SPY 2017-01-31 09:25:00.000000  in on_start()
XLF 2017-01-31 09:25:00.000000  in on_start()
GDX 2017-01-31 15:58:00.000000  order number: 0000000000000001

JNUG    2017-01-31 15:58:00.000000  order number: 0000000000000002

NUGT    2017-01-31 15:58:00.000000  order number: 0000000000000003

SPY 2017-01-31 15:58:00.000000  order number: 0000000000000004

XLF 2017-01-31 15:58:00.000000  order number: 0000000000000005

BUY GDX 2017-01-31 15:58:00.001700  in on_fill()
FillEvent(instruction_id='c64018ed-7d88-5682-aaec-b31270f8b1ac', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='c64018ed-7d88-5682-aaec-b31270f8b1ac', order_id='0000000000000001', state='F', price=23.850000381469727, shares=100, timestamp=1485896280001700, symbol='GDX', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='market', expected_direction='increase', actual_direction='increase', script_class_name='MarketOnClose', line_number=36, kind=8)

BUY JNUG    2017-01-31 15:58:00.001700  in on_fill()
FillEvent(instruction_id='6bbec185-0a50-5055-9719-4e59e5714659', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='6bbec185-0a50-5055-9719-4e59e5714659', order_id='0000000000000002', state='F', price=8.880000114440918, shares=100, timestamp=1485896280001700, symbol='JNUG', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='market', expected_direction='increase', actual_direction='increase', script_class_name='MarketOnClose', line_number=36, kind=8)

BUY NUGT    2017-01-31 15:58:00.001700  in on_fill()
FillEvent(instruction_id='260e3026-27aa-52ec-8e62-28f4c52ab31d', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='260e3026-27aa-52ec-8e62-28f4c52ab31d', order_id='0000000000000003', state='F', price=11.010000228881836, shares=100, timestamp=1485896280001700, symbol='NUGT', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='market', expected_direction='increase', actual_direction='increase', script_class_name='MarketOnClose', line_number=36, kind=8)

BUY SPY 2017-01-31 15:58:00.001700  in on_fill()
FillEvent(instruction_id='f767195e-03be-51bf-a5f2-1a683d01c9f2', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='f767195e-03be-51bf-a5f2-1a683d01c9f2', order_id='0000000000000004', state='F', price=227.33999633789062, shares=100, timestamp=1485896280001700, symbol='SPY', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='market', expected_direction='increase', actual_direction='increase', script_class_name='MarketOnClose', line_number=36, kind=8)

BUY XLF 2017-01-31 15:58:00.001700  in on_fill()
FillEvent(instruction_id='f6dbd57f-70e4-5996-900b-d9661b64e9fe', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='f6dbd57f-70e4-5996-900b-d9661b64e9fe', order_id='0000000000000005', state='F', price=23.299999237060547, shares=100, timestamp=1485896280001700, symbol='XLF', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='market', expected_direction='increase', actual_direction='increase', script_class_name='MarketOnClose', line_number=36, kind=8)

SELL    XLF 2017-01-31 16:00:00.008000  in on_fill()
FillEvent(instruction_id='f6dbd57f-70e4-5996-900b-d9661b64e9fe', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='f6dbd57f-70e4-5996-900b-d9661b64e9fe', order_id='0000000000000010', state='F', price=23.309999465942383, shares=-100, timestamp=1485896400008000, symbol='XLF', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='28bfb89c-93f9-45b1-b414-f79aa16865c5', expected_direction='reduce', actual_direction='reduce', script_class_name='MarketOnClose', line_number=24, kind=8)

SELL    JNUG    2017-01-31 16:00:00.061000  in on_fill()
FillEvent(instruction_id='6bbec185-0a50-5055-9719-4e59e5714659', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='6bbec185-0a50-5055-9719-4e59e5714659', order_id='0000000000000007', state='F', price=8.930000305175781, shares=-100, timestamp=1485896400061000, symbol='JNUG', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='28bfb89c-93f9-45b1-b414-f79aa16865c5', expected_direction='reduce', actual_direction='reduce', script_class_name='MarketOnClose', line_number=24, kind=8)

SELL    NUGT    2017-01-31 16:00:00.069000  in on_fill()
FillEvent(instruction_id='260e3026-27aa-52ec-8e62-28f4c52ab31d', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='260e3026-27aa-52ec-8e62-28f4c52ab31d', order_id='0000000000000008', state='F', price=11.079999923706055, shares=-100, timestamp=1485896400069000, symbol='NUGT', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='28bfb89c-93f9-45b1-b414-f79aa16865c5', expected_direction='reduce', actual_direction='reduce', script_class_name='MarketOnClose', line_number=24, kind=8)

SELL    GDX 2017-01-31 16:00:00.119000  in on_fill()
FillEvent(instruction_id='c64018ed-7d88-5682-aaec-b31270f8b1ac', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='c64018ed-7d88-5682-aaec-b31270f8b1ac', order_id='0000000000000006', state='F', price=23.93000030517578, shares=-100, timestamp=1485896400119000, symbol='GDX', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='28bfb89c-93f9-45b1-b414-f79aa16865c5', expected_direction='reduce', actual_direction='reduce', script_class_name='MarketOnClose', line_number=24, kind=8)

SELL    SPY 2017-01-31 16:00:00.124000  in on_fill()
FillEvent(instruction_id='f767195e-03be-51bf-a5f2-1a683d01c9f2', script_id=u'73ac79e2-e8a6-4c25-bee5-c6c6ac6686ce', user_key='f767195e-03be-51bf-a5f2-1a683d01c9f2', order_id='0000000000000009', state='F', price=227.52999877929688, shares=-100, timestamp=1485896400124000, symbol='SPY', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='28bfb89c-93f9-45b1-b414-f79aa16865c5', expected_direction='reduce', actual_direction='reduce', script_class_name='MarketOnClose', line_number=24, kind=8)