Hi all,
My algo uses a simple rule to allow only one order at any gieven time. So far I have been using SetHoldings with 100% allocations:
// Method 1
// ------------
// check if it's time to buy, bla bla bla
if (!Portfolio.Invested) {
SetHoldings(symbol, 1); // for buying with 100% allocation
}
// and
// check if it's time to sell, bla bla bla
if (Portfolio.Invested) {
SetHoldings(symbol, 0); // sell everything
}
With this, if you look at the resulted trades, you always see a nicely filled Long trade followed by a nicely filled Short trade. And my Portfolio.Cash never goes to any negative number.
Now I need to trade with a fixed amount instead (e.g. $50K). I used a couple of different methods:
// method 2
if (!Portfolio.Invested) {
LimitOrder(symbol, shares, price, tag: "Buy LimitOrder");
}
// method 3
if (!Portfolio.Invested) {
Order(symbol, shares, OrderType.Limit, price, "Buy Order");
}
// method 4
if (!Portfolio.Invested) {
StopMarketOrder(symbol, shares, price, tag: "Buy StopMarketOrder");
}
When I used any of these methods, the trades show a strange behavior. I get multiple Long tickets, some show as New and finally one that says Filled. Also in several points my Portfolio.Cash goes to negative numbers!
I'm thinking of two possible reasons.
1. Portfolio.Invested doesn't become true if I allocate parts of the cash and not all of it ... very unlikely!
2. There might be a delay (considering that I use Resolution.Second) that causes a new OnData to happen before the first Order is filled.
Could anyone please shed some light on this behavior? Thanks a lot!
Petter Hansson
In general, I would stay away from assuming instant fills. For some kind of algos in liquid assets you can get away with that (e.g. daily rebalancing), otherwise it's going to take some time to get filled. It's definitely going to take at least ~0.7-2 s with Interactive Brokers in reality. For an algo that may trade again a second later, not keeping track of order tickets is suicidal.
Portfolio.Invested means the value of any holdings exceeds 0, i.e. any units long or short will count.
Limit orders will by definition not be filled unless price moves below or above limit for a buy or sell respectively. Similarly, stop market orders have a trigger criterion.
Patrick Star
Thanks a lot Petter. You always have greate advices! I think you are also working on algos that deal with short time spans, right?
From your answer it appears that my backtests are running with the assumption that it's a broker account and that I can buy more than the cash amount, right? is there a way to disable this?
Patrick Star
"otherwise it's going to take some time to get filled. It's definitely going to take at least ~0.7-2 s with Interactive Brokers in reality"
This is such a valuable information for me! I remember you had mentioned before that IB loves to add a delay. So I have to make sure that the algorithm accounts for this delay. The first things that come to my mind are:
- make sure that the code is aware of the orders' workflow and don't completely rely on the framework unless you are submitting orders at the close price
- don't place a second buy order until the first one is filled
- if there is a sell signal after a buy order is submitted, if the order has not been filled yet, cancel the order immediately
Is there anything else that I should be careful about? As always your answers are greatly appreciated!Alexandre Catarino
Your cash can have a negative value because you are using a margin account and leverage.
Please try setting Leverage to one:
// Before AddEquity SetSecurityInitializer(x => x.SetLeverage(1));
Patrick Star
Great. It could be very dangerous not knowing this for new comers like me! :)
Alexandre Catarino
Hopefully new comers will find out about the default leverage during the development process and will not put money at risk before knowing all they have to. This information is found at the docs: Cash and Brokerage Models.
Petter Hansson
This is such a valuable information for me! I remember you had mentioned before that IB loves to add a delay. So I have to make sure that the algorithm accounts for this delay. The first things that come to my mind are:
Is there anything else that I should be careful about? As always your answers are greatly appreciated!
Unless you're prepated to manage the significant increase in complexity, only allowing one active order at a time in a given Security is a good idea, yes. A counter example for why people would use more than one is due to stop orders.
Remember cancellation is delayed as well and an order might be filled further while it's being cancelled. Thus, if you're trying to calculate the size of the next order dependent on how many shares you already have, you will have to wait until the cancellation's confirmation.
I've done my latency measurements on a paper account (did no real money trading on QC yet) and it's possible real accounts differ, especially because IB paper accounts are limited to simulated fills on top of order book. Chances are a big order would fill faster on real market as more limit book levels are available.
On a side note, today I got 0.46 s average on my IB paper trading for very small (200 unit) SPY orders, In my worst case observed, it has taken up to 11 minutes to fill a -5000 unit market order for SPY after opening (not sure what was up with that). Fills near opening seem to have higher latency, possibly because IB and/or market is under stress at that time. More commonly, 5000 unit SPY orders take around 2-5 s, implying liquidity makes a lot of difference to simulation anyway. According to their documentation, IB does partition/stall big market orders also in real trading to reduce market impact.
Oh, another tip: Stay away from medium frequency trading in illiquid stocks, because the fills you get with ImmediateFillModel will be nothing like reality.
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!