
import pandas as pd
import numpy as np
import pandas.io.data as web
import datetime
import math
import sys

from pandas.io.data import Options

from app.model.NewtonRaphson import NewtonRaphson


class ImpliedVolatilityProcessor:


    @staticmethod
    def calculate(ticker):
        #ticker = 'SPY'
        today = datetime.date.today()
        
        try:
            optionReader = Options(ticker, 'yahoo')
            option = optionReader.get_all_data()
        except:
            print 'ERROR..'
            return None

        optionResult = None
        nr = NewtonRaphson()

        for expiryDate in optionReader.expiry_dates:
            diff = expiryDate - today
            expiryDays = diff.days

            callOptions = optionReader.get_call_data(expiry=expiryDate)
            ImpliedVolatilityProcessor.calculateImpliedVolatility(callOptions, expiryDays, nr)
        
            putOptions = optionReader.get_put_data(expiry=expiryDate)
            ImpliedVolatilityProcessor.calculateImpliedVolatility(putOptions, expiryDays, nr)
            
            
            optionResult = pd.concat([optionResult, callOptions, putOptions])
        
        # Save result
        fileName = today.strftime('%Y%m%d-') + ticker + '_IV.txt'
        optionResult.to_csv(fileName, sep=',', encoding='utf-8')
            
            
    @staticmethod
    def calculateImpliedVolatility(options, expiryDays, nr):
        dividendYield = 0
        riskfreeRate = 0.005
        expiryYears = expiryDays / 365.
        
        volBid = []
        volAsk = []
        volMid = []
        for row_index, row in options.iterrows():
            Strike, Expiry, Type, Symbol = row_index
            
            volatilityBid = nr.calculateVolatility(row['Bid'], Type, 
                                            row['Underlying_Price'], Strike, expiryYears, dividendYield, riskfreeRate)
            volBid.append(volatilityBid)
            
            volatilityAsk = nr.calculateVolatility(row.Ask, Type, 
                                            row.Underlying_Price, Strike, expiryYears, dividendYield, riskfreeRate)
            volAsk.append(volatilityAsk)
            
            volatilityMiddle = nr.calculateVolatility((row.Bid + row.Ask)/2., Type, 
                                            row.Underlying_Price, Strike, expiryYears, dividendYield, riskfreeRate)
            volMid.append(volatilityMiddle)
        
        options['Expiry Days'] = expiryDays
        options['Bid Implied Volatility'] = volBid
        options['Ask Implied Volatility'] = volAsk
        options['Middle Implied Volatility'] = volMid

