-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Place Order models and validation #98
Conversation
this looks fantastic, I had started to do this then gave it up as too much work. are any modifications to the client necessary to plug this in? |
Hmm, I haven't checked the client too much but this submodule can create a json string, so as long as the placeOrder API accepts JSON strings, it should be fine. I tested the placeOrder client function with a previous revision of this PR but I haven't done that with this version. I'll have to do that today and get back to you. |
Ok, so I made a little script to help me test this out. import tdameritrade as td
from tdameritrade.orders.order_builder import build_buy_market_stock_order
# You have to import constants with the full path since I didn't make it available in the ./orders/__init__.py.
from tdameritrade.orders.constants import Status
from pprint import pprint
# Authorize TD Client
td_client = td.TDClient(...)
# Load account info to get account Id
td_client.accounts()
account_id = td_client.accountIds[0]
# Creating market buy order json
symbol = "F" # Chose Ford since it's pretty cheap
quantity = 1
order = build_buy_market_stock_order(symbol, quantity)
pprint(order.asdict())
# Without this, it fails with a 415. Mentioned in issue #96
# This may screw up other API calls, so it may have to be reset if you want to try other ones.
td_client.session.headers = {
"Content-Type": "application/json"
}
# # NOW ENTERING DANGER ZONE AKA TESTING IN PRODUCTION
# # THIS WILL PLACE AN ORDER SO I ONLY TESTED IT AFTER HOURS
# # Placing Order
# try:
# # This will fail to return because the place order API does not return a JSONserializable object on success
# # BUT the order will still go through. Checked on the site. You can also check your active orders below.
# # Mentioned in #96
# response = td_client.placeOrder(account_id, order.json())
# pprint(response)
# except json.decoder.JSONDecodeError as err:
# print(err)
# Safe zone
# Print out orders
my_orders = td_client.orders(accountId=account_id)
pprint(my_orders)
# # DANGER ZONE AGAIN
# # THIS WILL CANCEL ALL WORKING ORDERS
# # Orders are a little weird since you will have WORKING and CANCELLED orders
# # so I just went through and cancelled all my cancellable orders.
# for order in td_client.orders(accountId=account_id):
# if order["status"] == Status.WORKING and order["cancelable"]:
# response = td_client.cancelOrder(account_id, order["orderId"])
# pprint(response) Mentioned issue #96 Haven't tested anything else. Would like to try buy at limit for stocks since I believe the price field will need some work. |
@ChocoShell thanks for testing, I cannot trade so this is very helpful. Maybe some day @TDAmeritrade will allow for trading against a paper account! I'm comfortable with this, I'll merge now |
Creates an orders submodule with the goal of validating the data of the Place Orders API
I created a series of dataclasses that are JSON serializable and will validate the content on initialization. These are available in tdameritrade.orders.models.
Since this uses dataclasses, you need python 3.7+ to run it.
The validation is done by taking the annotated type
legId: int
and checking if the value is an instance of that type or if it'sNone
This is all done in the orders.models.base.BaseOrder class. Check there for validation.
There are also builder functions for order legs and orders. I used the Place Order Samples for tests but didn't go much further. These can easily extended to create a nicer interface.
There are a few hiccups.
I saw that price was a
str
in the samples but the API says it should be an int. This may cause issues with price formatting. We can solve this by creating a new type that will handle this formatting.It is difficult to validate the members of a list due to some weirdness in the typing library example here, so we may not be able to validate some lists.
Resolves: #60