# Obtaining risk-neutral probability from option prices

Suppose I have the following data (for the current stock and option prices of the Bank of America)

Strike Last        IV Probability
4       8 5.43 0.5813566   0.0000000
7      11 2.45 0.2868052   0.1571556
8      12 1.68 0.3611712   0.0000000
9      13 0.93 0.3149634   0.0000000
10     14 0.42 0.2906097   0.4216563
11     15 0.16 0.2827868   0.0000000
12     16 0.06 0.2894076   0.0000000
13     17 0.03 0.3147238  12.5000000
14     18 0.02 0.3498626   0.0000000
15     19 0.02 0.4019490   0.0000000
16     20 0.01 0.4093461 100.0000000
17     21 0.01 0.4513419   0.0000000
18     22 0.02 0.5374740   0.0000000
19     23 0.01 0.5280132         Inf
20     24 0.02 0.6147154   0.0000000
21     25 0.01 0.5967137   0.0000000

What I want to do is to obtain risk-neutral probability distribution of stock returns from it. I read this question. It is stated that for this purpose I need to take second derivative of option price such as $\frac{\partial^2 c}{\partial K^2}$. Am I right that I cannot do that analytically from the option formula (I use BSM)? So what is practical solution for this (could you please explain in details and preferably with example using my data)?
In the Hull's book it is stated that one can use the following expression to evaluate probability density $g(K)$

$$g(K) = e^{rT}\frac{c_1+c_3-2c_2}{\delta^2}$$ where $K$ is a strike, $c_1$, $c_2$ and $c_3$ are prices of European call options with maturity $T$ and strikes $K-\delta$, $K$ and $K+\delta$ respectively. Is it the way I should use in practice to evaluate $g(K)$? I have tried it with my data but I get unrealistic results (e.g. negative probabilities).

Update: according to the @Quantuple answer I calculated probability, $Probability_i$, that the stock price will lie between $Strike_{i-1}$ and $Strike_{i+1}$ (am I interpret it right?). The values that I got seem to be unrealistic (e.g. negative probability). In this case I tried to do the same with another data (Apple current stock and option prices) and I got the following

Strike  Last        IV Probability
8    85.0 21.41 0.2814728  0.00000000
10   90.0 16.65 0.2712171  0.04287807
11   92.5 14.15 0.2350727  0.00000000
12   95.0 12.10 0.2530275  0.00000000
13   97.5 10.05 0.2506622  0.01535698
14  100.0  8.23 0.2525582  0.00000000
15  105.0  5.01 0.2436027  0.00000000
16  110.0  2.71 0.2368809  0.07017230
17  115.0  1.35 0.2363258  0.00000000
18  120.0  0.61 0.2362289  0.00000000
19  125.0  0.29 0.2435342  0.85066163
20  130.0  0.15 0.2548730  0.00000000
21  135.0  0.08 0.2660732  0.00000000
22  140.0  0.05 0.2814728  4.00000000
23  145.0  0.03 0.2935170  0.00000000

I use the following R code

chain <- getOptionChain("BAC", Exp = "2016-05-20")
chain <- chain$calls chain <- chain[, 1:2] chain$IV <- 0
time_remain <- as.numeric(as.Date("2016-05-20") - as.Date(Sys.time()))
time <- time_remain/360
rf <- 0.01
Spot <- getQuote("BAC")
Spot <- Spot$Last chain <- as.data.frame(apply(chain, 2, as.numeric)) for (i in 1:nrow(chain)) { chain$IV[i] <- iv.opt(S = Spot, K = chain$Strike[i], T = time, riskfree = rf, price = chain$Last[i], type = "Call")
}
chain <- na.omit(chain)
ggplot(chain, aes(x = Strike, y = IV)) + geom_line(size = 1, color = "red") + ylab("Implied volatility") + theme(axis.text = element_text(size = 18), panel.border = element_rect(fill = NA, colour = "black", size = 2), axis.title = element_text(size = 20))