Mariner Backtesting - Peg Orders

Example Pegged orders using order.algo_buy() and order.algo_sell()

See also: PEG Order GUIDs

Working Example:

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


class PrimPeg(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 9:33
        service.add_time_trigger(service.time(9, 33), timer_id='enter')

        # add a timer to exit any position held at the end of the day
        service.add_time_trigger(service.time(15, 59, 35), repeat_interval=service.time_interval(seconds=5),
                                 timer_id='exit')

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

        if event.timer_id == 'enter':
            # Send Order, algorithm: Buy Limit ARCA at Script Price - Prim Peg
            # Buy at pegged to midpoint price, starting price determine by script + 2 cents
            order.algo_buy(self.symbol, "0adb00e8-c057-453d-b3fe-d89303c4e9ca",
                           intent="init", order_quantity=100, price=md.L1.ask - .15)

            # print the symbol, time, and the order_id
            print("\nPeg Buy Order Placed\t" + self.symbol + "\t" + service.time_to_string(event.timestamp))

        else:

            # Cancel the buy order
            order.cancel(self.symbol)

            # check if a long position is held
            if account[self.symbol].position.capital_long != 0.00:
                # Send exit order
                # Algorithm: Sell Market ARCA
                order.algo_sell(self.symbol, '8fdee8fe-b772-46bd-b411-5544f7a0d917', intent='exit')

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

            # after a position has been entered place an limit order to cover position
            # algorithm: Sell Limit ARCA at Script Price - Prim Peg
            #
            order.algo_sell(self.symbol, "fc0b4b9f-920a-46a6-b4f3-c11c49bbcfd6", intent='exit', price=md.L1.bid + .15)

            # print the symbol and time
            print("\nPeg Sell Order Placed\t" + self.symbol + "\t" + service.time_to_string(event.timestamp))

            # if shares are sold
        elif event.shares < 0:
            print('\nSELL\t' + self.symbol + '\t' + service.time_to_string(event.timestamp) + "\tin on_fill()")

        # print statement when an order fills
        print('\n', service.time_to_string(event.timestamp), event)

Console

AAPL    2016-12-12 09:30:00.000000  in on_start()
GDX 2016-12-12 09:30:00.000000  in on_start()
JNUG    2016-12-12 09:30:00.000000  in on_start()
NUGT    2016-12-12 09:30:00.000000  in on_start()
SPY 2016-12-12 09:30:00.000000  in on_start()
XLF 2016-12-12 09:30:00.000000  in on_start()

Peg Buy Order Placed    AAPL    2016-12-12 09:33:00.000000

Peg Buy Order Placed    GDX 2016-12-12 09:33:00.000000

Peg Buy Order Placed    JNUG    2016-12-12 09:33:00.000000

Peg Buy Order Placed    NUGT    2016-12-12 09:33:00.000000

Peg Buy Order Placed    SPY 2016-12-12 09:33:00.000000

Peg Buy Order Placed    XLF 2016-12-12 09:33:00.000000

BUY SPY 2016-12-12 09:33:12.397000  in on_fill()

Peg Sell Order Placed   SPY 2016-12-12 09:33:12.397000

2016-12-12 09:33:12.397000 FillEvent(instruction_id='469793be-1b5c-5fe5-8814-da4a86a7f817', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='469793be-1b5c-5fe5-8814-da4a86a7f817', order_id='0000000000000005', state='F', price=226.3000030517578, shares=100, timestamp=1481553192397000, symbol='SPY', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='PeggedToMidpoint', line_number=27, kind=8)

BUY AAPL    2016-12-12 09:33:39.764000  in on_fill()

Peg Sell Order Placed   AAPL    2016-12-12 09:33:39.764000

2016-12-12 09:33:39.764000 FillEvent(instruction_id='e512704e-0681-586a-b3d6-89437553bdd7', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='e512704e-0681-586a-b3d6-89437553bdd7', order_id='0000000000000001', state='F', price=112.98, shares=100, timestamp=1481553219764000, symbol='AAPL', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='PeggedToMidpoint', line_number=27, kind=8)

SELL    SPY 2016-12-12 09:35:13.472000  in on_fill()

2016-12-12 09:35:13.472000 FillEvent(instruction_id='469793be-1b5c-5fe5-8814-da4a86a7f817', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='469793be-1b5c-5fe5-8814-da4a86a7f817', order_id='0000000000000007', state='F', price=226.43999, shares=-100, timestamp=1481553313472000, symbol='SPY', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='PeggedToMidpoint', line_number=51, kind=8)

BUY JNUG    2016-12-12 09:44:49.462000  in on_fill()

Peg Sell Order Placed   JNUG    2016-12-12 09:44:49.462000

2016-12-12 09:44:49.462000 FillEvent(instruction_id='a57e04b8-e649-5717-aaec-fd6efbf3f8df', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='a57e04b8-e649-5717-aaec-fd6efbf3f8df', order_id='0000000000000003', state='F', price=6.5799999, shares=100, timestamp=1481553889462000, symbol='JNUG', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='PeggedToMidpoint', line_number=27, kind=8)

BUY NUGT    2016-12-12 09:46:18.616000  in on_fill()

Peg Sell Order Placed   NUGT    2016-12-12 09:46:18.616000

2016-12-12 09:46:18.616000 FillEvent(instruction_id='c8560684-b900-56bc-b693-08c7b077b376', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='c8560684-b900-56bc-b693-08c7b077b376', order_id='0000000000000004', state='F', price=7.6700001, shares=100, timestamp=1481553978616000, symbol='NUGT', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='PeggedToMidpoint', line_number=27, kind=8)

BUY GDX 2016-12-12 09:49:17.208000  in on_fill()

Peg Sell Order Placed   GDX 2016-12-12 09:49:17.208000

2016-12-12 09:49:17.208000 FillEvent(instruction_id='5db2d2f0-d4d4-5bc9-b56a-0d4d998df92b', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='5db2d2f0-d4d4-5bc9-b56a-0d4d998df92b', order_id='0000000000000002', state='F', price=20.649999618530273, shares=100, timestamp=1481554157208000, symbol='GDX', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='PeggedToMidpoint', line_number=27, kind=8)

SELL    AAPL    2016-12-12 09:49:57.388000  in on_fill()

2016-12-12 09:49:57.388000 FillEvent(instruction_id='e512704e-0681-586a-b3d6-89437553bdd7', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='e512704e-0681-586a-b3d6-89437553bdd7', order_id='0000000000000008', state='F', price=113.12, shares=-100, timestamp=1481554197388000, symbol='AAPL', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='PeggedToMidpoint', line_number=51, kind=8)

SELL    GDX 2016-12-12 10:25:03.138000  in on_fill()

2016-12-12 10:25:03.138000 FillEvent(instruction_id='5db2d2f0-d4d4-5bc9-b56a-0d4d998df92b', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='5db2d2f0-d4d4-5bc9-b56a-0d4d998df92b', order_id='0000000000000011', state='F', price=20.789999, shares=-100, timestamp=1481556303138000, symbol='GDX', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='PeggedToMidpoint', line_number=51, kind=8)

SELL    NUGT    2016-12-12 10:25:06.528000  in on_fill()

2016-12-12 10:25:06.528000 FillEvent(instruction_id='c8560684-b900-56bc-b693-08c7b077b376', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='c8560684-b900-56bc-b693-08c7b077b376', order_id='0000000000000010', state='F', price=7.8200002, shares=-100, timestamp=1481556306528000, symbol='NUGT', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='PeggedToMidpoint', line_number=51, kind=8)

SELL    JNUG    2016-12-12 10:28:35.610000  in on_fill()

2016-12-12 10:28:35.610000 FillEvent(instruction_id='a57e04b8-e649-5717-aaec-fd6efbf3f8df', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='a57e04b8-e649-5717-aaec-fd6efbf3f8df', order_id='0000000000000009', state='F', price=6.73, shares=-100, timestamp=1481556515610000, symbol='JNUG', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='PeggedToMidpoint', line_number=51, kind=8)

BUY XLF 2016-12-12 11:44:39.562000  in on_fill()

Peg Sell Order Placed   XLF 2016-12-12 11:44:39.562000

2016-12-12 11:44:39.562000 FillEvent(instruction_id='6cf9e581-7baa-5932-a69c-944065cbcd91', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='6cf9e581-7baa-5932-a69c-944065cbcd91', order_id='0000000000000006', state='F', price=23.56999969482422, shares=100, timestamp=1481561079562000, symbol='XLF', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='PeggedToMidpoint', line_number=27, kind=8)

2016-12-12 15:59:35.000700 CancelEvent(instruction_id='6cf9e581-7baa-5932-a69c-944065cbcd91', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='6cf9e581-7baa-5932-a69c-944065cbcd91', order_id='0000000000000012', state='C', price=23.70999946594238, shares=-100, reason='Cancelled by user', timestamp=1481576375000700, symbol='XLF', account_id=0, clordid=None, intent='exit', order_algorithm='limit', expected_direction=None, script_class_name='PeggedToMidpoint', line_number=51, kind=6)

SELL    XLF 2016-12-12 15:59:35.001700  in on_fill()

2016-12-12 15:59:35.001700 FillEvent(instruction_id='6cf9e581-7baa-5932-a69c-944065cbcd91', script_id=u'e48769e8-169d-4ddc-bd31-c2efd1a325ea', user_key='6cf9e581-7baa-5932-a69c-944065cbcd91', order_id='0000000000000013', state='F', price=23.520000457763672, shares=-100, timestamp=1481576375001700, symbol='XLF', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='market', expected_direction='reduce', actual_direction='reduce', script_class_name='PeggedToMidpoint', line_number=41, kind=8)