Options, Futures, FOPs

The following functions can be used for selecting, analyzing, and trading options, futures, and options on futures (FOPs). Since they have additional parameters, namely type, strike, and expiration, options trading is a bit more complex than trading the underlying. For a brief introduction to options trading, read the Black Book chapter 8, or visit Financial Hacker.

contractUpdate (string Name, int Handle, int Mode): int

Loads a new contract chain of type Mode (see below) for the current underlying and the current day. The contract chain contains all options, futures, or FOP contracts available at a certain date. It is required for all the subsequent contract functions and for entering or exiting contract positions.
  Contract chains are only loaded when the LookBack period is over and real trading begins. They are loaded individually per asset and can be directly accessed with the Contracts pointer. Chains are automatically sorted at loading: first by expiration date, then by strike. This allows fast finding a certain option or combo. NumContracts is set to the number of contracts in the chain, which is also returned. If no contract chain for the current or given time is found, 0 is returned.
  In [Test] or [Train] mode the chain is either read out of a contract chain file given by Name.t8 at or before the current time, or from a previously loaded dataset of contracts when its Handle is nonzero. Name can contain month or day numbers for monthly or daily historical contract files. If Name is 0, the current asset name is used. If the global Now variable is nonzero in [Test] or [Train] mode, it is used for filtering contracts instead of the current time. ContractRow is set to the row of the first found contract in the dataset, which allows to load extra data, such as greeks, from a second parallel dataset.
  In [Trade] mode the chain for the symbol Name is either downloaded from the broker API, or - when Handle is nonzero - filled from a previoulsy loaded dataset with no date/time filtering. If Name is 0, the current asset name is used. For contracts that are no US stocks or traded on multiple exchanges, Name should be a symbol with exchange, currency, and for futures the expiration date (e.g. "N225-FUT-20220609-225-OSE.JPN-JPY"). For limiting the chain to a particular trading class, use the SET_CLASS command.

contractRecord (string Name, var MinStrike, var MaxStrike, int MinDays, int MaxDays)

Appends the current contract chain to the begin of the .t8 contract history file in [Trade] mode. This allows recording live contract chains for re-training or other purposes. The prices of all recorded contracts are loaded from the broker API. Because loading contract prices can take a long time (up to 10 seconds per option contract with the IB API), the strike range and life time can be limited with the MinStrike, MaxStrike, MinDays, MaxDays parameters. Only contracts that fall into the limits and have a nonzero price are recorded. If the limits are 0, prices for the whole chain are loaded. Example: contractRecord(0,priceClose()-50,priceClose()+50,1,70); appends all contracts within a +/-50 strike range and up to 70 days expiration at the begin of the .t8 file of the current asset.

contract (int Type, int Expiry, var Strike): CONTRACT*

Selects the option or future contract from the current option chain that matches exactly the given Type (including FUTURE or EUROPEAN), Expiry date, and Strike value. Returns a CONTRACT pointer to the found contract, or 0 when no such contract was found. If a contract is selected, enterLong and enterShort will buy or write (sell short) the contract instead of the underlying asset. The function sets up ContractStrike, ContractExpiry and other contract variables, and sets ContractRow to the row of the selected contract in the historical dataset or in the options chain. Calling asset(), contractUpdate(), or contract(0,0,0) deselects the contract and allows again trading with the underlying.

contract (int Type, int Days, var Strike): CONTRACT*

As above, but selects the option or future contract that has an expiration of at least the given minimum life time in Days and strike closest to the given Strike value. Returns the CONTRACT pointer, or 0 when no contract with matching Type, at least Days life time, and a strike closer than 10% to Strike was found. 

contract (int N): CONTRACT*

As above, but selects the Nth contract from the current contract chain, where N = 1..NumContracts. If N = 0, the currently selected contract is deselected in order to allow trading with the underlying.

contract (CONTRACT*): CONTRACT*

As above, but selects directly the given option or future contract, and does not alter ContractRow.

contract (TRADE*): CONTRACT*

