I ran into a situation where SetHoldings didn't create MarketOrder because CalculateOrderQuantity returned 0. CalculateOrderQuantity returned 0 because there had been no Securities[symbol].Price set. I ended up checking the Quantity for the Holdings after calling SetHoldings, something like:
if (securitesToPurchase > 0)
{
SetHoldings("VCLT", 0.20m);
var quantity = Securities["VCLT"].Holdings.Quantity;
if (quantity > 0)
{
securtitiesToPurchase -= 1;
}
....
}
Is there a better way to do this?
-- Wink
Alexandre Catarino
From the code snippet, we cannot tell why the price of the security is zero. However, I can suggest that you verify whether the symbol is part of the TradeBars object:
public void OnData(TradeBars data) { /* ... */ if (securitesToPurchase > 0 && data.ContainsKey("VCLT")) { SetHoldings("VCLT", 0.20m); var quantity = Securities["VCLT"].Holdings.Quantity; if (quantity > 0) { securtitiesToPurchase -= 1; } /* ... */ } }
After you call SetHoldings, the quantity can be zero if the call is made when the market is closed (e.g.: daily resolution algorithmns), because the order will only be executed on market open.
I hope this helps, otherwise you may need to share your code for the community take a look at it.
Wink Saville
The reason why is because Price is 0 just for the reason you said, SetHoldings was called when the markets were closed, my start date was 1/1/2010. I've attached the code and here is the log and as you can see on the line " ... VCLT Price=0":
2010-01-01 00:00:00 Launching analysis for c187f74155f968f25c5c53522ad946b5 with LEAN Engine v2.2.0.2.744
2010-01-01 00:00:00 Initialize:+
2010-01-01 00:00:00 Initialzie: securitiesParamStrg=
2010-01-01 00:00:00 Initialize: SPY 0.25
2010-01-01 00:00:00 Initialize: VCLT 0.25
2010-01-01 00:00:00 Initialize:-
2010-01-04 10:00:00 OnData-Slice: SPY Price=112.8300
2010-01-04 10:00:00 OnData-Slice: Purchased Stock SPY 0.25% quantity=22
2010-01-04 10:00:00 OnData-Slice: VCLT Price=0
2010-01-04 10:00:00 OnData-Slice: Bad quantity VCLT 0.25% quantity=0
2010-01-04 10:00:00 OnData-Slice: SPY time=01/04/2010 09:00:00 open=112.3700 high=112.9400 low=112.3300 close=112.8300 volume=17467767 Value=112.8300
2010-01-04 11:00:00 OnData-Slice: SPY Price=113.1000
2010-01-04 11:00:00 OnData-Slice: VCLT Price=74.2100
2010-01-04 11:00:00 OnData-Slice: Purchased Stock VCLT 0.25% quantity=33
...
So my question is what's the best way to handle this, using Securities like I'm doing doesn't feel right?
Alexandre Catarino
For accessing each security new information, you should use the Slice (or TradeBars) object. So instead of using Securities[security.symbol].Price, use data.Bars[security.symbol], intead.
Before that, check whether the security was included in the Slice (or TradeBars) object. You can do something like this:
public override void OnData(Slice data) { /* ... */ // Only loop through my_security items // which symbol are included in data foreach (var security in my_securities .Where(x => data.Bars.ContainsKey(x.symbol)) { var symbol = security.symbol; var price = data.Bars[symbol].Price; /* ... */ } }
Wink Saville
Thanks, that is much better! I tweaked the .Where statement so it would work for Ticks or Bars:
foreach (SecurityParam security in my_securities .Where(x => data.Bars.ContainsKey(x.symbol) || data.Ticks.ContainsKey(x.symbol)))
For anyone interested attached is the backtest with the .Where and other cleanup as well as defaulting to Resolution.Tick from 1/1/2010 to 1/5/2010.
Wink Saville
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!