alpacahq / alpaca-trade-api-csharp

C# SDK for Alpaca Trade API https://docs.alpaca.markets/
Apache License 2.0
251 stars 83 forks source link

insufficient qty available for order #247

Closed ooples closed 4 years ago

ooples commented 4 years ago

I'm receiving these constant messages even though I shouldn't because all I'm doing with my code is submitting a limit sell order after my buy order is filled. I must be missing a step in the ordering process I guess. I have sent you my code to verify on your end

OlegRa commented 4 years ago

I've checked your code and still don't understand why do you use such a complicated approach for order placement. AFAIU you want to emulate the OTO orders on the client-side. Why not just place a market order with OTO type and a take-profit leg?

jeffwlandry commented 4 years ago

I don't know about ooples, but I don't use OTO because I can't issue a replace against the order to update it as things change.

ooples commented 4 years ago

@jeffwlandry What do you do in your situation if something changes?

@OlegRa I changed my strategy and emailed you the code but I'm still getting the same error even though I can confirm that there are no open orders and that the underlying position is filled

jeffwlandry commented 4 years ago

@ooples Not having looked at your code I don't know that I have experience exactly the same situation. I was getting this message, but it was entirely my own fault. I had some timing issues which resulted in my submitting requests which ratcheted up the number of shares. Basically I was getting out of sync locally thinking my position was one thing, while Alpaca knew my position was different. Unfortunately I can't remember exactly what the problem was. I do remember I had two or three different problems which resulted in this message. One of them may have been overrunning a previous order, thus trying to place a new order with an existing order having just been received by alpaca and not moved to a viable state. For instance submitting two buy orders without the first one being completed.

I got a handle on all this by doing a lot of logging with timestamps and seeing conditions which were stepping on each other. After I got that cleaned up I was able to get a handle on problems like this.

The program is running on a basic cycle. I run anywhere between 5 seconds and one minute. Alpaca is responsive enough that things have settled down by the time I get to my next cycle. At the end of the interval I make a decision about opening a position by placing an order. Interrupt occurs telling me alpaca's response before the next interval completes. In the next interval logic checks to see what the state of things is and decides what to do next. That might be close the existing order because it hasn't filled and things have changed, or replace the order with new data (new stop or limit), or place a new order to close out the position.

This seems to give me more control than using some of the more exotic orders.

In short, this particular message was my fault, but I had to log a bunch of information to get a handle on what I was doing to cause it. FYI, I'm using Serilog for logging and Seq for analysis. Seirilog's object oriented (in the data sense, not the programming sense) allows me to log very consistent information. Seq allows me to quickly pull the data and sort it in a meaningful way. As a result I'm getting data logs from which I can quickly pick up even threading and async issues. Without that I might have given up by now.

Jeff

ooples commented 4 years ago

I would love to take a look at your code and how you handle everything is that is possible

jeffwlandry commented 4 years ago

too be honest, the code is extremely messy. I started out with one set of expectations and have been evolving it for quite a while. It's burdened by a design which might allow another api to be spliced into it. It's supposed to allow me to drop in different decision making logic as well.

We should move this discussion out of the issues area. I'll think about if there is anything I can do to make something available.

jeff

OlegRa commented 4 years ago

@ooples @jeffwlandry This discussion is very interesting and useful but it doesn't relate to SDK itself.

This error string returned by Alpaca servers and if your program believes that at this particular moment you able to place an order and the server thinks differently - the server will win. We are unable to do anything at the SDK level to prevent such errors.

If you have some ideas on how to prevent such problems using SDK - you are welcome but don't forget. This is just a low-level wrapper around API and I don't like the idea to add client-side state management into it.

Maybe it's a good idea to write a more high-level client which will hide all details of low-level API calls behind some object model and will use this SDK as a base point, but I'm not sure I have time and willing to do so right now.

I suppose to close this issue in the scope of the final 3.9.0 release preparation if nobody will provide any idea how to prevent such a case without handling the account state changes inside SDK.

ooples commented 4 years ago

Are you even running the reproducible code I sent you? In my program I'm deleting all pending orders and only selling positions I have in my portfolio already.

OlegRa commented 4 years ago

@ooples According to your last email, this problem was solved by canceling all outstanding orders on the algorithm start, right? So it's not related to SDK and I'll close it right now. You can re-open it if you have any ideas on how we can prevent such a problem at the SDK level without introducing client-side state management.

ooples commented 4 years ago

No that is incorrect. I provided a fix to the problem by forcing the thread to wait after cancelling open orders before placing a sell order

jeffwlandry commented 4 years ago

@ooples I just ran into this in a similar (but possibly not identical) situation. I issued a limit order and tried to modify it. I received "insufficient qty available for order". it also told me that only x shares were available. In pursuing this I found the order I was trying to modify was in status of "accepted". Apparently i received this error because I tried to modify the outstanding order and it was telling me the existing order can't be filled because there aren't enough shares available. Trying to cancel the position would clearly result in a similar position and possibly the same error. As a result you may have issued a command you think should have closed out the position, but it didn't because of lack of shares and successive actions may result in this message.