As above, but selects the trade and its contract from the current contract chain. Returns 0 if no contract for this trade was found, which can happen at the expiration day or when the chain was not updated. Otherwise trade variables and contract variables are available for the trade and contract. 

contractNext (int Type, int Expiry, var Strike): CONTRACT*

As above, but selects and returns the option or future contract with the Type and Expiry, but the next-higher strike than the given Strike value. If Strike is negative, selects and returns the contract with the next-lower strike value. 

contractFind (int Type, int Days, var Find, int N): CONTRACT*

contractFind (int Type, int Days, var Find, int N, var MinStrike, var MaxStrike): CONTRACT*

contractFind (int Type, int Expiry, var Find, int N): CONTRACT*

contractFind (int Type, int Expiry, var Find, int N, var MinStrike, var MaxStrike): CONTRACT*

As above, but selects the option or future contract with the given Type, closest to the given minimum life time in Days, and a parameter closest to the given Find value. The parameter can be selected with N: 1 = ask, 2 = bid, 3 = fVal, 4 = fVol, 5 = fUnl, 6 = strike, 7 = strike distance from the underlying. The strike range can be optionally limited to MinStrike and MaxStrike for speeding up the function. Returns a CONTRACT pointer, or 0 when no contract was found. If a selected parameter is not yet available, such as ask, bid, or underlying price in live trading, it is automatically retrieved from the broker API. Depending on the number of contracts that match the expiration and strike range, this function can then take a long time (up to 10 seconds per contract) on the first call in live trading after loading a new contract chain. Subsequent calls are faster.

contractDays (CONTRACT*): var

contractDays (TRADE*): var

Returns the fractional number of calendar days until contract or trade expiration (see ExpiryTime). Returns a negative number when the expiration time is in the past. Note that the exact time to expiration depends on the time zone and market close time of the exchange where the contract is traded, so adapt ExpiryTime to your exchange when the exact life time in hours and minutes is needed. Note that many exchanges have restrictions to trading contracts at their expiration day.

contractPrice (CONTRACT*): var

contractPrice (TRADE*): var

Selects the contract and updates its current ask, bid, and underlying price, fill amount, and profit, either from the broker API, or from historical data by the last contractUpdate call. Returns the bid/ask mid price per underlying unit. Updating contract prices can be slow, depending on broker, Some broker plugins, such as IB, support a 'fast mode' by brokerCommand(SET_PRICETYPE,8); this can remarkably speed up the price update. For retrieving the underlying price in live trading, the GET_UNDERLYING command is used; for updating the fill amount, the BrokerTrade function is used and must be supported by the API. If the contract is not traded or the market data not subscribed, the function returns 0. Contract prices of open positions are automatically updated at any bar. If the underlying price is not available, it is updated from the current asset price. The underlying price is automatically copied to all contracts of the current chain with the same expiration date.  

contractUnderlying (): var

Returns the current unadjusted price of the underlying, in [Trade] mode from the broker and otherwise from the fUnl element of the first contract of the chain. contractUpdate must be called before. Note that FOPs have no common underlying price, but fUnl depends on the expiration and can be different for any contract. Source code in contract.c.

contractPosition (TRADE*): int

Returns the current number of open lots or open contracts of the given trade (negative values for a short position). Can be used for determining if a certain contract was expired or exercised by the broker. In live trading the GET_POSITION command must be supported by the broker API, and no other trades with the same contract type, strike, and expiry must be opened.

contractCheck (TRADE*, int Mode): int

Checks the option position on the broker account in live [Trade] mode. If it is still open, returns the total number of open contracts (negative for a short position). Otherwise it checks for an open position of the underlying, and returns the position size. If Mode is at 1 and no open contract was found, the trade is automatically closed with a "Lapsed" message. If Mode is at 3 and an underlying position was found, it is sold at market. Mode = 3 thus replicates the backtest behavior of expired options. The function can be called regularly in a for(open_trades) loop for keeping the positions between broker and strategy in sync. The GET_POSITION command must be supported by the broker API, and no other trades with the same contract type, strike, expiry, and underlying must be opened.

