I have the below function which calls an options chain from yahoo finance, things work well when I am downloading one ticker, however, it does not work when I have more than one ticker, may I know if I am required to add a loop element in the function or I just simply make some errors writing this function? Many thanks.
library(quantmod)
library(pedquant)
option_chain<-function(ticker,exp){
view_window <- function(dfr, var, x, pm){
idx <- which(abs(dfr[, var]-x) == min(abs(dfr[, var] - x)))
return(dfr[(idx - pm) : (idx + pm), ])
}
options<-getOptionChain(ticker,exp)
call_filter<-options$calls[,c("Strike","Last","Vol")]
put_filter<-options$puts[,c("Strike","Last","Vol")]
ticker_price<-md_stock(ticker,type="real")
price<-ticker_price$close
call<-view_window(dfr=call_filter,
var="Strike",
x=price,
pm=7)
put<-view_window(dfr=put_filter,
var="Strike",
x=price,
pm=7)
colnames(call)<-c('Option Strike',"Call Price","Call Volume")
colnames(put)<-c('Option Strike',"Put Price","Put Volume")
print(ticker_price$symbol)
print(ticker_price$time)
print(price)
print(call)
print(put)
}
Test case with one ticker:
> ticker<-"AAPL"
> exp="2023-06-30"
> option_chain(ticker,exp)
[1] "AAPL"
[1] "2023-06-27 10:05:20 CST"
[1] 186.69
Option Strike Call Price Call Volume
22 170.0 17.14 30
23 172.5 14.38 3
24 175.0 12.10 77
25 177.5 9.42 21
26 180.0 7.10 251
27 182.5 4.85 1252
28 185.0 2.74 3729
29 187.5 1.19 14873
30 190.0 0.38 12760
31 192.5 0.08 5576
32 195.0 0.03 2623
33 197.5 0.01 227
34 200.0 0.01 72
35 202.5 0.01 1
36 205.0 0.01 56
Option Strike Put Price Put Volume
23 170.0 0.02 80
24 172.5 0.02 315
25 175.0 0.04 73
26 177.5 0.05 412
27 180.0 0.11 2857
28 182.5 0.27 3408
29 185.0 0.71 6642
30 187.5 1.68 3399
31 190.0 3.30 100
32 192.5 5.60 4
33 195.0 8.05 133
34 197.5 10.64 8
35 200.0 13.34 20
36 202.5 17.10 20
37 205.0 17.80 7
Test case with more than 1 ticker:
> ticker<-c("AAPL","BABA")
> exp="2023-06-30"
> option_chain(ticker,exp)
[1] "AAPL" "BABA"
[1] "2023-06-27 10:06:00 CST" "2023-06-27 10:05:58 CST"
[1] 186.69 86.92
Option Strike Call Price Call Volume
22 170.0 17.14 30
23 172.5 14.38 3
24 175.0 12.10 77
25 177.5 9.55 24
26 180.0 7.10 251
27 182.5 4.85 1252
28 185.0 2.70 3759
29 187.5 1.19 15115
30 190.0 0.36 12894
31 192.5 0.08 5576
32 195.0 0.02 2637
33 197.5 0.01 227
34 200.0 0.01 72
35 202.5 0.01 1
36 205.0 0.01 56
Option Strike Put Price Put Volume
22 167.5 0.03 2
23 170.0 0.02 80
24 172.5 0.02 315
25 175.0 0.04 89
26 177.5 0.05 412
27 180.0 0.11 2857
28 182.5 0.28 3460
29 185.0 0.73 8300
30 187.5 1.72 3613
31 190.0 3.32 106
32 192.5 5.60 4
33 195.0 8.05 133
34 197.5 10.64 8
35 200.0 13.34 20
36 202.5 17.10 20
As shown, the second case fails to display the options chain data for "BABA" (Alibaba).
All ideas are appreciated. Thanks a lot.
I think the problem is that you're using print()
to return lots of results. Only the last printed result gets saved in the object. I would suggest, instead, returning a list that has the relevant pieces. In the code below, I made a list that had the call
and put
frames returned and the symbol, time and price are saved as attributes to the list. I also wrote a print function that would print the relevant information. After that, you can use lapply(ticker, function(x)option_chain(x, exp))
to return data for all required tickers - each one ends up as a different element in the list.
First, here's the modified option_chain()
function:
library(quantmod)
library(pedquant)
option_chain<-function(ticker,exp){
view_window <- function(dfr, var, x, pm){
idx <- which(abs(dfr[, var]-x) == min(abs(dfr[, var] - x)))
return(dfr[(idx - pm) : (idx + pm), ])
}
options<-getOptionChain(ticker,exp)
call_filter<-options$calls[,c("Strike","Last","Vol")]
put_filter<-options$puts[,c("Strike","Last","Vol")]
ticker_price<-md_stock(ticker,type="real")
price<-ticker_price$close
call<-view_window(dfr=call_filter,
var="Strike",
x=price,
pm=7)
put<-view_window(dfr=put_filter,
var="Strike",
x=price,
pm=7)
colnames(call)<-c('Option Strike',"Call Price","Call Volume")
colnames(put)<-c('Option Strike',"Put Price","Put Volume")
res <- list(cl=call, put=put)
attr(res, "symbol") <- ticker_price$symbol
attr(res, "time") <- ticker_price$time
attr(res, "price") <- price
class(res) <- "option_chain"
res
}
Next is the print()
method for the result
print.option_chain <- function(x, ...){
cat("Symbol: ", attr(x, "symbol"), "\n", sep="")
cat("Time: ", attr(x, "time"), "\n", sep="")
cat("Price: ", attr(x, "price"), "\n", sep="")
cat("Call:\n")
print(x$cl)
cat("\nPut\n")
print(x$put)
}
Now, we can run the code and look at the results:
ticker<-c("AAPL","BABA")
exp="2023-06-30"
out <- lapply(ticker, function(x)option_chain(x,exp))
out
#> [[1]]
#> Symbol: AAPL
#> Time: 1687832620
#> Price: 186.72
#> Call:
#> Option Strike Call Price Call Volume
#> 22 170.0 17.02 38
#> 23 172.5 14.69 4
#> 24 175.0 12.15 89
#> 25 177.5 9.65 25
#> 26 180.0 6.80 353
#> 27 182.5 4.51 1771
#> 28 185.0 2.38 5424
#> 29 187.5 0.96 19728
#> 30 190.0 0.25 25574
#> 31 192.5 0.06 6128
#> 32 195.0 0.02 2812
#> 33 197.5 0.02 494
#> 34 200.0 0.01 78
#> 35 202.5 0.01 2
#> 36 205.0 0.01 56
#>
#> Put
#> Option Strike Put Price Put Volume
#> 23 170.0 0.01 119
#> 24 172.5 0.02 1097
#> 25 175.0 0.04 170
#> 26 177.5 0.06 654
#> 27 180.0 0.11 3385
#> 28 182.5 0.28 5215
#> 29 185.0 0.77 12525
#> 30 187.5 1.90 6321
#> 31 190.0 3.70 283
#> 32 192.5 5.55 204
#> 33 195.0 8.50 143
#> 34 197.5 10.64 8
#> 35 200.0 13.34 20
#> 36 202.5 17.10 20
#> 37 205.0 17.80 7
#>
#> [[2]]
#> Symbol: BABA
#> Time: 1687832620
#> Price: 87.14
#> Call:
#> Option Strike Call Price Call Volume
#> 17 80 7.25 5
#> 18 81 6.47 7
#> 19 82 5.35 13
#> 20 83 4.55 3
#> 21 84 3.63 20
#> 22 85 2.55 391
#> 23 86 1.88 339
#> 24 87 1.43 2087
#> 25 88 1.01 3044
#> 26 89 0.63 1383
#> 27 90 0.49 4992
#> 28 91 0.29 297
#> 29 92 0.21 1244
#> 30 93 0.15 617
#> 31 94 0.10 109
#>
#> Put
#> Option Strike Put Price Put Volume
#> 24 80 0.04 284
#> 25 81 0.06 39
#> 26 82 0.09 173
#> 27 83 0.18 338
#> 28 84 0.33 1118
#> 29 85 0.57 959
#> 30 86 0.93 864
#> 31 87 1.37 456
#> 32 88 1.83 57
#> 33 89 2.49 16
#> 34 90 3.21 16
#> 35 91 4.00 3
#> 36 92 4.90 1
#> 37 93 5.80 5
#> 38 94 7.88 59
Created on 2023-06-27 with reprex v2.0.2