I am stuck on the last execrise "Visualizing the Stop Levels". Below is my code (what I have so far):
class BootCampTask(QCAlgorithm):
def Initialize(self):
self.AddEquity("SPY", Resolution.Daily)
def OnData(self, data):
self.Plot("Data Chart", "Asset Price", self.Securities["SPY"].Price)
if self.Portfolio.Invested:
self.Plot("Data Chart", "Stop Price", 0.9 * self.orderTicket.Get(OrderField.StopPrice))
The task requires two series "Asset Price" and "Stop Price". However, the error message says
Exercise Hint: You should create exactly three different series.
Also, I tried the "solution" (solution.py), but it is not in Python, probably C#
namespace QuantConnect
{
class OrderManagementBootCampLesson : QCAlgorithm
{
// Main asset we intend to trade
private string _mainAssetTicker = "SPY";
// Stop loss price as a percentage of main asset close price
private decimal _stopLossRatio = 0.90m;
// Order ticket for our stop loss
private OrderTicket _stopLossTicket;
// Datetime when stop loss or take profit was last hit
private DateTime _lastLimitHitAt;
// The highest close price our main asset has achieved since placing our market order
private decimal _highestClose = -1m;
// Take profit price as a percentage of main asset close price
private decimal _takeProfitRatio = 1.10m;
// Order ticket for our take profit
private OrderTicket _takeProfitTicket;
public override void Initialize()
{
SetStartDate( 2018, 12, 1 );
SetEndDate( 2019, 4, 1 );
SetCash( 100000 );
AddSecurity( SecurityType.Equity, _mainAssetTicker, Resolution.Daily );
}
public override void OnData( Slice slice )
{
// Plot the asset price in a separate chart
Plot( "Data chart", "Asset price", Securities[_mainAssetTicker].Close );
// Check that at least 15 days (~3 weeks) have passed since we last hit our limit order
if ( ( Time - _lastLimitHitAt ).TotalDays < 15 )
return;
if ( !Portfolio.Invested ) {
// Create market order for some units of SPY
MarketOrder( _mainAssetTicker, 500 );
// Create stop loss through a stop market order
_stopLossTicket = StopMarketOrder( _mainAssetTicker, -500, _stopLossRatio * Securities[_mainAssetTicker].Close );
// Store current price as the highest price
_highestClose = Securities[_mainAssetTicker].Close;
// Create take profit through a limit order
_takeProfitTicket = LimitOrder( _mainAssetTicker, -500, _takeProfitRatio * Securities[_mainAssetTicker].Close );
} else {
// Update stop loss price if main asset has risen above its highest price
if ( Securities[_mainAssetTicker].Close > _highestClose ) {
_stopLossTicket.Update( new UpdateOrderFields() { StopPrice = Securities[_mainAssetTicker].Close * _stopLossRatio } );
_highestClose = Securities[_mainAssetTicker].Close;
Debug( "SL:" + Securities[_mainAssetTicker].Close * _stopLossRatio );
}
// Plot the current stop loss price
Plot( "Data chart", "Stop loss price", _stopLossTicket.Get( OrderField.StopPrice ) );
// Plot the current take profit price
Plot( "Data chart", "Take profit price", _takeProfitTicket.Get( OrderField.LimitPrice ) );
}
}
public override void OnOrderEvent( OrderEvent orderEvent )
{
// Only act on fills (ignore submits)
if ( orderEvent.Status != OrderStatus.Filled )
return;
// Log order fill price (can be extended to log more information)
Debug( orderEvent.FillPrice );
// Check if we hit our stop loss
if ( _stopLossTicket != null && orderEvent.OrderId == _stopLossTicket.OrderId ) {
_lastLimitHitAt = Time;
// Cancel the take profit, we no longer need it
_takeProfitTicket.Cancel();
}
// Check if we hit our take profit
else if ( _takeProfitTicket != null && orderEvent.OrderId == _takeProfitTicket.OrderId ) {
_lastLimitHitAt = Time;
// Cancel the stop loss, we no longer need it
_stopLossTicket.Cancel();
}
}
}
}