question

Upvotes
Accepted
3 1 2 4

Order Update via Python

I am trying to find out how I can update my current orders via Python.

I took a look at the Python examples on Github and the ones I found were for sending a basic order and reading L1 data.

There looks to be an order update examples in VBA on page 33 of the API specification (version 2.0) but not sure how I would implement this in Python.

Thanks for any information and/or examples.

websocketsredi-api
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

13 Answers

Upvotes
Accepted
23k 22 9 14

Hello @4AKD,

You will not be able to do this fully from python, at this time. This is what I tried to convey in my first answer.

1. In Python, you will be able to consume L1 via get. CacheControl is not supported in Python, and it is required to monitor orders, and modify orders. This is fully consistent with what @jirapongse.phuriphanvichai said.

2. You can get the complete info elsewhere, such as REDIPlus UI or CacheControl-based monitoring is exposed in C#. Which, in my understanding, is not what you require.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
23k 22 9 14

Hello @4AKD,

You are correct in your assumption. Order update is not supported from Python at this time.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
3 1 2 4

Thanks for the response.

1.) Do you mean that there are not examples given in Python or that it is 100% not possible to do at all with Python?

2.) I am looking over the members of the Order class (p. 8 of v2.0 API spec) there looks to be the method SetOrderKey. Can't I use this as part of the REDI API to update the order?

Thanks for the clarification.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
38.1k 71 35 53

@4AKD

Yes, you can use Python to update an order. The code is:

import win32com.client
# Equity Order Entry Example
o = win32com.client.Dispatch("REDI.ORDER")
o.SetOrderKey("#UserId#", "#OrderRefKey#")
o.Quantity = "500"
# Prepare a variable which can handle returned values from submit method of the order object.
msg = win32com.client.VARIANT(win32com.client.pythoncom.VT_BYREF | win32com.client.pythoncom.VT_VARIANT, None)
# Send an options order
result = o.Submit(msg)
print (result) # 'True' if order submission was successful; otherwise 'False'
print (msg)    # message from sumbit

However, you need to know the Order Ref Key.

According to this thread, the query is not supported via Python.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

This basic example does not work. This returns an error that "Symbol is required"

Upvotes
3 1 2 4

Thank you for the post.

1.) Am I able to set the original key for the original order? If that is the case they I don't have to query for the key later.

2.) The thread that is speaking of a query that is not supported looks to be for an existing position. I am looking to update an order that is open but has not been filled yet (no position).

Thanks for any information.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
23k 22 9 14

Hello @4AKD

This is exactly the case, SetOrderKey method can be used on an existent order.

The app would need to know the Order Key, in order to update the order.

It can be looked up on REDIPlus, by adding the field OrderRefKey to the order view.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
3 1 2 4

Hello Zoya,

I am going to just try this out tomorrow but I wasn't 100% clear on your response. Sorry to drag this out.

Can I use SetOrderKey when creating a new order (not an exiting order at first). This way I will know the key for the order without having to look it up.

For example:

1.) Creating a brand new order including o.SetOrderkey ("", "XXX124orderkey")

2.) Now I know the orderkey for my created order - ""XXX124orderkey".

3.) Later, I want to update the order (quantity, price, etc.) and I will again use o.SetOrderkey ("", "XXX124orderkey")

Thanks.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvote
38.1k 71 35 53

@4AKD

No, you can't use SetOrderKey when creating a new order. It is used for updating a submitted order.

The order key can be retrieved from the CacheControl class and REDIPlus UI (Message Monitor). However, the CacheControl class is not supported in Python. Therefore, you need to get it from the Message Monitor.

You may consider cancelling the order and then submitting a new order, instead.

To cancel the order, you need to set ClientData when submitting an order. The ClientData must be unique.

o.ClientData = "123456Order" 

Then, you can cancel it by calling the CancelOrder method of the REDI.APPLICATION class with the unique ClientData.

import win32com.client
o = win32com.client.Dispatch("REDI.APPLICATION")
msg = win32com.client.VARIANT(win32com.client.pythoncom.VT_BYREF | win32com.client.pythoncom.VT_VARIANT, None)
o.CancelOrder("123456Order", msg) 
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
3 1 2 4

1.) I created a order to buy 1 share of SPY at the limit price of 0.01. The order reference key is shown under the field Ord Ref Key of the header. The value is: F0A40000A337

2.) Using SetOrderKey() I have been trying to update this order with minimal modifications. (i.e. only update the price from 0.01 to 0.50)

<br>

def send_order_update():

o_new = win32com.client.Dispatch("REDI.ORDER")

o_new.SetOrderKey("", "F0A40000A337")

# o_new.Quantity = 2

# o_new.Symbol = "SPY"

# o_new.Side = "BUY"

o_new.PriceType = "Limit"

o_new.Price = 0.50

msg = win32com.client.VARIANT(win32com.client.pythoncom.VT_BYREF | win32com.client.pythoncom.VT_VARIANT, None)

result = o_new.Submit(msg)

3.) The problem is that when I run the above code the error message that is returned is that "Symbol is required". I then uncomment out:

o_new.Symbol = "SPY"

4.) I then get an error that "Side is required" so I comment out

o_new.Side = "BUY"

5.) I next get an error from the submit that "Price type is required". You can see from the code that both the price type and the numerical price is given.

6.) I am not sure what is going on here but a simple SetOrderKey() doesn't seem to be working correctly.

Thank you for your help.


order.png (90.9 KiB)
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
23k 22 9 14

Hello @4AKD,

Try setting from Order Ref Key field, not from Ord Ref Key.

Remove the redundant calls, something like:

o_new = win32com.client.Dispatch("REDI.ORDER") 
o_new.SetOrderKey("", "F0A40000A337")
o_new.Price = 0.50 
msg = win32com.client.VARIANT(win32com.client.pythoncom.VT_BYREF | win32com.client.pythoncom.VT_VARIANT, None) 
result = o_new.Submit(msg)
print(result)
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
3 1 2 4

Hello Zoya!

I have goods news to report!

I used the field "Order Ref Key" instead of "Ord Ref Key" and the update works correctly! I am doing this "manually" as a test.

1.) Comment on CacheControl

jirapongse.phuriphanvichai said:

"The order key can be retrieved from the CacheControl class and REDIPlus UI (Message Monitor). However, the CacheControl class is not supported in Python. Therefore, you need to get it from the Message Monitor."

I did a test grabbing the last price for a stock using the GetL1Value. GetL1Value works and I am able to get the last price:

msg2.value = stock_name

msg3.value = "Close" q.GetL1Value(msg2, msg3, msg4)

This GetL1Value looks to be part of the CacheControl and works. This seems to contradict what Jirapongse said that CacheControl class is not supported in Python. (?)

Maybe he is saying that there is not a L1 value that will produce the OrderRefKey?

2.) Part of the previous section of the thread mentioned using the Message Monitor to grab the "Order Ref Key". Is this going to be using the table name of "Message" and the field of "OrderRefKey"? What function/method do I use to do this? Example? What section of the API is this?

Thanks!!

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Another solution is using IronPython instead. From my quick test, RediLib.CacheControlClass can be used with IronPython.

Thanks for testing this out. I am trying to stay with my Anaconda distribution but it is good to know there are other options out there! :)

Upvotes
3 1 2 4

@zoya.farberov

Are there any limitations on doing the implementation using VBA?

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Upvotes
23k 22 9 14

Hello @4AKD,

You will find VBA implementation to be per REDI API Specification

The one exception, and it's only mentioned briefly in spec, is L2.

L2 market data is not available as of this time.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 5.0 MiB each and 10.0 MiB total.

Click below to post an Idea Post Idea