contractRoll (TRADE*, int Days, var Strike, function TMF): TRADE*

Rolls a closed option or future contract by opening a duplicate with the same type, volume, stop loss and profit distances, the given number of Days until expiration, the given Strike (0 for using the previous strike) and an optional trade management function. Returns a pointer to the new trade, or 0 if the contract could not be rolled. Source code in contract.c.

contractSellUnderlying (): int

Checks in [Trade] mode if any underlying position of the current asset is open, and if so, sells it at market. Returns the number of lots, or 0 when no underlying position was found. Source code in contract.c.

contractExercise (TRADE*)

Exercises an option contract. In the backtest, the option is closed at its intrinsic price (see remarks). In live trading, an order to exercise the option is sent to the broker. It is normally not immediately executed, but pending. Use contractCheck() for closing the trade and selling the underlying as soon as the order was executed. Don't call this function for European options before expiration, or for options that are not in the money.
 

contractVal (CONTRACT*, var Price, var HistVol, var Dividend, var RiskFree, var* Delta, var* Gamma, var* Vega, var* Theta, var* Rho): var

Returns the theoretical value and optionally the greeks of the given option contract at the given unadjusted Price of the underlying. Type, fStrike, and Expiry of the contract must be set; the other parameters don't matter. Expiry can be either an expiration date in the YYYYMMDD format, or alternatively the number of calendar days until expiration. HistVol is the underlying annual volatility of the log returns, f.i. by Volatility or VolatilityOV (usually over 20 days). Dividend is the continuous annual dividend yield per year of the underlying, as a fraction in the 0..1 range. RiskFree is the annual risk-free yield as a fraction in the 0..1 range, f.i. by yield()/100.
  Delta is the impact of an underlying price change on the option value, in the 0..1 range for calls and 0..-1 for puts. Gamma is the impact on Delta. Vega is the impact of a change of the underlying volatility, Theta is the impact of a change of the expiration time, and Rho is the impact of a change of the risk-free yield.
  The function uses R and the RQuantLib package; both must be installed (see remarks below). Source code in contract.c.

contractVol (CONTRACT*, var Price, var HistVol, var Value, var Dividend, var RiskFree): var

Returns the implied volatility (IV) of the given option contract with the given Value. For the parameters, see contractVal. The function uses R and the RQuantLib package; both must be installed on the trading PC (see remarks below). Source code in contract.c. The implied volatility is an estimate of the future volatility of the underlying, based on the current option parameters. If the contract has no value or if the strike price is too far or on the wrong side of the asset price, the function returns 0

contractDelta (int Type, int Days, var Price, var HistVol, var RiskFree, var Strike): var

Returns the theoretical delta of a contract of given Type with the given Days until expiration, unadjusted underlying Price, volatility HistVol, RiskFree yield rate, and Strike. Uses the formula Delta = cdf((ln(Price/Strike) + (r + (sigma^2)/2) * T) /(sigma * sqrt(T))). Source code in contract.c. Delta is the first derivative of the option value with respect to the underlying price, and can be used as a proxy of the probability to expire in the money. Note that some platforms and brokers use individual methods for calculating HistVol and thus produce different Delta values for the same contracts.

contractStrike (int Type, int Days, var Price, var HistVol, var RiskFree, var Delta): var

Returns the theoretical strike value of a contract of given Type with the given Days until expiration, unadjusted underlying Price, volatility HistVol, RiskFree yield rate, and Delta. Uses the formula Strike = Price * exp(-qnorm(Delta) * sigma * sqrt(T) + (r + (sigma^2)/2) * T). If a positive Delta is entered for a put, it is converted to the equivalent negative delta, so the same Delta value can be used for selecting put and call contracts. Source code in contract.c.

contractIntrinsic (CONTRACT*, var Price): var

contractIntrinsic (TRADE*, var Price): var

