- ago
I am working on a monthly protective put strategy that I am trying to code for the backtester. You buy put contracts ATM (or as close to ATM) and the corresponding shares the day after OpEx. At time of option expiration, you either let the options exercise or sell the shares. Rinse and repeat. I have written pseudocode for my strategy below.

I am attempting to write the C# code, but I’m struggling with the following problems:
- Converting the options price to a double
- Not selling the option price when the option is ITM. It needs to be held until the end of expiration day so that it will exercise.

Pseudocode: NOTE: Please see image below for a better formatted version of pseudocode.

This Strategy purchases the day after options expiry

If today is options expiration day Then
If options are ITM Then
Let options exercise
End If
Else Then
Sell Shares
End Else
Calculate the next trading day
End If

If today is the day after OpEx Then
Calculate put option contract price using historical volatility, At-the-money strike price**
Calculate number of hundreds of shares able to purchase based on put option contract price
Calculate number of option contracts to purchase
Execute trade to purchase shares
Execute trade to purchase put option contracts
End If

** We are using conventional options expiration.

Here is my attempted C# code:
CODE:
using WealthLab.Backtest; using System; using WealthLab.Core; using WealthLab.Data; using WealthLab.Indicators; using System.Collections.Generic; namespace WealthScript1 { public class MyStrategy : UserStrategyBase { //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) {          // Grab the day afrter the options expiry date          if (bars.DateTimes[idx].IsOptionExpiry())          {             // Finding next trading day after OpEx             tradingDayAfterExpiry = idx + 1;             //Closing all open positions. I need to add code here that does not let ITM options sell.             foreach(Position pos in OpenPositions)                ClosePosition(pos, OrderType.Market); ;          }     // Purchase Options and corresponding Shares          if (idx == tradingDayAfterExpiry)          {             // identify an option contract symbol             string osym = OptionSynthetic.GetOptionsSymbol(bars, OptionType.Put, bars.Close[idx], bars.DateTimes[idx], 30, allowExpired: false);             _hash = Math.Abs(osym.GetHashCode());             //get the option bars             _obars = OptionSynthetic.GetHistory(bars, osym, 0.4);             _syms.Add(osym);             _expiry = OptionsHelper.SymbolExpiry(osym);                          //Use option greeks to pull the current option price             // I'm struggling in this area             TimeSeries iv = HV.Series(bars.Close, 21, 5) / 10d;             OptionGreek greeks = OptionSynthetic.GetGreeks(bars, bars.Count - 1, osym, iv.LastValue);             double optionPrice;             double.TryParse(greeks.OptionPrice.ToString(), out optionPrice);             WriteToDebugLog(optionPrice);             // Function to figure out how many contracts and shares to purchase             int HowManyAllocations()             {                double cash = CurrentCash;                double stockPrice = bars.Close[idx];                double realOptionPrice = optionPrice * 100; // Replace with your actual option contract price (multiplied by 100)                // Calculate the cost of one allocation (1 option contract and 100 shares)                double oneAllocationCost = (stockPrice * 100) + (optionPrice * 100);                int noAllocations = 0;                // Calculate the maximum number of allocations you can buy with the available cash                while (cash >= oneAllocationCost)                {                   cash -= oneAllocationCost;                   noAllocations++;                }                return noAllocations;             }             int optionsToBuy = HowManyAllocations();             int stocksToBuy = optionsToBuy * 100;             // buy number of contracts based on optionsToBuy             Transaction t1 = PlaceTrade(_obars, TransactionType.Buy, OrderType.Market, 0, _hash, "Protective Put Option Buy");             t1.Quantity = optionsToBuy;             // Buy number of shares based on stocksToBuy             Transaction t2 = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, 0, "Purchasing Shares");             t2.Quantity = stocksToBuy;          }       } //The code below is for charting the options       public override void Cleanup(BarHistory bars)       {          // don't overload the chart with panes - plot only the last 5 contracts that were traded in Single Symbol Mode                   if (!Backtester.Strategy.SingleSymbolMode)             return;          // Indicate the trades          foreach (Position p in GetPositionsAllSymbols())          {             if (p.Bars == bars || _syms.IndexOf(p.Symbol) < _syms.Count - 5)                continue;             PlotBarHistory(p.Bars, p.Symbol);             if (!p.NSF)             {                if (p.EntryBar > 0)                   DrawTextVAlign("▲", p.EntryBar, p.Bars.Low[p.EntryBar] * 0.95, VerticalAlignment.Top, WLColor.NeonBlue, 16, 0, 0, p.Symbol, true);                if (p.ExitBar > 0)                   DrawTextVAlign("▼", p.ExitBar, p.Bars.High[p.ExitBar] * 1.05, VerticalAlignment.Bottom, WLColor.NeonFuschia, 16, 0, 0, p.Symbol, true);             }          }       }       //declare private variables below       private int tradingDayAfterExpiry;       private DateTime OpEx;       private int numberContracts;       private Double price;              //Options Variables       string _osym;       DateTime _expiry;       BarHistory _obars; // the option's BarHistory       int _hash = -1;       UniqueList<string> _syms = new UniqueList<string>(); } }

0
490
2 Replies

Reply

Bookmark

Sort
- ago
#1
Here is an easier to read version of the pseudocode:
0
Cone8
 ( 4.83% )
- ago
#2
Why would you do this?
CODE:
            double optionPrice;             double.TryParse(greeks.OptionPrice.ToString(), out optionPrice);             WriteToDebugLog(optionPrice);
.. when greeks.OptionPrice is already double value. Just use it.

As for "exercise", there's no such thing here. You need to create your own method(s) to do that. Options will close at some price and there will be a profit or a loss on those contracts. That's one position. Then you need to buy or sell the stock shares. That's a separate position.

You're not even using _expiry to determine if you've reached that date for the trading actions.
0

Reply

Bookmark

Sort