Mariner Backtesting - Limit Orders examples

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

See also: GUIDs for LMT orders

(LMT)

A limit order (LMT) sets the worst price at which an order should be executed. Fills on the order may be at a better price, but never at one worse than the order specifies. * Buy limit: The highest price that the order may be filled. * Sell limit: The lowest price that the order may be filled.

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


class LimitOrder(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,45), timer_id='exit')

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

        if event.timer_id == 'enter':
            # Send Order, algorithm: Sell Limit ARCA PL at Script Price
            # PL: Passive liquidity - Offer below the bid
            # selling at 15 cents over the current bid
            order_id = order.algo_sell(self.symbol, "9a024e60-b53c-43e7-a3e0-2a5600d732dc",
                                       intent="init", order_quantity=100, price=md.L1.bid + .15)

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

        else:

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

            if account[self.symbol].position.capital_short != 0.00:

                # Send exit order
                # Algorithm: Buy Market ARCA
                order.algo_buy(self.symbol, '2b4fdc55-ff01-416e-a5ea-e1f1d4524c7d', intent='exit')


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

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

            # after a position has been entered place an limit exit order
            # algorithm: Buy Limit ARCA PL at Script Price
            order.algo_buy(self.symbol, "e3ad53b9-4195-4c68-8407-f38be2a94f04", intent='exit', price=md.L1.bid - .15)

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

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

Console

AAPL    2016-12-12 09:25:00.000000  in on_start()
GDX 2016-12-12 09:25:00.000000  in on_start()
JNUG    2016-12-12 09:25:00.000000  in on_start()
NUGT    2016-12-12 09:25:00.000000  in on_start()
SPY 2016-12-12 09:25:00.000000  in on_start()
XLF 2016-12-12 09:25:00.000000  in on_start()
AAPL    2016-12-12 09:33:00.000000  order number: 0000000000000001

GDX 2016-12-12 09:33:00.000000  order number: 0000000000000002

JNUG    2016-12-12 09:33:00.000000  order number: 0000000000000003

NUGT    2016-12-12 09:33:00.000000  order number: 0000000000000004

SPY 2016-12-12 09:33:00.000000  order number: 0000000000000005

XLF 2016-12-12 09:33:00.000000  order number: 0000000000000006

SELL    SPY 2016-12-12 09:49:55.613000  in on_fill()
FillEvent(instruction_id='48f023cf-3993-5f62-951f-306da83ac2d4', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='48f023cf-3993-5f62-951f-306da83ac2d4', order_id='0000000000000005', state='F', price=226.58999633789062, shares=-100, timestamp=1481554195613000, symbol='SPY', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='LimitOrder', line_number=27, kind=8) 

BUY SPY 2016-12-12 10:16:40.224000  in on_fill()
FillEvent(instruction_id='48f023cf-3993-5f62-951f-306da83ac2d4', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='48f023cf-3993-5f62-951f-306da83ac2d4', order_id='0000000000000007', state='F', price=226.44000244140625, shares=100, timestamp=1481555800224000, symbol='SPY', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='LimitOrder', line_number=55, kind=8) 

SELL    NUGT    2016-12-12 10:28:43.901000  in on_fill()
FillEvent(instruction_id='9a011276-e9e2-501d-a378-6d0ebeacb26a', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='9a011276-e9e2-501d-a378-6d0ebeacb26a', order_id='0000000000000004', state='F', price=7.96, shares=-100, timestamp=1481556523901000, symbol='NUGT', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='LimitOrder', line_number=27, kind=8) 

SELL    GDX 2016-12-12 10:29:08.237000  in on_fill()
FillEvent(instruction_id='18788ec1-15f2-52ee-973d-43ff9b22c3bf', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='18788ec1-15f2-52ee-973d-43ff9b22c3bf', order_id='0000000000000002', state='F', price=20.940000534057617, shares=-100, timestamp=1481556548237000, symbol='GDX', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='LimitOrder', line_number=27, kind=8) 

BUY GDX 2016-12-12 10:57:39.836000  in on_fill()
FillEvent(instruction_id='18788ec1-15f2-52ee-973d-43ff9b22c3bf', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='18788ec1-15f2-52ee-973d-43ff9b22c3bf', order_id='0000000000000009', state='F', price=20.790000915527344, shares=100, timestamp=1481558259836000, symbol='GDX', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='LimitOrder', line_number=55, kind=8) 

BUY NUGT    2016-12-12 10:59:27.227000  in on_fill()
FillEvent(instruction_id='9a011276-e9e2-501d-a378-6d0ebeacb26a', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='9a011276-e9e2-501d-a378-6d0ebeacb26a', order_id='0000000000000008', state='F', price=7.7999997, shares=100, timestamp=1481558367227000, symbol='NUGT', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='LimitOrder', line_number=55, kind=8) 

SELL    JNUG    2016-12-12 12:06:00.077000  in on_fill()
FillEvent(instruction_id='cfaba6bd-0016-502e-9b66-3452e55648b5', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='cfaba6bd-0016-502e-9b66-3452e55648b5', order_id='0000000000000003', state='F', price=6.8600001, shares=-100, timestamp=1481562360077000, symbol='JNUG', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='LimitOrder', line_number=27, kind=8) 

SELL    AAPL    2016-12-12 13:04:03.581000  in on_fill()
FillEvent(instruction_id='2939df7f-17de-598e-b5d2-8a01fea178d7', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='2939df7f-17de-598e-b5d2-8a01fea178d7', order_id='0000000000000001', state='F', price=113.27, shares=-100, timestamp=1481565843581000, symbol='AAPL', account_id=0, clordid=None, collect=None, intent='init', order_algorithm='limit', expected_direction='increase', actual_direction='increase', script_class_name='LimitOrder', line_number=27, kind=8) 

BUY AAPL    2016-12-12 13:31:16.027000  in on_fill()
FillEvent(instruction_id='2939df7f-17de-598e-b5d2-8a01fea178d7', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='2939df7f-17de-598e-b5d2-8a01fea178d7', order_id='0000000000000011', state='F', price=112.88, shares=100, timestamp=1481567476027000, symbol='AAPL', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='LimitOrder', line_number=55, kind=8) 

BUY JNUG    2016-12-12 15:18:29.762000  in on_fill()
FillEvent(instruction_id='cfaba6bd-0016-502e-9b66-3452e55648b5', script_id=u'e7b75f43-9fc4-4485-a144-fae5fe53e9bc', user_key='cfaba6bd-0016-502e-9b66-3452e55648b5', order_id='0000000000000010', state='F', price=6.6999998, shares=100, timestamp=1481573909762000, symbol='JNUG', account_id=0, clordid=None, collect=None, intent='exit', order_algorithm='limit', expected_direction='reduce', actual_direction='reduce', script_class_name='LimitOrder', line_number=55, kind=8)