| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 |
namespace QuantConnect
{
/*
* Basic Template Algorithm
*
* The underlying QCAlgorithm class has many methods which enable you to use QuantConnect.
* We have explained some of these here, but the full base class can be found at:
* https://github.com/QuantConnect/Lean/tree/master/Algorithm
*/
public class BasicTemplateAlgorithm : QCAlgorithm
{
public String StockTicker = "SPY";
public Symbol OptionSymbol;
private const decimal GoalRate = 0.25M;
private const decimal GoalFactor = 1 + GoalRate;
public RollingWindow<Decimal> PercentChangeH = new RollingWindow<Decimal>(1);
public Decimal PercentChange;
public RateOfChangePercent PercentChangeI;
private string OrderTrackingDebugStr = "";
public int OrderQuantity (decimal cash, decimal price) {
return (int) Math.Floor(cash / price);
}
bool HasOrderOrHolding = false;
public override void Initialize()
{
// backtest parameters
SetStartDate(2016, 07, 1);
SetEndDate(DateTime.Now);
// cash allocation
SetCash(3000);
// request specific equities
// including forex. Options and futures in beta.
var equity = AddEquity(StockTicker, Resolution.Daily);
//AddForex("EURUSD", Resolution.Minute);
// Must add option universe filter
var option = AddOption(StockTicker, Resolution.Daily);
OptionSymbol = option.Symbol;
option.SetFilter(universe => from symbol in universe
// default is monthly expirations only
.Expiration(TimeSpan.FromDays(30), TimeSpan.FromDays(60))
where symbol.ID.OptionRight == OptionRight.Call
where Math.Abs(symbol.ID.StrikePrice - universe.Underlying.Price) < 10
select symbol);
// use the underlying equity as the benchmark
SetBenchmark(equity.Symbol);
PercentChangeI = ROCP(StockTicker, 1, Resolution.Daily);
}
/*
* New data arrives here.
* The "Slice" data represents a slice of time, it has all the data you need for a moment.
*/
public override void OnData(Slice data)
{
if (!PercentChangeI.IsReady) return;
PercentChangeH.Add(PercentChangeI);
PercentChange = PercentChangeH[0];
Plot("Daily", PercentChangeI);
ExecuteShort(data);
ExecuteLong(data);
}
public void ExecuteLong(Slice slice)
{
if (HasOrderOrHolding) { return; } // We already have a position
if ((PercentChange < -0.02m)
&& (PercentChange > -0.125m) // -2.5 to -12.5%
)
{
OptionChain chain;
if (slice.OptionChains.TryGetValue(OptionSymbol, out chain))
{
var contract = (
from optionContract in chain.OrderByDescending(x => x.Strike)
select optionContract
).FirstOrDefault();
if (contract != null)
{
HasOrderOrHolding = true;
MarketOrder(contract.Symbol, OrderQuantity(Portfolio.Cash, contract.AskPrice) );
}
}
}
}
public void ExecuteShort(Slice slice)
{
foreach (var security_option in Securities)
{
if ((security_option.Value.Symbol.SecurityType == SecurityType.Option) && (security_option.Value.Invested))
{
Decimal midPrice = MidPrice(security_option.Value.BidPrice, security_option.Value.AskPrice);
var currentGoal = ((security_option.Value.Holdings.AveragePrice * security_option.Value.Holdings.AbsoluteQuantity * 100) * GoalFactor) + security_option.Value.Holdings.TotalFees;
var currentValue = (midPrice * security_option.Value.Holdings.AbsoluteQuantity * 100);
Plot("Plotter", "HoldingGoal", currentGoal);
Plot("Plotter", "HoldingValue", currentValue);
OrderTrackingDebugStr = String.Format("{0} - POSITION IN {1} {2:0.00} {3} {4:MM/dd/yy} -- Cost {5:0.00} -- Will exit at {6:0.00} and current value={7:0.00}",
Time.ToString(),
security_option.Value.Symbol.Underlying,
security_option.Value.Symbol.ID.StrikePrice,
security_option.Value.Symbol.ID.OptionRight,
security_option.Value.Symbol.ID.Date,
security_option.Value.Holdings.AbsoluteHoldingsCost,
currentGoal,
currentValue
);
if (currentValue >= currentGoal)
{
HasOrderOrHolding = false;
Liquidate();
}
}
}
}
private void ShowOrderTracking()
{
if (HasOrderOrHolding)
Debug(OrderTrackingDebugStr);
}
private Decimal MidPrice(Decimal Low, Decimal High)
{
return Math.Round(((High - Low) / 2) + Low, 2);
}
}
}