Finding the ATM strike

Discussion in 'Options' started by TheBigShort, Jan 27, 2019.

  1. I'm not sure I understand your question. The strike nearest to the current nderlying is usually considered the "ATM Strike" (or the interpolation between the two nearnest). Are you saying that Yahoo data for the weeklies doesn't include all strikes? If that is the case you can access the list of strikes-for-expiries for a given symbol from the OCC with this call:

    https://www.theocc.com/webapps/series-search?symbolType=U&symbol=AAPL

    You'll get back an ascii file with a few lines of headers and the rest space delimited rows sorted by expiry, strike. It includes all strikes.


    You can pretty easily match the NASDAQ index numbers to expiry dates. You need to do a regexp search for the following regular expresson:

    '<div id="OptionsChain-dates" .*> <a .*>[JFMASOND][a-y]{2} [12][0-9]</a>'

    There are still a few hidden rest API's for option chains; none as good as Barcharts free core-api used to be though. I will pm you on this, as Barchart closed off core-api access (put it behind proxies.barchart.com) due, I suspect, to low-post-count ET'ers over-using it. You can still get the barchart options chain json api to work but you have to send the right cookies and auth token along with the request, and since the auth token is generated by dynamically loaded javascript on the page and resets every 10 or so chain requests, you have to use Selenium (or, e.g. a custom coded version of ELinks) to repeatedly get the token -- tldr: not worth the effort anymore.

    What's your yearly carrying cost on $1000? Your best choice is to open an account with a low-minimum, low activity requirement broker and use their API for pulling realtime option chains. TD, Tradier... a few others meet this criteria. TD rate limits you to 120 chain requests per minute, but that should be adequate for your purposes.
     
    #11     Jan 27, 2019
    jtrader33 likes this.
  2. I think Orats has an API where you can specify the moneyness of the data you want to pull. Also TD ameritrade has an REST API where you can specify the # of strikes you want retrieved. So I would think entering "1" would give you the ATM.
     
    #12     Jan 27, 2019
    Adam777 and TheBigShort like this.
  3. tommcginnis

    tommcginnis

    I set up the QuoteMonitor page specifically to be a DB -- it's snapshot only, remember: no historical. Hit File/down-arrow/Export Page to .csv/ and give it a name+location. Then you just import it into your spreadsheet. (Or in your case! feed your API from something that takes about 5 seconds to do.)
     
    #13     Jan 27, 2019
    TheBigShort likes this.
  4. TheBigShort

    TheBigShort

    I apologize for the confusion in my question. I just needed access to a reliable option chain I could scrape to get the ATM strike. If you look at yahoo finance there is missing strikes and expirations for certain stocks. As an example Citigroup:

    Screen Shot 2019-01-27 at 9.12.31 PM.png

    Do you know what the limit is for downloads from this site? It does the job. Here's my code:

    library(rvest)
    library(readr)

    get.chain = function(ticker){
    tryCatch({
    url = sprintf("https://www.theocc.com/webapps/series-search?symbolType=U&symbol=%s", ticker)
    df <- read_html(url) %>%
    html_text() %>%
    read_tsv( skip = 6)
    dfnames <- names(df)[1:10]
    df <- df %>%
    select(-year)
    names(df) <- dfnames
    return(df)}, error = function(e) NULL)
    }

    #tickers = S&P 500 companies
    start = Sys.time()
    x = lapply(tickers, get.chain)
    Sys.time() - start

    This took me only 2.9 minutes. I am very happy with the result. And can easily filter the data to find the ATM strike. Great source Kevin.

    After filtering for the closest to ATM strike it will go into a interactive brokers call where I can get all realtime greeks/implied vol etc..:
    reqMktData(tws, twsOPT("", expiry = "2019-02-15", right = "C", strike = strike, symbol = ticker), eventWrapper = eWrapper.data.bid(1), CALLBACK = snapShot)


    I would estimate $200. But the source you provided above really does the trick, I hope the site will allow me to run this code every hour. Do you see any problems with that?
     
    #14     Jan 28, 2019
  5. No limits AFAIK. Even if there were limits I am unaware of, you could easily get around them as the OCC, unlike some other sites, does not block TOR exit nodes. For small amounts of data like this, routing through a TOR socks5h proxy will not slow you down.

    Run the call asynch, it should only take a few seconds:

    require(parallel)
    require(doparallel)
    ...
    nCores <- 64
    cl <- makeCluster(nCores,outfile="somefilename.x")
    ...
    resa <- foreach(a=tickers,.errorhandling='pass',.packages=c('rvest','readr')) %dopar% {
    get.chain(a)
    }


    I am pretty sure that you could run the code every five minutes if you want to. If they start rate-limiting you, let me know and I'll send you code to get around the restrictions.
     
    #15     Jan 28, 2019
    tommcginnis likes this.
  6. TheBigShort

    TheBigShort

    AMAZING!!! I can finally leave the yahoo days behind me!
    And I will let you know if I get rate limited.
     
    #16     Jan 28, 2019
    tommcginnis likes this.
  7. TheBigShort

    TheBigShort

    I was not able to sign up for either of these (canadian citizen), but just incase you ever wanted access to a retail api, Questrade trade rate limit is 20 calls per second! 1k min deposit. I just got approved today and the api is very nice.
     
    #17     Feb 7, 2019
  8. TheBigShort

    TheBigShort

    Where are you geting this from? I justed recently started saving my code on rstudio cloud https://rstudio.cloud/projects (eligible python/sql/java + 16 cores to run "doParellel/foreach" on), and just bought(built) a new core i7, 8 processors (upgrading from a 86k). I re-read this thread and had a laugh as maybe you were having some fun with me.
     
    #18     Mar 9, 2019
  9. That was an unfortunate choice of variable name. It should probably have been something like:

    nThreads <- 64
    cl <- makeCluster(nThreads,outfile="xxxx.x")

    In the use-case above there is no problem having more threads than cores. Since R parrallel uses sockets in its multi-threading model, you're limited to somewhat less than each R instance's upper bound of 128 simultaneously open sockets. So 64 or 96 is a good choice for the first parameter in makeCluster. For a cpu-intensive application, on the other hand, it makes sense to have the number of parallel threads equal to the number of cores or fewer. My choice of "nCores" as the variable name was just force of habit left over from compute-bound applications.
     
    #19     Mar 9, 2019
    TheBigShort likes this.