The document says:
"The OrderTicket Status property can be used to determine if the order is filled. The OrderStatus enum has the values Submitted, PartiallyFilled, Filled, Cancelled or Invalid."
From what I understand, the PartiallyFilled status only happens when the order is not set to All or None. Now my questions:
1- where do we set detail attribues of a buy order such as AllOrNone or Till End Of Day or Good Until Cancelled, etc.?
2- If Partially Filled happens, will the order stop there? or continues to try to fill the whole order?
3- If it continues to fill it, can we cancel the rest of the order?
Thanks a lot!
Petter Hansson
1. Lean only supports the most common order types, with no variations. Jared commented recently on why this is:
2. Partially filled is an intermediate state. The order will only stay there if it cannot fill further (e.g. a limit order might have the limit price set too low or high, preventing it from ever filling completely). Basically, brokerage reports "order has now filled another X units of order total Y", and order will remain in partially filled state as long as sum(X) != Y.
3. Sure, you can cancel a partially filled order. Remember the volume filled at the time of cancellation at the market will not be "undone" though.
Patrick Star
Thanks Petter. Se let me make sure that I understand it correctly.
1. I place an order for 100 shares
2. 70 shared get filled -> my status is Partially Filled now
3. If I don't cancel the remaining 30 shares, the engine is going to keep trying until when? time based? until EOD? or until cancelled?
4. If I cancel the original (100 shares) order, the only thing that gets cancelled is the remaining 30 shares and I still have my 70 shares in hand.
Is that correct?
Petter Hansson
3. I actually don't know how long an order will last assuming it's not filling and you don't cancel it - I haven't had to find out since I don't leave orders overnight. One can probably dig in the Lean source code to find out, but would be nice if QC staff can answer if they happen to read thread.
4. Here's what can happen to confuse matters w.r.t. latency:
Unrelated: Look up the concept of "round lots" (increments of 100 units). If you place an order for 100 units on US equity exchanges, it won't be partially filled (though this is maybe not an assumption you wish to make in code). Either way, you will want to keep order quantities in increments of 100 if they're latency critical.
Patrick Star
Thanks Petter.
I was going through LEAN's code and I found that Order actually has an attibute called OrderDuration. Currently is has only GTC and Custom but the docs don't say what Custom means. Anyway I would try to not even think about customizing it and considering Jared's quote that you sent earlier, I'm not sure if it's even used anywhere. So, with this I think we can pretty much assume that all the orders are GTCs in LEAN.
Patrick Star
On the other note, I was finally able to implement a near-reality workflow model that supports a Limit Order for buys, Cancel for buy orders that are not good any more, and Market Order for sells. I chose this because when I get a sell signal, I don't want to take any risk of waiting for a Limit Sell to happen. So I just sell it for whatever market offers.
Anyway, I tested a sample algo with two models: A. buy at the market value and B. buy with a limit order, By comparing the downloaded trades side by side I can see that backtesting in LEAN is very optimistic at high frequencies such as Second. This is true even for very liquid assets. Basically LEAN just fills the order at the close price or better put, the last price.
The thing is that the close price even at the Second resolution belongs to the past and if I want to buy something at that price, there may or may not be someone out there that offers that ask price.
Of course using Limit Orders could go both ways. I could end up getting a better deal or not anything at all. The problem is that, when I tested the algorithm with those two models, model B turned a profitable results (of the model A) into loss! In the begining I was excited as I thought enabling Limit Order would make the results better for me because either I would only buy at the price that is accepted for the algo. But I guess this surprising outcome is very much related to the level of optimism that comes with the default immediate-fill-at-close-price of LEAN that is, you always get the best offers!
This is a little disappointing and I'm not sure what my next options are at this point especially with the fact that QC doesn't provide historical trade data so you can't even code based on the bid/ask data.
The only remaining hope is that, in real market there is still a good chance that most of the orders that are submitted at the close price are filled one or two seconds later. But even that maybe an optimistic assumption.
By any chance do you have any stats on what percentage of the orders get cancelled in a liquid asset such as SPY?
Thanks again.
Alexandre Catarino
I am glad you have figured out everything!
The only question remaining is about Duration.Custom. It is custom because we can use DurationValue to define the limit time for being executed. Also, we need to create a custom brokerage model to deal with this value.
Here is how it is used in OandaBrokerageModel.
Patrick Star
Alex,
I berifly looked at the code and I think I understand it a little better now. Not sure if I know enough to make my own custom implmenetation of it though. But I will send more questions when I'm there.
Can you also answer this question? I will put it in Gherkin format to make it easier:
Scenario:
Given - I am using Second resolution
Given - at 10:00:00 the close price of ABC is $30.00
Given - at 10:00:01 the close price of ABC is $30:02
Given - I am in an OnData loop at the time of 10:00:00
When - I submit a buy market order using ImmediateFill
Questions:
1- Do I get a fill in the same OnData loop? does it get filled in the next OnData loop? or it happens asynchronously beteen these two loops?
2- Do I get a fill at $30.00 or $30.02?
Alexandre Catarino
Since we are working with the default fill model (ImmediateFillModel), you order is filled in the current loop interaction, thus the fill price is $30.00.
Patrick Star
Thanks Alex. In one of last conversations you said:
"In backtesting mode, the default fill model is ImmediateFillModel that does not take volume into account.
If you want to add a check, ideally, you should create o custom fill model:
// Set the fill models in initialize: Securities["IBM"].FillModel = new PartialFillModel(); // Custom fill model implementation stub public class PartialFillModel : ImmediateFillModel { public override OrderEvent MarketFill(Security asset, MarketOrder order) { //Override order event handler and return partial order fills, } }
Is it possible to put a delay on the custom fill model and fill it on the next bar (in this case, the next second)?
Looking at the LEAN codes, MarketOrder has CreateTime but inside MarketFill I don't know how to get the current time to check it against.
BTW, another thing that I found is: MarketOrderDelayedTradeClose. Can you explain this as well?
Sorry for so many questions. I hope these conversations will be used for the next prople with similar problems :)
Petter Hansson
I'm using delayed fill models in some of my backtesting (usually with on/off parameter to see effect). I would share them if I wasn't afraid they're buggy though. E.g. with ImmediateFillModel I have a Sharpe 7 algo, with a 1 s delay I get nearly -0.1% slippage (huge) and algo appears worthless. BUT in IB paper testing I get closer slippage to what I would expect of -0.01% for that symbol and my algo is making money (still in progress forward test, will be followed by minimal position real money test).
Point being, this stuff is very complicated. The lack of bid/ask data means fills at next trade will be very off if there's a longer delay, AND timestamps rounded to nearest second incurring up to 2 s of error (source timestamp 1 s off, fill timestamp 1 s off). My delayed fill models seem off anyway. There's no substitute for testing at the brokerage here.
As far as I know there's some volume aware fill model being worked on in Lean. Not sure if it incorporates delay.
Alexandre Catarino
What would be the fundamental difference between a delayed fill model and a slippage model?
Say, instead of using a delayed fill model, we could use a slippage model with a fixed 0.1% slippage. Then we could make sensibility tests on that fixed value to find out how bad slippage can be.
Patrick Star
Alex,
I did a similar (but primitive) model in my recent test. I changed the order type from Market to Limit and added 0.1% to the current price. The result was not too bad but I found many cases that in a second the price jumped more than that 0.1%. So I then increased it and increased it until it was a 5%. Given that I was using elevated ETFs I still had cases where the price jumped more than 5% in just a single second and I received a cancel signal! The more interesting thing was that even after adding 5% to the close price, the profit of this test was still behind the original test that got filled immediately at the current close/market price.
So the delay really could be different from slippage unless I don't understand the concept of slippage correctly - which is very much possible :)
Petter Hansson
You tell me Alex, I am not the expert, haha. I've assumed that I can derive more accurate slippage via filling with some latency, but it seems overly pessimistic as I noted above. Maybe I should just be content with measuring real slippage and use that with ImmediateFillModel?
Patrick: With "slippage" as I've been using it in this context, I mean difference in "intended" fill price (in my case, latest trade price at time of order) and actual fill price of market order.
Patrick Star
Petter, my algo is making good trades right now when I test it with paper QC and I would really love to test it with paper IB. But the problem is that I should keep at least $30K in that account. I remember you mentioned earlier that you have never taken your algo to live trading. I think in one point we should just say, f** it, I'm going to do it in real world and if it's really burning the cash, I will pull the plug.
Having said that, I added a safe guard to my code to make sure that if I make more than 5% loss in a day, it will stop trading. The problem with thsese safeguards is that they can also go against you as they stop when it's really time to hold and wait for the bounce.
Any ideas how to make it safer with live trading?
Patrick Star
When I see the results of the back tests, it's too good to be true. I believe if something is too good to be true, then it's definitely too good to be true. That's why I'm looking so hard to see what is the flaw here? why I am making so much profit? LOL
Petter Hansson
True, I've reached the point where I have to test the algo in real trading. Better backtesting would save time though because running algos at IB is a bottleneck; they have only one live data feed per account by default (IB using it for simulated fills), etc. And, when algo keeps crashing due to external circumstances (as it's currently doing for me) the test is unreliable nontheless because you keep restarting it with warmup state which may be different from live state.
Stoplosses tend to work against you, really badly. That said, I would look at Maximum Draw Down for a period you define as the current market regime, and multiply that by some factor. Then, if your algo reached a greater draw down than that, you declare the market regime has changed and take it down. It's going to happen some time, the problem is once it does you're on a guaranteed loss from the peak similar to your tolerance level. Hopefully, your algo has increased your capital correspondingly before then...
In addition to that, intraday limits can be sensible for some algos. Same problem with stoplosses there, but they can be backtested easier since you should/can probably look at some points in history where they triggered without stopping algo longer than that day (or however long period). Nonetheless, it can be really difficult to not have stoplosses drain on your algo's performance.
Patrick Star
Ah, I didn't know they have only one data feed. I definitely need more than that. But you can add data feeds to your account, right? or the paper IB test applies that limitation even if you have the data feed added to your account?
Petter Hansson
My understanding is live and paper account share real time data feed, so if you're running real money algo it blocks paper account algo from using it. But you can get one more sub-account live-paper pair with another live feed if you pay for said feed. Not sure if you can get more than one additional sub-account like this. IB has weird limitations like this. Disclaimer: It was a while ago I looked at this, please do look into it yourself.
Alexandre Catarino
Petter Hansson, your assumption is totally valid. However, since you said it was complicated, buggy and overly pessimistic, I was wondering whether a simpler approach shouldn't be revisited.
It is great that both of you and other members (I am thinking of JayJayD) are making some research and talking about it here. By the way, if you could share some code, we would appreciate it.
Patrick Star
Thanks Alex. It will be hard for me to share the main code but if I find enough time I will make a simplified and cleaned version of it to share.
BTW, I implemented a manual delay system last night and did some testing. Basically what it does is, it kicks off a buy (or sell) counter but doesn't place the order until the next n OnData cycles. A little primitive but better that trying to get the custom filler to work with so little knowledge that I have about LEAN.
Are you ready for the results?
Here they are:
1- with 0 sec delay: 158.2% gain
2- with 1 sec delay: 68.8% gain
3- with 2 sec delay: 27.5% gain
Conclusion: if you are using an algo like mine that deals with high resolution data and is trading at high frequency, ImmediateFill could be your enemy as it's too optimistic to rely on! fortunately in this case it's not losing money but it's way less than having a fast fill.
Now researching on how to make the orders fill faster, so far what I have found are these:
- Broker! the most important factor
- Network latency
- Make the orders in Round Lots
If you guys have something else to share, I would really appreciate it.
PS: @Petter, would it be possible for you to send me an email? it's patrick.estariane and it's on gmail. Thanks!
Patrick Star
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!