Slow and steady ??
Oh yes ... we all know the adage "Slow and steady wins the race".
But this adage is far from the truth when it comes to fast-moving markets. The speed with which a trader can enter an order, and the speed with which the broker can execute the order, makes plenty of difference for the profit/loss. Similarly the ease/convenience of order-entry is quite important. I am writing this on 3/24/2020 which is when Santa Clara County, and in fact whole of California is under 'shelter-in-place' order because of COVID-19, and the financial markets have experienced violent ups/downs. Overall this situation is bad for humanity, but that does not necessarily mean that the situation ought to result into a financial loss for the traders.
Besides being a trader, I'm an ORACLE ERP and Zuora professional as well, and the speed+ease matters a lot when it comes to data/transactions moving from upstream-to-downstream.
I've seen slow-cumbersome interfaces in IT that have caused many issues to IT personnel, and the Business Partners. :-)
Many brokers provide REST APIs to simplify the order-entry. Most notably Intractive Brokers, TD Ameritrade, and Alpaca. (At present i.e. 3/24/2020 Neither Charles Schwab, nor Fidelity provide any APIs to the retail traders - so I just use Python/Selenium to do the Web-Automation to automate the order-entry/portfolio-download etc.) In this article I will give a few details for the API that TD Ameritrade provides for Order Entry, and my usage of this API.
<< I leverage my experience of ORACLE/Zuora for my trading. There are many 'open' interfaces in R12 Order Import, Invoice Import, Receiving Transactions Import etc., and for Zuora Platform there are 'connectors', and REST APIs, and "Callouts". The Web-automation via Selenium is used widely by the QA personnel for doing the testing. I use these for my day-job all the time, so the skill I get from the usage becomes quite handy for my trading. >>
Lowest Low Orders:
There are many Alogs I've developed to trade. One such Algo is to trade based on the Lowest Low value from past week. This is almost like bottom fishing, but with a drastic difference that this is geared for very rapid trading with a very short time-span. I've found this to be especially useful when there is high volatility such as the present Corona Virus time. I'm giving below a sample Excel Workbook that I create every day automatically. And it's necessary for me to submit all of these orders to my broker for execution. All of these are "Limit", "Good-Till-Cancelled" orders, so these will get submitted and keep waiting to get executed. If the price falls to the level given in the order, the order will get executed, else it will just be kept as "Working" order, and after 6 months it will expire or I might cancel it. If the main "buy" order gets executed then the child "sell" order that was "waiting" gets trigged and it becomes "working" order that keeps waiting to get executed.
By the sheer number of orders - 72 that are visible below (and there are plenty others that are not within the visible range) it's not practical for me to do this data-entry every day manually.
... So ... what's the answer ?? ... Use API to automate.
Giving below aother example of worksheet that shows some more orders I enter.
These are 74 orders for the Junk Bonds, Preferred Stocks and Sernior Loans.
As before, the amounts/percentages are not what I use for real trading, but these are just samples.
What happened to triple-leveraged ETFs today (3/24/2020):
The day 24-MAR-2020 was a historic day for markets. The financial markets went up today by a record.
Performance of DOW today has beaten the record that was set by DOW in year 1933 - that's nearly a century ago !!
The performance of the triple-leveraged ETFs was spectacular as well.
API - "orders":
TD Ameritrade offers elegant APIs to place, query, cancel Orders. The complete DOC for the API are at TD Ameritrade site (of course). I am giving Schema for the "orders" in the following texbox.
{
"session": {
"type": "string",
"enum": [
"NORMAL",
"AM",
"PM",
"SEAMLESS"
]
},
"duration": {
"type": "string",
"enum": [
"DAY",
"GOOD_TILL_CANCEL",
"FILL_OR_KILL"
]
},
"orderType": {
"type": "string",
"enum": [
"MARKET",
"LIMIT",
"STOP",
"STOP_LIMIT",
"TRAILING_STOP",
"MARKET_ON_CLOSE",
"EXERCISE",
"TRAILING_STOP_LIMIT",
"NET_DEBIT",
"NET_CREDIT",
"NET_ZERO"
]
},
"cancelTime": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"shortFormat": {
"type": "boolean",
"default": false
}
}
},
"complexOrderStrategyType": {
"type": "string",
"enum": [
"NONE",
"COVERED",
"VERTICAL",
"BACK_RATIO",
"CALENDAR",
"DIAGONAL",
"STRADDLE",
"STRANGLE",
"COLLAR_SYNTHETIC",
"BUTTERFLY",
"CONDOR",
"IRON_CONDOR",
"VERTICAL_ROLL",
"COLLAR_WITH_STOCK",
"DOUBLE_DIAGONAL",
"UNBALANCED_BUTTERFLY",
"UNBALANCED_CONDOR",
"UNBALANCED_IRON_CONDOR",
"UNBALANCED_VERTICAL_ROLL",
"CUSTOM"
]
},
"quantity": {
"type": "number",
"format": "double"
},
"filledQuantity": {
"type": "number",
"format": "double"
},
"remainingQuantity": {
"type": "number",
"format": "double"
},
"requestedDestination": {
"type": "string",
"enum": [
"INET",
"ECN_ARCA",
"CBOE",
"AMEX",
"PHLX",
"ISE",
"BOX",
"NYSE",
"NASDAQ",
"BATS",
"C2",
"AUTO"
]
},
"destinationLinkName": {
"type": "string"
},
"releaseTime": {
"type": "string",
"format": "date-time"
},
"stopPrice": {
"type": "number",
"format": "double"
},
"stopPriceLinkBasis": {
"type": "string",
"enum": [
"MANUAL",
"BASE",
"TRIGGER",
"LAST",
"BID",
"ASK",
"ASK_BID",
"MARK",
"AVERAGE"
]
},
"stopPriceLinkType": {
"type": "string",
"enum": [
"VALUE",
"PERCENT",
"TICK"
]
},
"stopPriceOffset": {
"type": "number",
"format": "double"
},
"stopType": {
"type": "string",
"enum": [
"STANDARD",
"BID",
"ASK",
"LAST",
"MARK"
]
},
"priceLinkBasis": {
"type": "string",
"enum": [
"MANUAL",
"BASE",
"TRIGGER",
"LAST",
"BID",
"ASK",
"ASK_BID",
"MARK",
"AVERAGE"
]
},
"priceLinkType": {
"type": "string",
"enum": [
"VALUE",
"PERCENT",
"TICK"
]
},
"price": {
"type": "number",
"format": "double"
},
"taxLotMethod": {
"type": "string",
"enum": [
"FIFO",
"LIFO",
"HIGH_COST",
"LOW_COST",
"AVERAGE_COST",
"SPECIFIC_LOT"
]
},
"orderLegCollection": {
"type": "array",
"items": {
"type": "object",
"properties": {
"orderLegType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"legId": {
"type": "integer",
"format": "int64"
},
"instrument": {
"type": "object",
"discriminator": "assetType",
"properties": {
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"cusip": {
"type": "string"
},
"symbol": {
"type": "string"
},
"description": {
"type": "string"
}
}
},
"instruction": {
"type": "string",
"enum": [
"BUY",
"SELL",
"BUY_TO_COVER",
"SELL_SHORT",
"BUY_TO_OPEN",
"BUY_TO_CLOSE",
"SELL_TO_OPEN",
"SELL_TO_CLOSE",
"EXCHANGE"
]
},
"positionEffect": {
"type": "string",
"enum": [
"OPENING",
"CLOSING",
"AUTOMATIC"
]
},
"quantity": {
"type": "number",
"format": "double"
},
"quantityType": {
"type": "string",
"enum": [
"ALL_SHARES",
"DOLLARS",
"SHARES"
]
}
}
}
},
"activationPrice": {
"type": "number",
"format": "double"
},
"specialInstruction": {
"type": "string",
"enum": [
"ALL_OR_NONE",
"DO_NOT_REDUCE",
"ALL_OR_NONE_DO_NOT_REDUCE"
]
},
"orderStrategyType": {
"type": "string",
"enum": [
"SINGLE",
"OCO",
"TRIGGER"
]
},
"orderId": {
"type": "integer",
"format": "int64"
},
"cancelable": {
"type": "boolean",
"default": false
},
"editable": {
"type": "boolean",
"default": false
},
"status": {
"type": "string",
"enum": [
"AWAITING_PARENT_ORDER",
"AWAITING_CONDITION",
"AWAITING_MANUAL_REVIEW",
"ACCEPTED",
"AWAITING_UR_OUT",
"PENDING_ACTIVATION",
"QUEUED",
"WORKING",
"REJECTED",
"PENDING_CANCEL",
"CANCELED",
"PENDING_REPLACE",
"REPLACED",
"FILLED",
"EXPIRED"
]
},
"enteredTime": {
"type": "string",
"format": "date-time"
},
"closeTime": {
"type": "string",
"format": "date-time"
},
"tag": {
"type": "string"
},
"accountId": {
"type": "integer",
"format": "int64"
},
"orderActivityCollection": {
"type": "array",
"items": {
"type": "object",
"discriminator": "activityType",
"properties": {
"activityType": {
"type": "string",
"enum": [
"EXECUTION",
"ORDER_ACTION"
]
}
}
}
},
"replacingOrderCollection": {
"type": "array"
},
"childOrderStrategies": {
"type": "array"
},
"statusDescription": {
"type": "string"
}
}
//The class has the following subclasses:
//-Option
//-MutualFund
//-CashEquivalent
//-Equity
//-FixedIncome
//schemas for each are listed below:
//Option:
{
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"cusip": {
"type": "string"
},
"symbol": {
"type": "string"
},
"description": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"VANILLA",
"BINARY",
"BARRIER"
]
},
"putCall": {
"type": "string",
"enum": [
"PUT",
"CALL"
]
},
"underlyingSymbol": {
"type": "string"
},
"optionMultiplier": {
"type": "integer",
"format": "int32"
},
"optionDeliverables": {
"type": "array",
"items": {
"type": "object",
"properties": {
"symbol": {
"type": "string"
},
"deliverableUnits": {
"type": "number",
"format": "double"
},
"currencyType": {
"type": "string",
"enum": [
"USD",
"CAD",
"EUR",
"JPY"
]
},
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
}
}
}
}
}
//OR
//MutualFund:
{
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"cusip": {
"type": "string"
},
"symbol": {
"type": "string"
},
"description": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"NOT_APPLICABLE",
"OPEN_END_NON_TAXABLE",
"OPEN_END_TAXABLE",
"NO_LOAD_NON_TAXABLE",
"NO_LOAD_TAXABLE"
]
}
}
//OR
//CashEquivalent:
{
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"cusip": {
"type": "string"
},
"symbol": {
"type": "string"
},
"description": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"SAVINGS",
"MONEY_MARKET_FUND"
]
}
}
//OR
//Equity:
{
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"cusip": {
"type": "string"
},
"symbol": {
"type": "string"
},
"description": {
"type": "string"
}
}
//OR
//FixedIncome:
{
"assetType": {
"type": "string",
"enum": [
"EQUITY",
"OPTION",
"INDEX",
"MUTUAL_FUND",
"CASH_EQUIVALENT",
"FIXED_INCOME",
"CURRENCY"
]
},
"cusip": {
"type": "string"
},
"symbol": {
"type": "string"
},
"description": {
"type": "string"
},
"maturityDate": {
"type": "string",
"format": "date-time"
},
"variableRate": {
"type": "number",
"format": "double"
},
"factor": {
"type": "number",
"format": "double"
}
}
//The class has the following subclasses:
//-Execution
//schemas for each are listed below:
//Execution:
{
"activityType": {
"type": "string",
"enum": [
"EXECUTION",
"ORDER_ACTION"
]
},
"executionType": {
"type": "string",
"enum": [
"FILL"
]
},
"quantity": {
"type": "number",
"format": "double"
},
"orderRemainingQuantity": {
"type": "number",
"format": "double"
},
"executionLegs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"legId": {
"type": "integer",
"format": "int32"
},
"quantity": {
"type": "number",
"format": "double"
},
"mismarkedQuantity": {
"type": "number",
"format": "double"
},
"price": {
"type": "number",
"format": "double"
},
"time": {
"type": "string",
"format": "date-time"
}
}
}
}
}
There are provisions to enter orders for whole gamut of instruments 'equity', 'option', 'currency' etc.
and to route the order to specific exchange 'ecn_arca', 'cboe', 'amex', 'box', 'nyse', 'nasdaq' etc.
and to use different strategies 'diagonal', 'straddle', 'strangle', 'butterfly', 'condor', 'iron_condor', 'vertical_roll' etc.
and to have different tax lots 'FIFO', 'LIFO', 'HIGH_COST', 'LOW_COST', 'AVERAGE_COST', 'SPECIFIC_LOT' etc.
... in general there are many many many choices available for the savvy traders.
.... .... Almost reminds me of Item Attributes in MTL_SYSTEM_ITEMS_B from R12 :-)
I've coded a Python program that reads the Excel Workbook, and places all the orders via API. I don't even know how long it will take for me to manually place these orders. But using the automation it takes less than 3 minutes each day !!
As a sample I'm giving below the CMD window that executed the program just for one order. It took 1 second.
Following screen-grab of "Think or Swim" shows the order placed. The order is a two part order. Main order, and the child order as shown above in the "Payload".
Fast, Easy, and Accurate:
No no ... the method of placing bulk orders using automation is definitely not "slow"
... So ... not quite sure about the adage of 'slow and steady ... ' :-)
I've designed rapid order entry that's Fast, Easy and Accurate !!
|