| Overall Statistics |
|
Total Trades 2 Average Win 1.16% Average Loss 0% Compounding Annual Return 4.431% Drawdown 0.100% Expectancy 0 Net Profit 1.156% Sharpe Ratio 4.054 Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.043 Beta 0.015 Annual Standard Deviation 0.011 Annual Variance 0 Information Ratio 0.702 Tracking Error 0.108 Treynor Ratio 2.755 Total Fees $1.00 |
namespace QuantConnect
{
public partial class CoveredCallAlgorithm : QCAlgorithm
{
string _symbol = "BMY";
Symbol _equitySymbol;
Symbol _optionSymbol;
string phoneNumber = ""; // Fill this in ex 2125551212
private Slice lastSlice = null;
private bool orderedOnce = false;
public override void Initialize()
{
//Start and End Date range for the backtest:
SetStartDate(2012, 8, 8);
SetEndDate(2012,11, 12);
//SetEndDate(2016,8, 26);
//Cash allocation
SetCash(25000);
var equity = AddEquity(_symbol, Resolution.Minute);
_equitySymbol = equity.Symbol;
Securities[_symbol].SetDataNormalizationMode(DataNormalizationMode.TotalReturn);
var option = AddOption(_symbol);
_optionSymbol = option.Symbol;
// Call Side
/*option.SetFilter(universe => from symbol in universe
// default is monthly expirations only
.Expiration(TimeSpan.FromDays(10), TimeSpan.FromDays(55))
where symbol.ID.OptionRight == OptionRight.Call
&& (symbol.ID.StrikePrice - universe.Underlying.Price) / universe.Underlying.Price <= 0.10m // within 10%
select symbol);*/
// Put Side
option.SetFilter(universe => from symbol in universe
// default is monthly expirations only
.Expiration(TimeSpan.FromDays(10), TimeSpan.FromDays(55))
where symbol.ID.OptionRight == OptionRight.Put
&& (symbol.ID.StrikePrice - universe.Underlying.Price) / universe.Underlying.Price >= -0.15m // within 15%
select symbol);
Notify.Sms(phoneNumber,"SimpleShortPutExpirationTest Started");
Schedule.On(DateRules.EveryDay(_symbol), TimeRules.At(9, 35), () =>
{
ConsiderTrade();
});
}
//Data Event Handler: New data arrives here. "TradeBars" type is a dictionary of strings so you can access it by symbol.
public void OnData(Slice data)
{
if (IsWarmingUp) { return;}
lastSlice = data;
}
public override void OnEndOfDay()
{
//if (Time.Date == new DateTime(2012,09,22)) // Comment this out in live mode (for controlled backtest)
{
if (lastSlice == null) { return; }
Log(String.Format("{0} closed at {1}",
_symbol,
lastSlice.Bars[_symbol].Close.ToString("#.####")
));
}
}
private void ConsiderTrade()
{
if (orderedOnce) { return; }
if (Time.Date == new DateTime(2012,08,22)) // Comment this out in live mode (for controlled backtest)
{
Debug("Consider Trade");
if (lastSlice == null) { return; }
if (lastSlice.Bars == null) { return;}
if (!lastSlice.Bars.ContainsKey(_symbol)) { return; }
OrderCallOption(lastSlice);
}
}
public void OrderCallOption(Slice slice)
{
OptionChain chain;
if (slice.OptionChains.TryGetValue(_optionSymbol, out chain))
{
// find the first call strike under market price expiring today
var contracts = (
from optionContract in chain.OrderByDescending(x => x.Strike)
where optionContract.Right == OptionRight.Put
where optionContract.Expiry > Time.Date
where optionContract.Strike < chain.Underlying.Price
select optionContract
).Take(100);
// Show Chain
OptionContract contract = null;
foreach (OptionContract _contract in contracts)
{
Decimal pctOtm = ((_contract.Strike - _contract.UnderlyingLastPrice) / _contract.UnderlyingLastPrice) * 100;
Log(String.Format("Chain => Option Contract. Strike {0}, ULPrice={1}, Bid={2}, Ask={3}, Expiry={4} {5}, {6}%",
_contract.Strike,
_contract.UnderlyingLastPrice,
_contract.BidPrice,
_contract.AskPrice,
_contract.Expiry,
_contract.Expiry.DayOfWeek.ToString(),
pctOtm.ToString("#.####")
));
if (contract == null) { contract = _contract; }
}
if ((contract != null) && (!orderedOnce))
{
orderedOnce = true;
int numContracts = -10;
string message = String.Format("Order Option Contract. Strike {0} x {1}, ULPrice={2}, Bid={3}, Ask={4}, Expiry={5} {6}",numContracts,contract.Strike,contract.UnderlyingLastPrice,contract.BidPrice,contract.AskPrice,contract.Expiry,contract.Expiry.DayOfWeek.ToString());
Log(message);
Notify.Sms(phoneNumber,message);
MarketOrder(contract.Symbol, numContracts,tag:"Sell Option");
}else{
Debug("No Option Contract Found");
}
}else{
Debug("No Option Contract Found [TryGetValue]");
}
}
public override void OnOrderEvent(OrderEvent fill)
{
// if (fill.Status.IsFill())
{
string message = String.Format("Order {0} {1} x {2} at {3} commission={4} OrderId={5}",
fill.Status.ToString(),
fill.FillQuantity,
fill.Symbol,
fill.FillPrice,
fill.OrderFee,
fill.OrderId);
Log(message);
Notify.Sms(phoneNumber,message);
}
}
}
}