Trading¶
Overview¶
The latest release of the library makes creating, viewing, and modifying orders very simple and intuitive. Each order object must have a few attributes:
Buysell
Pricing
Quantity
Time
Symbol
The parameters can be provided all at once on object instantiation, or any of the orders can be set or modifed before submitting.
Submit a Stock Order¶
Buy 8 shares of AAPL at market price, good for the day.
>>> o = ally.Order.Order(
buysell = 'buy',
symbol = 'aapl', # case insensitive
price = ally.Order.Market(),
time = 'day',
qty = 8
)
# Get a summary of this order in human-readable terms
>>> print(str(o))
'Side.Buy 8 units of "AAPL" TimeInForce.Day, Market'
# See a hypothetical execution info for this order,
# without actually submitting the order
>>> a.submit(o)
{ ... }
# Actually submit this order for execution
# Returns the ID of this new order, but this parameter
# also becomes a parameter of the 'o' object created earlier
>>> o.orderid
None
>>> a.submit(o, preview=False)
'SVI-12345678'
>>> o.orderid
'SVI-12345678'
Order information can be passed to the class on instantiation. Notice that any or all fields can be None, and added later.
- class ally.Order.Order(buysell: Optional[str] = None, symbol: Optional[str] = None, price=None, qty: Optional[int] = None, time: Optional[int] = None, account=None, type_=<OType.Order: 1>, orderid=None, fixml=None)
- __init__(buysell: Optional[str] = None, symbol: Optional[str] = None, price=None, qty: Optional[int] = None, time: Optional[int] = None, account=None, type_=<OType.Order: 1>, orderid=None, fixml=None)
Creates an order.
- Parameters
buysell – Specify the postion desired.
symbol – Enter the symbol of the instrument to be traded. You can use ally.utils.option_format(…) to generate the OCC-standard option symbol.
price – Specify the pricing options for execution.
qty – Specify the number of shares (or contracts, for options) to be purchased. Accepts integers, not fractions.
time – Specify the time-in-force of the order.
Viewing Open Orders¶
View recent orders (open or executed)
>>> os = a.orders()
# View a summary of each order
>>> [ str(o) for o in os ]
['(OType.Order) Side.BuyCover 10 units of "GLD" TimeInForce.GTC, Limit $1.000']
# View the order status of one of the orders
>>> os[0].status
{
'Stat': '8',
'RejRsn': '',
'LeavesQty': '10.0',
'TrdDt': '2020-01-01T01:01:00.000-04:00',
'TxnTm': '2020-01-01T01:01:00.000-04:00',
'Txt': 'The limit price you have entered is significantly away from the current market price.',
'OrdQty': {},
'Comm': {'Comm': '0.0'}
}
Order objects have a few attributes, most important among them are
account
buysell
instrument
orderid
otype
pricing
quantity
status
time
The full class documentation:
- class ally.Order.Order(buysell: Optional[str] = None, symbol: Optional[str] = None, price=None, qty: Optional[int] = None, time: Optional[int] = None, account=None, type_=<OType.Order: 1>, orderid=None, fixml=None)¶
- property convert_buysell¶
Turns buysell type into string.
- property fixml¶
Compiles the object into FIXML string.
Does not affect internal state of object
- set_account(account)¶
Specifies the account used to execute an order.
Users shouldn’t really need to use this under normal circumstances, this is handled by the ally object.
Can be viewed at obj.account
- set_buysell(buysell)¶
Specify the side of this order.
Can be viewed at obj.buysell
- Parameters
buysell – one of (‘buy’,’sell’,’sellshort’,’buycover’), or the corresponding enum types.
- set_orderid(orderid)¶
Specifies the order’s ID.
Can be viewed at obj.orderid
- set_pricing(priceobj)¶
Sets the pricing information of an order.
Can be viewed at obj.pricing
- Parameters
priceobj – Must be one of ally.Order.Market(), ally.Order.Limit(x), ally.Order.Stop(x), ally.Order.StopLimit(x,y), ally.Order.TrailingStop(x,y)
- set_quantity(qty)¶
Sets the order quantity.
Can be viewed at obj.quantity
- set_symbol(symbol: str)¶
Sets the order’s instrument.
Can be viewed at obj.instrument
- set_time(time)¶
Sets the order’s time-in-force.
Can be viewed at obj.time
- Parameters
time – must be one of (‘day’,’gtc’,’onclose’), or the corresponding enums instances.
- property status¶
Execution status of this order.
None implies that this order hasn’t been submitted for execution yet.
Dealing With Options¶
The only difference between how stocks and options must be handled, is that the option contract must be changed into its standard OCC symbol first. Then the option can be treated like any other stock, in every other feature. The ally.utils.option_format
function formats the options’s unique OCC symbol from its parameters:
- ally.utils.option_format(symbol='', exp_date='1970-01-01', strike=0, direction='')¶
Returns the OCC standardized option name.
- Parameters
symbol – the underlying symbol, case insensitive
exp_date – date of expiration, in string-form.
strike – strike price of the option
direction – ‘C’ or ‘call’ or the like, for call, otherwise ‘p’ or ‘Put’ for put
- Returns
OCC string, like ‘IBM201231C00301000’
# Construct the option's OCC symbol >>> ibm_call = ally.utils.option_format( exp_date = '2020-12-31', symbol = 'IBM', # case insensitive direction = 'call', strike = 301 ) >>> ibm_call 'IBM201231C00301000'
This symbol can now be traded, same as any other stock or option.
Short sell 1 contract (with contract size 100 shares) of the IBM call specified above, limit at $18, good-til-cancelled.
>>> o = ally.Order.Order(
buysell = 'sellshort',
symbol = ibm_call,
price = ally.Order.Limit( limpx = 18 ),
time = 'gtc',
qty = 1
)
Changing Order Parameters¶
Modifying orders, outstanding or local orders, is easy as well.
# Doesn't matter where this order came from
>>> o
<ally.Order.order.Order at 0x7f6ae8246278>
# It turns out that it's a buy-to-open order
>>> o.buysell
<Side.Buy: 1>
# Modify something about it
>>> o.set_buysell ( 'sellshort' )
# And now its a sell-to-open
>>> o.buysell
<Side.SellShort: 4>
Any of these functions can be used to modify the order’s parameters:
- class ally.Order.Order(buysell: Optional[str] = None, symbol: Optional[str] = None, price=None, qty: Optional[int] = None, time: Optional[int] = None, account=None, type_=<OType.Order: 1>, orderid=None, fixml=None)
- set_buysell(buysell)
Specify the side of this order.
Can be viewed at obj.buysell
- Parameters
buysell – one of (‘buy’,’sell’,’sellshort’,’buycover’), or the corresponding enum types.
- set_orderid(orderid)
Specifies the order’s ID.
Can be viewed at obj.orderid
- set_pricing(priceobj)
Sets the pricing information of an order.
Can be viewed at obj.pricing
- Parameters
priceobj – Must be one of ally.Order.Market(), ally.Order.Limit(x), ally.Order.Stop(x), ally.Order.StopLimit(x,y), ally.Order.TrailingStop(x,y)
- set_time(time)
Sets the order’s time-in-force.
Can be viewed at obj.time
- Parameters
time – must be one of (‘day’,’gtc’,’onclose’), or the corresponding enums instances.
And the order type (Order, Cancel or Modify) can be set as so:
o.otype = ally.Order.OType.{Order, Modify, Cancel}
Modifying and Cancelling Outstanding Orders¶
Cancelling an order is very simple, and can be done in one of three ways:
(Easiest) Inline method. Cancel or modify from the submit function.
The function will do the rest for you.
>>> a.submit(
o,
preview = False,
type_ = ally.Order.OType.Cancel # Either OType.Cancel, or OType.Modify
)
Directly modify existing order
>>> o.otype = ally.Order.OType.Cancel
>>> a.submit( o, preview=False )
Construct new cancel order object
>>> cxl = ally.Order.Order(
orderid = o.orderid,
type_ = ally.Order.OType.Cancel
)
>>> a.submit ( cxl, preview=False )
Orders can be revised once submitted but before execution like so:
# Modify an attribute of this order
>>> o.set_pricing( ally.Order.Limit(8) )
# Submit to ally for revision
>>> a.submit ( o, preview=False, type_ = ally.Order.OType.Modify )
Pricing Types¶
The Ally API supports 5 price types in total.
- class ally.Order.Limit(limpx)¶
- __init__(limpx)¶
Creates a limit price object.
- Parameters
limpx – the stop price
- class ally.Order.Stop(stoppx)¶
- __init__(stoppx)¶
Creates a stop price object.
- Parameters
stoppx – the stop price