Mariner Backtesting - order.algo_sell()

Function to send a sell order.

Function to send a sell order.

Key Points:
  • symbol - can be the current symbol (ie self.symbol) or can be another symbol. For example you can run a script where you only qualify SPY and qualify other symbols as backtest symbols, then on a timer you sort the other symbols and send orders to them one at a time.
  • algorithm - for backtesting this will be simply market or limit. In live trading you will want to specify a particular market algorithm type. If you use one of these algo's and run a backtest the system will generally replace it with a default market or limit order (whichever is appropriate).
  • intent - you should specify your intent (init, increase, decrease, exit, reverse), then if your intent does not match what you are doing we can block the order. Prevents runaway scripts.
  • allow_multiple_pending - should only be used when dealing with multiple orders on the same side of the market, else they will be rejected. Should not be used to collar either side, main use would be to set up a series of limit orders at steps down or up from the current price.
  • user_key - can be used to create the account object based on that user_key
  • collect - only works in backtesting - construct a dictionary (key:data pair) containing the data you wish to collect with the order, ideal use would be entry criteria and exit criteria. Data will stored be in the trades.csv file with entry_yourkeys and exit_yourkeys. Example collect = {"bid":md.L1.bid,"ask":md.L1.ask,"rvol",md.L1.rvol}. Note : if you use the letters time in any of the keys in collect then that field will be formatted as a time, regardless of what it actually is!.
  • exit-script - a special feature of the system allows an entry order to start the exit script (Advanced)
  • The call of order.algo_sell() is queued until the current Strategy method returns from being called. In other words, the system doesn't process the order request until after returning from the system method (plus any market/data latency settings). So if you placed an order and immediately queried the Account object (ie account[self.symbol].position.shares or account[self.symbol].pending.shares_long or account[self.symbol].pending.shares_short) it would not show.
  • The account object is held constant until the current Strategy method returns from being called. In other words, the account won't reflect having a pending order if queried in the same callback as the order.algo_sell()
Interface:
 algo_sell(symbol,
          algorithm,
          intent,
          order_quantity=None,
          price=0.0,
          position_size=None,
          allow_multiple_pending=False,
          user_key=None,
          collect=None,
          exit_script=None,
          exit_options=None,
          exit_parameters=None)

Sample - Calling Method

 order.algo_sell(self.symbol, algorithm='8fdee8fe-b772-46bd-b411-5544f7a0d917', intent='init', order_quantity=100) # Sell Market ARCA
Parameters:
Name Type Default Information
symbol string required Symbol to be traded, can be current symbol ie self.symbol or can be any other qualified symbol.
algorithm string required Name of algorithm to use to process the order. For most backtesting this is simply limit or market. For live trading you will want to use a specific market algorithm
intent string required Intended position change. One of "none", "init", "increase", "decrease", "exit", "reverse".
  • "init" - Initiate a short position. Must be flat.
  • "increase" - Increase a short position. Must be flat or short.
  • "decrease" - Decrease a short position (Note: "order_quantity" > 0) . Must be short, not flat and not long. Will not cover more than short position.
  • "exit" - Using sell with Exit means you are exiting a long position - you must be long. Order_quantity is not permitted, it will cover the entire long position.
  • "reverse" - Reverse a long position to a short position. Must be long or flat. We recommend using "position_size" instead of "order_quantity" to specify desired position.
  • "none" - Skip intent check. In production, very few scripts uses this setting.
order_quantity integer None Number of shares to change by. Can't be used with position_size. Cannot be used if intent is exit.
price float 0.0 Desired purchase price. 0.0 indicates current market price.
position_size integer None Desired position size after order. This value is compared to the current position to decide whether to increase or decrease a position. Long position is positive number. Short position is negative number. Should not be supplied if intent is exit.
allow_multiple_pending boolean False Allow this order to proceed even if there are already pending orders on the same side of the market.
user_key string None User-selected key to attach to this order. Orders can be queried by key in the Account object.
collect dictionary None Additional fields to record along with this order. dict[str]->object
exit_script string None Name of strategy to instantiate to handle exiting the position created by this order.
exit_options dictionary None Control options for starting and stopping strategies. dict[str]->object
exit_parameters dictionary None Parameters to passed to the exit script. dict[str]-> object. The system will pass entry_price and entry_shares into the exit script as parameters.
Returns:
Type Special Notes
string order_id Unique order identifier.
Working Example:
 # Copyright Cloudquant, LLC. All right reserved.
from cloudquant.interfaces import Strategy


class AlgoSellExample(Strategy):
    @classmethod
    def is_symbol_qualified(cls, symbol, md, service, account):
        return symbol == "AAL"

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

        # send order for 100 shares of current symbol at market price, intent is "init" when entering a position
        order.algo_buy(self.symbol, "market", intent="init", order_quantity=100)
        print("100 shares of " + self.symbol + " were bought\n\n")

    def on_minute_bar(self, event, md, order, service, account, bar):
        if event.timestamp > service.time(9, 31):
            # sell the shares in on_minute_bar after the 9:31 minute bar has formed
            print(service.time_to_string(event.timestamp) + "\tin on_minute_bar()\n")

            # send an order to sell
            # intent is exit when getting out of a position
            order.algo_sell(self.symbol, "market", intent="exit")
            print("100 shares of " + self.symbol + " were sold")

            service.terminate()

Console

AAL
2016-09-07 09:30:00.000000  in on_start()

100 shares of AAL were bought


2016-09-07 09:31:00.517000  in on_minute_bar()

100 shares of AAL were sold