I am trying to convert the strategy below to QC in order to be able to test and have the ability to test with Interactive Brokers.
Assistance is greatly appreciated.
/* Modified as described in post #33*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using System.Globalization;
namespace WealthLab.Strategies
{
public class OptionATMv2 : WealthScript
{
Dictionary<string, Bars> _contracts;
StrategyParameter _plot;
StrategyParameter _minDays;
StrategyParameter _round;
StrategyParameter _fast;
StrategyParameter _slow;
public OptionATMv2()
{
_plot = CreateParameter("Plot Options=1", 1, 0, 1, 1);
_minDays = CreateParameter("Days out (min)", 1, 0, 21, 1);
_round = CreateParameter("Round down", 1, 0.5, 5, 0.5);
_fast = CreateParameter("EMA fast", 10, 2, 20, 2);
_slow = CreateParameter("EMA slow", 30, 20, 50, 5);
}
private DateTime OptionExpiryDateForMonth(DateTime tempDate)
{
tempDate = new DateTime(tempDate.Year, tempDate.Month, 1);
while (tempDate.DayOfWeek != DayOfWeek.Friday) // find first friday
tempDate = tempDate.AddDays(1);
return tempDate.AddDays(14); // add two weeks
}
double FloorIt(double price, double interval)
{
double f = 1d / interval;
double r = price * f;
r = Math.Floor(r);
r /= f;
return r;
}
string GetOptionSymbol(string underlying, DateTime expiry, double strike, bool call = true)
{
string putcall = call == true ? "C" : "P";
return String.Format("-{0}{1}{2}{3}", underlying, expiry.ToString("yyMMdd"), putcall, strike);
}
string GetATMOptionSymbol(int bar, bool call = true)
{
double strike = FloorIt(Close[bar], _round.Value);
string osym = GetOptionSymbol(Bars.Symbol, GetNextExpiry(bar), strike, call);
//PrintDebug(bar + "\t" + Date[bar].ToString("yyyyMMdd") + "\t" + osym);
return osym;
}
// Find the expiry at least n calendar days out from the last bar
DateTime GetNextExpiry(int bar)
{
DateTime nextExpiry = NextOptionExpiryDate(bar);
int tradingdays = this.TradingDaysBetweenDates(Date[bar].Date, nextExpiry);
if (tradingdays < _minDays.ValueInt)
nextExpiry = OptionExpiryDateForMonth(nextExpiry.AddMonths(1));
return nextExpiry;
}
Bars GetOptionData(int bar, bool isCall = true)
{
DateTime nextExpiry = GetNextExpiry(bar);
double strike = FloorIt(Close[bar], _round.Value);
Bars obars = CreateSyntheticOption(nextExpiry.AddMonths(-2), nextExpiry, strike, isCall);
return obars;
}
// return a date 1 day prior to expiry
DateTime OptionExDate(string osymbol)
{
// e.g. !SPY_216.00_161216_CALL
string[] s = osymbol.Split(new char[] {'_'});
DateTime exdate = DateTime.ParseExact(s[2], "yyMMdd", new CultureInfo("en-US"));
return exdate.Date.AddDays(-1);
}
protected override void Execute()
{
ClearDebug();
// Dictionary to hold on-demand contracts
_contracts = new Dictionary <string, Bars>();
// Let's put the most recent data in the dictionary
Bars obars = GetOptionData(Bars.Count - 1);
_contracts.Add(obars.Symbol, obars);
// Create and plot the EMAs of the underlying
DataSeries ema10 = EMA.Series(Close, _fast.ValueInt, EMACalculation.Modern);
DataSeries ema30 = EMA.Series(Close, _slow.ValueInt, EMACalculation.Modern);
PlotSeries(PricePane, ema10, Color.Blue, LineStyle.Solid, 1);
PlotSeries(PricePane, ema30, Color.Red, LineStyle.Solid, 1);
HideVolume();
for(int bar = 20; bar < Bars.Count; bar++)
{
if (IsLastPositionActive)
{
Position p = LastPosition;
if (Bars.IsLastBarOfDay(bar))
ExitAtClose(bar, p);
else if (CrossUnder(bar, ema10, ema30)
|| Date[bar] >= OptionExDate(p.Symbol))
{
ExitAtMarket(bar + 1, p);
SetPaneBackgroundColor(PricePane, bar, Color.FromArgb(40, Color.Red));
}
}
else if (CrossOver(bar, ema10, ema30))
{
/* Buy the ATM call */
obars = GetOptionData(bar);
if (!_contracts.ContainsKey(obars.Symbol)) _contracts.Add(obars.Symbol, obars);
SetContext(obars);
BuyAtMarket(bar + 1);
SetBackgroundColor(bar, Color.FromArgb(40, Color.Green));
RestoreContext();
}
}
if (_plot.ValueInt == 1)
{
// Done trading, let's plot the option contracts and trades
foreach (KeyValuePair<string, Bars> kvp in _contracts)
{
//PrintDebug(kvp.Key);
Bars optBars = kvp.Value;
if (optBars != null)
{
ChartPane optPane = CreatePane(20, true, true);
PlotSymbol(optPane, optBars, Color.Green, Color.Red);
this.PlotSymbolTrades(optBars, optPane);
}
}
}
}
}
}