Returns the intrinsic value of the option contract per underlying unit at the given Price of the underlying. The intrinsic value of a call option is the difference between price and strike; for put options it's the difference between strike and price. A positive difference means that the option is in the money, a negative difference means it's out of the money. Type and fStrike of the contract or trade must be set; the other parameters don't matter. Source code in contract.c.

contractProfit (CONTRACT*, var Price, var Premium): var

Returns the profit per underlying unit of a contract sold or purchased at the given Premium when expiring at the given underlying Price. Premium is positive for sold, negative for bought contracts. Type and fStrike of the contract must be set; the other parameters don't matter. Trading costs are not included. The calculation of profit or loss is described in the remarks below. Source code in contract.c.

contractMargin (CONTRACT*, int AssetType): var

Calculates the margin cost of the given non-covered short put/call contract for the given AssetType (the margin of long contracts is simply their ask price). Uses the margin formula on the Interactive Broker's US Options Margin Requirements page. Source code in contract.c.

contractLetter (int AssetMonth): string

Returns the letter assigned to the given expiration month (F Jan, G Feb, H Mar, J Apr, K May, M Jun, N Jul, Q Aug, U Sep, V Oct, X Nov, Z Dec). Source code in contract.c.
  

contractPrint ()

Exports the current contract chain to a Data\*.csv file, for diagnostics purposes,

contractPrint (CONTRACT*)

Prints the given contract parameters to the log file for diagnostics purposes, in the order Date, Type, Expiry, Strike, Underlying, Ask, Bid, fVal, fVol. 

plotContract (int N, CONTRACT*, var HistVol, var Min, var Max, int Days, int Modus)

Plots the payoff diagram of N contracts (negative for selling) with volatility HistVol from price Min to price Max. Modus 0 initializes the plot and plots a zero line, Modus 1 plots the diagram at expiration, Modus 2 at the given Days into the lifetime (RQuantLib required), and Modus 3 plots the Delta. Type, strike, ask, bid, and expiry in days must be set in the CONTRACT struct. Source code in contract.c; usage example in PayOff.c.

 

yield(): var

Helper function, returns the current yield rate of 3-months US treasury bills in percent. Can be used as a proxy of the risk-free interest for calculating the values of option contracts (divide it by 100 for using it in contractVal or contractVol). Works in backtest as well as live trading. Uses the dataFromQuandl function. Zorro S required for Quandl data access; enter your Quandl key in the QuandlKey field in Zorro.ini. Source code in contract.c.

yieldCSV(): var

As above, but gets the current yield rate from an already-downloaded treasure history in History\FRED-DTB3.csv.

initRQL(): int

Helper function that initalizes RQuantLib. Call this in the INITRUN when contractVal or contractVol are used.

 

Parameters:

Name The name of the underlying, f.i. "ES" or "SPY", or the symbol - if different to the name - in live trading, or 0 for using the name or symbol of the current asset. For contract chains in backtest mode, use the name of the current .t8 file for loading monthly or daily files.
Handle A number from 1...800 that identifies a previously loaded dataset containing a CONTRACT list with historical options data; or 0 for automatically loading content from a historical file or from the broker API.
Mode PUT|+CALL for options, FUTURE for futures, PUT+CALL+FUTURE for options on futures.
Type The exact contract type to match, a combination of PUT, CALL, FUTURE, EUROPEAN, BINARY (f.i. PUT+EUROPEAN), plus the following optional flags:
+ONLYW3 - select only contracts that expire at the 3rd Friday, i.e. between the 16th and the 21th of the month.
+ONLYMATCH - select only contracts that exactly match the expiration date.
AssetType 1 for a currency, 2 for an index, 3 for stocks and ETFs. The margin for futures must be individually calculated.
Days The minimum number of calendar days until expiration. The closest expiration date will be selected.
Expiry The expiration date in the YYYYMMDD format.
Strike Option strike price, or 0 for futures.
Delta First derivative of the option value with respect to the underlying price. Determines the impact of an underlying price change on the option value, and can serve as a proxy of the probability to expire in the money. 0..1 for calls and 0..-1 for puts.
HistVol The historical annualized volatility of the underlying asset, as a fraction, f.i. 0.2 for 20%. Normally calculated with the Volatility or VolatilityOV indicators from the last 20 days. For the calculation of greeks, implied volatility is often used instead of historical volatility.
Dividend The annual dividend yield of the underlying, as a fraction, f.i. 0.02 for 2% dividend yield.
RiskFree The risk-free interest rate, as a fraction, f.i. yield()/100.
Value The value of the option for determining the implied volatility.
TRADE* The pointer of an option or future trade. Use ThisTrade for the trade pointer in a TMF or trade enumeration loop.

