A free covered call calculator for the ThinkorSwim option chain: one column shows each call's return if you keep the premium and if you're called away.
Download CalculatorFor educational use. Not investment advice.
In this tutorial I build a covered call calculator for the ThinkorSwim option chain. It’s a custom quote column that prints 2 returns next to every call strike: what you make if you keep only the premium, and what you make if your shares are called away at the strike. With it you can compare strikes, expirations and stocks without filling in a spreadsheet.
The video has 4 parts: a comparison with rental income, the math in Excel, the thinkScript code, and a live example in KOPN. It’s for traders who already sell covered calls and want the numbers faster, and for anyone weighing the strategy for the first time. The finished code is a free download.
A covered call is a trade where you own 100 shares of a stock and sell 1 call option against them. Selling the call gives the buyer the right to buy your shares at the strike price, and you collect the premium for it. In the video I treat the shares like a rental house and the premium like the rent.
Two outcomes matter at expiration, and the covered call calculator prices both of them:
The rental comparison in Part 1 of the video uses a house for sale in Indiana as the baseline. The seller’s worksheet listed a cash price of $67,500 and $373.34 of monthly cash flow after expenses. I used about 1% a month as the rent baseline and left equity appreciation out of it.
Next I priced the at-the-money call in the April monthly series, 25 days from expiration, on 4 stocks from 4 volatility tiers. These are the quotes from the day of the video:
| Stock | Volatility tier | Implied volatility (April series) | Return if not exercised | Return if exercised |
|---|---|---|---|---|
| AT&T (T) | Low | 25% | 1.44% | 2.25% |
| Fastly (FSLY) | Mid | 74.49% | 5.3% | 11.23% |
| CURI | High | 119% | 9.32% | 18% |
| AMC | Very high | 196% | 19% | A little above 19% |
Every tier in the table cleared the 1% rent baseline, and the premium rose with implied volatility. That extra premium is pay for extra risk: you have to be willing to sit in the shares if the volatility takes them lower. At AMC’s 196%, the premium alone was 19%, and being called away added only a little more.
Real estate is a different asset class with different risks, so the comparison is apples to oranges. Premiums also change with price and implied volatility every day, so treat these numbers as the video’s snapshot.
The covered call calculator runs 2 formulas, and Part 2 of the video builds them in Excel before writing any code. Each row needs 4 inputs: the symbol, the stock’s closing price, the strike of the call you’d sell, and the premium you’d collect. The return is measured against the cost of 100 shares.
| Return | Formula (1 contract, 100 shares) | AT&T 30 strike in the video |
|---|---|---|
| If not exercised | Premium / (stock price x 100) | $43 / $2,976 = 1.44% |
| If exercised | (Premium + (strike – stock price) x 100) / (stock price x 100) | ($43 + $24) / $2,976 = 2.25% |
For AT&T, the stock closed at $29.76 and the 30 strike call last traded at $0.43, or $43 for 1 contract. If the call isn’t exercised, the return is the $43 premium. If it is, you sell the shares at $30, a gain of $0.24 a share or $24, so the total return is $67.
The 31 strike shows the trade-off. It paid only $18, or 0.60%, but if exercised it returned $142, or 4.77%, because the strike sits further above the stock price.
The if-called return is also the most a covered call can make by expiration: above the strike, your shares go at the strike however high the stock trades. The premium lowers your breakeven on the shares by the same amount, so on AT&T’s 30 strike it moves from $29.76 to $29.33. Neither formula counts dividends, and both cover the time to expiration, not a full year.
Google Sheets makes this step faster, because its Google Finance function can fill in the current price for you. Either way, one strike by hand is quick, and comparing every strike, every expiration and a few stocks (AT&T against Verizon and T-Mobile, say) takes far too long.
The web calculator at the top of this page runs the same 2 formulas for one trade. Enter the stock price, strike, premium and number of contracts, and it shows the premium received, the premium return and the total return if called away. Its optional cost basis field adds both returns measured from your own entry price.
The covered call calculator lives in a custom quote column on the option chain, so it goes in the Trade tab instead of on a chart. Here are the steps from the video:
ThinkorSwim gives you a limited number of custom quotes, and the same slots feed dashboard scripts and other option scripts, so plan which ones you keep loaded. To edit the code later, go back to Layout, then Customize, and click the same scroll icon.
If you haven’t added custom code to ThinkorSwim before, our guide on how to import a study into ThinkorSwim covers the basics.
The calculator’s code is 8 statements of thinkScript, and its math lines follow the columns of the Excel sheet. I built it one line at a time and tested each value with a label before moving on.
def maxShares = 100;
def maxContracts = 1;
I define these once so they’re easy to change in one place. They matter if you later want to see returns in dollars against a monthly income goal. If you change them, change both together (2 contracts and 200 shares) so the percentages stay the same.
def premium = maxContracts * close * 100;
Here close is the last price of the option itself. The custom quote runs on each strike’s row, so close reads that strike, and times 100 gives the premium in dollars for 1 contract. When I tested it on AT&T, the column showed 43 for the 30 strike and 18 for the 31 strike.
def premiumPct = premium/(MaxShares * close(getUnderlyingSymbol()));
close(getUnderlyingSymbol()) reads the stock’s close instead of the option’s, so the bottom of the fraction is the cost of 100 shares. For AT&T at $29.76 it returned 1.44%, the same as the Excel sheet. thinkScript ignores capitalization, so MaxShares and maxShares are the same variable.
def strikePriceGain = getStrike() - close(getUnderlyingSymbol());
def premiumPlusSharesPct = ((strikePriceGain * maxShares) + premium)/(MaxShares * close(getUnderlyingSymbol()));
getStrike() returns the strike of the row. Subtracting the stock price gives the gain per share if the shares are called away, $0.24 for AT&T’s 30 strike. That gain times 100 shares, plus the premium, over the cost of the shares gave 2.25%.
For a strike below the stock price the gain is negative, so the second number can fall below zero. In the KOPN option chain screenshot further down, the April 2.5 strike shows 73.61% | -3.95%.
AddLabel(yes, AsPercent(premiumPct) + " | " + AsPercent(premiumPlusSharesPct), if premiumPlusSharesPct >= 0.5 then color.green else color.white);
AddLabel prints both numbers with AsPercent, split by a bar: the premium return on the left and the if-called return on the right. The label turns green when the if-called return is 0.5 (50%) or more and stays white otherwise. I set it to an outrageous 50% in the video. It’s an arbitrary number, so pick your own.
KOPN is the stock I used to apply the covered call calculator in Part 4 of the video, because I already had a reason to be bullish on it. It had a Slingshot Squeeze and a Squeeze Signal on the daily chart, and the Slingshot Squeeze stats on the chart showed 2 winners and 1 loser, with an average win of 15.96% and an average loss of 0.48%.
The 127.2% Fibonacci extension sat at $15.68 and the 161.8% extension at $18.30. If I expected a move into that zone, a strike between those levels was the place to sell a call. For more on trading Fibonacci levels, see our Fibonacci Trading Course.
With 100 shares bought at $11.14, the calculator showed these returns on the calls I looked at in the video:
| Expiration (days left) | Strike | Return if not exercised | Return if exercised |
|---|---|---|---|
| April 16, 2021 (26) | 17.50 | 4.94% | 62.03% |
| April 16, 2021 (26) | 20 (16 delta) | 2.87% | 82.41% |
| May 21, 2021 (61) | 20 | 8.08% | 87.61% |
| July 16, 2021 (117) | 20 | About 16% | Not read out |
The 17.50 strike is where KOPN’s April calls first crossed the 50% threshold. If KOPN stayed below $17.50 through April 16, the premium alone returned 4.94%. If the shares were called away at $17.50, the total return was 62%.
The 20 strike, a 16 delta call, still paid 2.87%, between $30 and $40, and returned 82.41% if exercised. In rental terms, the house cost about $1,100 and the 20 strike paid about $35 of rent for 26 days. Lower strikes paid upwards of $150, if you were willing to sell the house fairly quickly.
If KOPN finished between the 2 extensions, below the 20 strike, the call would expire and I’d keep 100% of the premium. Then I could sell a call in the May series at a higher strike and repeat the trade.
The covered call calculator shows every expiration already calculated, so comparing series takes seconds. Going from the 26-day April series to the 61-day May series, the 20 strike’s premium return rose from 2.87% to 8.08%. That’s 5.21% more premium for 35 more days of risk.
The trade-off: the May 20 strike had less liquidity than the April one, and you have to stay in the trade longer while the premium erodes. I prefer the series around 30 days to expiration, where theta decay starts to work in your favor.
The covered call calculator handles the math, and the chart picks the strike. I look for strikes near a level where I’d be happy to sell my shares anyway, like the Fibonacci extensions on KOPN. Then I use the column to compare the premium return and the if-called return at each one, across a few expirations, and pick the strike that pays best for that plan.
The premium is your only cushion if the stock drops: you hold all 100 shares through the decline. And if it rallies past your strike, your shares are called away and you give up the gain above it. Decide before you buy where you’d sell the shares if the trade fails, and size the position so that loss is a small, fixed part of your account.
The covered call calculator is Part 1 of our options calculator series for the ThinkorSwim option chain. The other calculators reuse the math on this page:
Most covered call calculator problems come from how custom quotes work in ThinkorSwim:
maxPctThreshold input set to 0.5, but the AddLabel line compares against a typed-in 0.5. Edit that number, or swap in the input with the edit below.Here is my suggested edit for the threshold. It isn’t in the video or the download: replace the AddLabel line with this one, which compares against maxPctThreshold instead of 0.5.
AddLabel(yes, AsPercent(premiumPct) + " | " + AsPercent(premiumPlusSharesPct), if premiumPlusSharesPct >= maxPctThreshold then color.green else color.white);
With that change, the input controls the color, as a decimal: 0.3 means 30%. In the video, AT&T’s chain showed no green at all with 35 strikes listed, while KOPN turned green from the 17.50 strike up. For another script that reads the option chain, see our Option Chain Relative Value tutorial.
<pre><code>#Written by TOS Indicators - 2021
#Home of the Volatility Box
#Covered Call Calculator
#Tutorial: https://www.tosindicators.com/indicators/covered-call-calculator
#The following thinkSript code needs to be pasted in a Custom Quote script on the options chain.
input maxPctThreshold = 0.5;
def maxShares = 100;
def maxContracts = 1;
def premium = maxContracts * close * 100;
def premiumPct = premium/(MaxShares * close(getUnderlyingSymbol()));
def strikePriceGain = getStrike() - close(getUnderlyingSymbol());
def premiumPlusSharesPct = ((strikePriceGain * maxShares) + premium)/(MaxShares * close(getUnderlyingSymbol()));
AddLabel(yes, AsPercent(premiumPct) + " | " + AsPercent(premiumPlusSharesPct), if premiumPlusSharesPct >= 0.5 then color.green else color.white);</code></pre>Want the .ts file and the one-click import? Both come with a free account.
Join 40,000+ traders using institutional-grade tools for ThinkOrSwim.
Get the Bundle