Previous: Machine Learning

Workshop 8: Options Trading

An option is a contract that gives its owner the right to buy (call option) or sell (put option) a financial asset (the underlying) at a fixed price (the strike price) at or before a fixed date (the expiration date). Options trading has the reputation to be more rewarding, but also more complex than trading currencies or stocks. At least for the script, the latter is not true; Zorro allows easy and straightforward coding of options strategies. Here's an example of a simple options selling system (Workshop8.c):

#include <contract.c>

#define PREMIUM  2.00 // $200 per contract 
#define DAYS     6*7  // 6 weeks to expiration

void run() 
  BarPeriod = 1440;

  History = "a.t8"; // artificial options data
  Multiplier = 100;

// load today's contract chain
  if(!contractUpdate(Asset,0,CALL|PUT)) return; 

  if(!NumOpenShort) { 
// find contracts with 6 weeks expiration and $2 premium
    { // sell a Strangle
      MarginCost = 0.15*priceClose()/2;

For backtesting this strategy, you can use artificially generated SPY options data (SPYa.t8) or real data (SPY.t8), both available on the Zorro download page. More about generating artificial options data and a general introduction in automated options trading can be found on Financial Hacker.

There are a few differences to a 'normal' trading system. We're using an asset list for the broker IB that contains the underlying stock, SPY, a fund following the S&P500 index. Option contracts usually cover batches of N stocks, often 100, which must be set through Multiplier. The contractUpdate function loads the current options chain - the list of options with all available combinations of expirations and strikes - either from historical data, or from the broker API. If no positions are open, the strategy attempts to sell short a put and a call contract with 6 weeks expiration at a bid price of 2 dollars per stock. The contractFind function scans the options chain for fitting contracts.  

The two contracts that match the desired bid price and expiration are now combined to a combo. Options and option combos can be traded with the usual enter functions, they must only be selected before with contract() or comboLeg() to distinguish the order from a trade with the underlying. The earned price - the premium, in total about 400 dollars minus commission - is booked on the account. That's not yet our profit, since we might be later obliged to sell or buy the underlying SPY stock at the strike price. The broker - or Zorro, respectively - will do that automatically when the underlying price at expiration date is not in our favor, and will deduct the difference of price and strike from our account. Otherwise, the contracts will expire worthlessly and we can keep the premium.

This combination of a put and a call contract is called a Strangle. Because we aimed for small premiums, our contracts start out of the money, meaning that the underlying price is below the call strike and above the put strike. This way we will normally win the premium, or most of it, when the SPY price does not move too far away until expiration. Otherwise, we'll lose. If the price moves a lot, we'll lose a lot.

Mind the MarginCost calculation. It is needed for a realictic backtest, since margin determines the required capital. Brokers use a different margin formula for any options combination, so it should be calculated in the script. Here we assume that the margin of a sold strangle is the premium (which is automatically added) plus 15% of the underlying price. We divide that by 2 because MarginCost is per stock, but the used margin formula is for the whole strangle. For this formula to work, the historical prices that we're using (priceClose) must be not adjusted for splits and dividends. That's the case for the SPY options history from the download page.

The result

We can see that the strategy achieves not spectacular, but relatively constant annual returns in the 20% area. 84% of all trades are won - that's the statistical seller advantage of options trading. The result is based on artificial options data, but real historical data - available from data vendors at some hundred dollars for daily SPY contracts - produces a similar result.

It is not advisable to trade this system unchanged. For live trading some issues must be considered, for instance allocating the right number of lots for a given capital, or disposing of assigned stock when getting exercised. The script also has no mechanism for filtering unprofitable periods and limiting losses. We can see the dips in the equity curve whenever the S&P500 strongly rises or falls. We could place a stop loss just like for a normal trading system. The contracts are then automatically bought back when the underlying price moves dangerously far. Another solution is buying 'insurance' in the form of two additional contracts with more distant strikes. This long/short combination of 4 contracts reduces the profit, but also restricts losses to a limit that can be determined with the strike prices. The Payoff script can display the risk and profit curves of arbitrary option combinations.

We're now at the end of the strategy coding course. For writing your own systems, it can save you a lot of time when you flip through this manual and make yourself familiar with Zorro's math and statistics functions. Often-used code snippets for your own scripts and strategies can be found on the Tips & tricks page. Writing good code and fixing bugs is described under Troubleshooting. If you worked with a different trade platform before, read the Conversion page about how to convert your old scripts or EAs to C. For serious strategy development, some knowledge of the leading data analysis software R can be of advantage - check out the R lectures.

What have we learned in this workshop?

Further reading: ►contract, combo