Remarks:

Examples:

// Sell call and put options at 1 stddev of the underlying
// Buy them back 2 days before expiration #include <contract.c> void run() { BarPeriod = 1440; BarZone = ET; BarOffset = 15*60; // trade at 3 pm Eastern time assetList("AssetsIB"); assetHistory("SPY",FROM_AV|UNADJUSTED); asset("SPY"); Multiplier = 100; contractUpdate(Asset,0,PUT|CALL); vars Close = series(priceClose()); int DTE = 6*7; // look for 6-week contracts var Strangle = StdDev(Close,20); CONTRACT* Call = contract(CALL,DTE,Close[0] + Strangle); CONTRACT* Put = contract(PUT,DTE,Close[0] - Strangle); if(!NumOpenTotal && Call && Put && !is(LOOKBACK)) { contract(Call); enterShort(); contract(Put); enterShort(); } // Check expiration and buy them back when in the money for(open_trades) { if(contractDays(ThisTrade) <= 2 && contractIntrinsic(ThisTrade,Close[0]) > 0) exitTrade(ThisTrade); } }
// Load high res contract chains from daily files like "SPY_20210505.t8"
if(day(0) != day(1)) { // new day?
  if(Live) // load a new contract chain without prices
    contractUpdate(0,1,CALL|PUT);
  else // load a new t8 file with prices 
    dataLoad(1,strf("History\\%s_%04d%02d%02d.t8",Asset,year(0),month(0),day(0)),9);
}
if(!Live) // in the backtest, update prices at any bar
  contractUpdate(0,1,CALL|PUT);
// Example script for converting EOD options data to .t8:
// Format: underlying symbol, exchange, date MMDDYYYY, adj close, option symbol, expiry MMDDYYYY, strike, Call/Put, American/European, ask, bid, volume, open interest, close
// Sample: "TLT,NYSEArca,04/10/2015,129.62,TLT   150410C00112500,04/10/2015,112.5,C,A,17.3,16.2,0,0,129.62"
string Format = ",,%m/%d/%Y,,,i,f,s,s,f,f,f,f,f";

void main() 
{
// first step: parse the CSV file into a dataset
  int Records = dataParse(1,Format,FILENAME);
  printf("\n%d Records parsed",Records);
// second step: convert the raw data to the final CONTRACT format
  for(i=0; i<Records; i++) 
  {
    CONTRACT* C = dataAppendRow(2,9);
    C->time = dataVar(1,i,0);
    string PC = dataStr(1,i,3);
    string EA = dataStr(1,i,4);
    C->Type = ifelse(*PC == 'P',PUT,CALL) + ifelse(*EA == 'E',EUROPEAN,0);
    int Expiry = dataInt(1,i,1); 
    C->Expiry = 10000*(Expiry%10000) + Expiry/10000; // MMDDYYYY -> YYYYMMDD
    C->fStrike = dataVar(1,i,2);
    C->fAsk = dataVar(1,i,5);
    C->fBid = dataVar(1,i,6);
    C->fVol = dataVar(1,i,7);
    C->fVal = dataVar(1,i,8); // open interest
    C->fUnl = dataVar(1,i,9);
    if(!progress(100*i/Records,0)) break; // show a progress bar
  }
  dataSort(2);
  dataSave(2,"History\\MyOptions.t8");
}

See also:

enterLong/Short, exitLong/Short, Quandl bridge, date functions, contract variables, contractCPD, combo, workshop 8

 

► latest version online