# -*- coding: utf-8 -*-
"""
Created on Tue May 30 12:44:54 2017

@author: Iván Ortiz AND Andrés Salamanca
"""

#from flask import Flask, request, render_template, jsonify
#import pandas.io.sql as sql
#import sqlite3
#import platform
#import datetime
#import numpy as np
#import pandas as pd
#import json
#import pygal
#import matplotlib.pyplot as plt
#from scipy.stats import norm
#from bokeh.charts import Histogram
#import plotly
#
##from pandas.io.data import DataReader
#from pandas_datareader import wb, DataReader
#from sklearn.linear_model import LogisticRegression
#from sklearn.lda import LDA
#from sklearn.qda import QDA
#
#from bokeh.layouts import gridplot
#from bokeh.plotting import figure, show, output_file


def create_lagged_series(symbol, start_date, end_date, lags=50,outcome_period=5):
    """This creates a pandas DataFrame that stores the percentage returns of the
    adjusted closing value of a stock obtained from Yahoo Finance, along with
    a number of lagged returns from the prior trading days (lags defaults to 5 days).
    Trading volume, as well as the Direction from the previous day, are also included."""

    # Obtain stock information from Yahoo Finance
#    symbol = "tef.mc"
    from flask import Flask, request, render_template, jsonify
    import pandas.io.sql as sql
    import sqlite3
    import platform
    import datetime
    import numpy as np
    import pandas as pd
    import json
    #import pygal
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    from bokeh.charts import Histogram
    import plotly
    
    #from pandas.io.data import DataReader
    from pandas_datareader import wb, DataReader
    from sklearn.linear_model import LogisticRegression
    from sklearn.lda import LDA
    from sklearn.qda import QDA
    
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure, show, output_file
    ts = DataReader(symbol, "google", start_date-datetime.timedelta(days=2*(lags+outcome_period)), end_date)

    # Create the new lagged DataFrame
    tslag = pd.DataFrame(index=ts.index)
    tslag["Today"] = ts["Close"]
    tslag["Volume"] = ts["Volume"]

    # Create the shifted lag series of prior trading period close values
    for i in xrange(0,lags):
        tslag["Lag%s" % str(i+1)] = ts["Close"].shift(i+1)

    # Create the returns DataFrame
    tsret = pd.DataFrame(index=tslag.index)
    tsret["Volume"] = tslag["Volume"]
    tsret["Today"] = tslag["Today"].pct_change()*100.0

    # If any of the values of percentage returns equal zero, set them to
    # a small number (stops issues with QDA model in scikit-learn)
    for i,x in enumerate(tsret["Today"]):
        if (abs(x) < 0.0001):
            tsret["Today"][i] = 0.0001

    # Create the lagged percentage returns columns
    for i in xrange(0,lags):
        tsret["Lag%s" % str(i+1)] = tslag["Lag%s" % str(i+1)].pct_change()*100.0

    # Create the "Direction" column (+1 or -1) indicating an up/down day
#    tsret["Direction"] = np.sign(tstsret["Today"]))

    tsret["Direction"] = np.sign(ts["Close"] - ts["Close"].shift(outcome_period))

    tsret = tsret[tsret.index >= start_date]
    return tsret

###################################
###################################

def fit_model(name, model, X_train, y_train, X_test, X_last, pred, pred_last):
    
    """Fits a classification model (for our purposes this is LR, LDA and QDA)
    using the training data, then makes a prediction and subsequent "hit rate"
    for the test data."""

    from flask import Flask, request, render_template, jsonify
    import pandas.io.sql as sql
    import sqlite3
    import platform
    import datetime
    import numpy as np
    import pandas as pd
    import json
    #import pygal
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    from bokeh.charts import Histogram
    import plotly
    
    #from pandas.io.data import DataReader
    from pandas_datareader import wb, DataReader
    from sklearn.linear_model import LogisticRegression
    from sklearn.lda import LDA
    from sklearn.qda import QDA
    
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure, show, output_file
    # Fit and predict the model on the training, and then test, data
    model.fit(X_train, y_train)
    pred[name] = model.predict(X_test)
    pred_last[name] = model.predict(X_last)

    # Create a series with 1 being correct direction, 0 being wrong
    # and then calculate the hit rate based on the actual direction
    pred["%s_Correct" % name] = (1.0+pred[name]*pred["Actual"])/2.0
    hit_rate = np.mean(pred["%s_Correct" % name])
    print "%s: %.3f" % (name, hit_rate)
    return hit_rate

###################################
###################################

def prediction(period,ticker):
    from flask import Flask, request, render_template, jsonify
    import pandas.io.sql as sql
    import sqlite3
    import platform
    import datetime
    import numpy as np
    import pandas as pd
    import json
    #import pygal
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    from bokeh.charts import Histogram
    import plotly
    
    #from pandas.io.data import DataReader
    from pandas_datareader import wb, DataReader
    from sklearn.linear_model import LogisticRegression
    from sklearn.lda import LDA
    from sklearn.qda import QDA
    
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure, show, output_file
    from ciff_2017_af3_asio import create_lagged_series
#    global models
    
    results =  {"TICKER":'ticker no found',"predictedprice5daysfromnow":'',"myactionrecommendaction":''}


    try:
#    ticker = "pop.mc"
#    ticker = "tef.mc"
        results =  {"TICKER":ticker,"PREDICTION_FINAL_TXT": "Error: no he podido predecir que va a pasar con la accion "+ticker}

        historical_period_in_days = 365*2
        start_date = datetime.datetime.today()-datetime.timedelta(days=historical_period_in_days)
        end_date = datetime.datetime.today()
        start_test = datetime.datetime.today()-datetime.timedelta(days=int(historical_period_in_days/2))
        n_lags=50
        n_outcome_period=int(period)
        snpret = create_lagged_series(ticker, start_date, end_date, lags=n_lags, outcome_period=n_outcome_period)


        # Drop 4 previous days, to use the prior days (from 5...to the past) of returns as predictor values, with direction as the response
        X = snpret.drop(['Volume','Today','Lag1','Lag2','Lag3','Lag4'], axis=1)
        y = snpret["Direction"]

        #
        X_last = snpret.tail(1)
#        print X_last
        for i in range(n_lags,n_outcome_period,-1):
            X_last["Lag%s" % str(i)] = X_last["Lag%s" % str(i-n_outcome_period)]
#        print X_last
        X_last = X_last.drop(['Volume','Today','Lag1','Lag2','Lag3','Lag4'], axis=1)

        # The test data is split into two parts: Before and after 1st Jan 2005.

        # Create training and test sets
        X_train = X[X.index < start_test]
        X_test = X[X.index >= start_test]
        y_train = y[y.index < start_test]
        y_test = y[y.index >= start_test]

        # Create prediction DataFrame
        pred = pd.DataFrame(index=y_test.index)
        pred["Actual"] = y_test

        pred_last = pd.DataFrame(index=X_last.index)

        # Create and fit the three models
#        print "Hit Rates:"
        models = [("LR - Logistic Regression", LogisticRegression()), ("LDA - Linear Discriminant Analysis", LDA()), ("QDA - Quadratic Discriminant Analysis", QDA())]

        results["PREDICTION_FINAL_NUM"]  = 0
        for m in models:
            try:
                print "1.0"
                results["MODEL_"+m[0]]=fit_model(m[0], m[1], X_train, y_train, X_test, X_last, pred, pred_last)
                if results["MODEL_"+m[0]] != -1.0:
                    print "1.1"
                    results["PREDICTION_MODEL_"+m[0]] = pred_last[m[0]][0]
                    print "1.2"
                    results["PREDICTION_FINAL_NUM"] += pred_last[m[0]][0]
                    print "1.3"
                else:
                    results["PREDICTION_MODEL_"+m[0]] = 0
            except:
                results["PREDICTION_MODEL_"+m[0]] = 0

        print "2.0"
        if results["PREDICTION_FINAL_NUM"] > 0:
            results["PREDICTION_FINAL_TXT"] = "La accion "+str(ticker)+ " va subir en los proximo "+ str(n_outcome_period) +" dias"
        else:
            results["PREDICTION_FINAL_TXT"] = "La accion "+str(ticker)+ " va bajar en los proximo "+ str(n_outcome_period) +" dias"
        print "3.0"

    except:
        print "ERROR!"
    #return jsonify(results)
    return json.dumps(results)

###################################
###################################

def grafica(shortticker):
    from flask import Flask, request, render_template, jsonify
    import pandas.io.sql as sql
    import sqlite3
    import platform
    import datetime
    import numpy as np
    import pandas as pd
    import json
    #import pygal
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    from bokeh.charts import Histogram
    import plotly
    
    #from pandas.io.data import DataReader
    from pandas_datareader import wb, DataReader
    from sklearn.linear_model import LogisticRegression
    from sklearn.lda import LDA
    from sklearn.qda import QDA
    
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure, show, output_file
    def datetime(x):
        return np.array(x, dtype=np.datetime64)

    symbol = shortticker#"GOOG"
    df = DataReader(symbol, "google", '01/01/2016', '08/03/2017')
    df['date'] = df.index


    p1 = figure(x_axis_type="datetime", title="Stock Closing Prices")
    p1.grid.grid_line_alpha=0.3
    p1.xaxis.axis_label = 'Date'
    p1.yaxis.axis_label = 'Price'

    p1.line(datetime(df['date']), df['Close'], color='#A6CEE3', legend=symbol)
    #p1.line(datetime(GOOG['date']), GOOG['adj_close'], color='#B2DF8A', legend='GOOG')
    #p1.line(datetime(IBM['date']), IBM['adj_close'], color='#33A02C', legend='IBM')
    #p1.line(datetime(MSFT['date']), MSFT['adj_close'], color='#FB9A99', legend='MSFT')
    #p1.legend.location = "top_left"

    df_array = np.array(df['Close'])
    df_dates = np.array(df['date'], dtype=np.datetime64)

    window_size = 30
    window = np.ones(window_size)/float(window_size)
    aapl_avg = np.convolve(df_array, window, 'same')

    p2 = figure(x_axis_type="datetime", title="One-Month Average")
    p2.grid.grid_line_alpha = 0
    p2.xaxis.axis_label = 'Date'
    p2.yaxis.axis_label = 'Price'
    p2.ygrid.band_fill_color = "olive"
    p2.ygrid.band_fill_alpha = 0.1

    p2.circle(df_dates, df_array, size=4, legend='close',
              color='darkgrey', alpha=0.2)

    p2.line(df_dates, aapl_avg, legend='avg', color='navy')
    p2.legend.location = "top_left"

    output_file("./templates/stocks.html", title="My Own Bokeh Example")
    show(gridplot([[p1,p2]], plot_width=400, plot_height=400))  # open a browser
    return render_template('stocks.html')

###################################
###################################

def oportunidaddesubida(ndiasmaximo,shortticker):
    from flask import Flask, request, render_template, jsonify
    import pandas.io.sql as sql
    import sqlite3
    import platform
    import datetime
    import numpy as np
    import pandas as pd
    import json
    #import pygal
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    from bokeh.charts import Histogram
    import plotly
    
    #from pandas.io.data import DataReader
    from pandas_datareader import wb, DataReader
    from sklearn.linear_model import LogisticRegression
    from sklearn.lda import LDA
    from sklearn.qda import QDA
    
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure, show, output_file
    symbol = shortticker
    historical_period_in_days = 365#*2
    start_date = datetime.datetime.today() - datetime.timedelta(days=historical_period_in_days)
    end_date = datetime.datetime.today()
    #start_date = datetime.datetime(2015,01,01)
    #end_date = datetime.datetime(2016,01,01)
    lags = int(ndiasmaximo)
    outcome_period = 5
    #def create_lagged_series(symbol, start_date, end_date, lags=50, outcome_period=5):
    """This creates a pandas DataFrame that stores the percentage returns of the
    adjusted closing value of a stock obtained from Yahoo Finance, along with
    a number of lagged returns from the prior trading days (lags defaults to 5 days).
    Trading volume, as well as the Direction from the previous day, are also included."""

    # Obtain stock information from Yahoo Finance
    ts = DataReader(symbol, "google", start_date-datetime.timedelta(days=2*(lags+outcome_period)), end_date)
    #ts = web.DataReader(symbol, 'google', start_date, end_date)

    ## Create the new lagged DataFrame
    tslag = pd.DataFrame(index=ts.index)
    tslag = ts[['Low', 'High']]

    tslag=tslag.sort_index(axis=0, ascending=False)
    for i in xrange(0,lags):
        tslag["lag%s" % str(i+1)] = (tslag["High"] - tslag["Low"].shift(-(i+1)))/tslag["Low"].shift(-(i+1))
    tslag = tslag[(tslag.index >= start_date) & (tslag.index<=end_date)]
    result = {}
    for item in (tslag.index):
        result[str(item).split('T')[0]]=list(tslag.ix[item,2:].values)
    result2 = {}
    valores = []
    for item in result.keys():
        for j in range(lags):
            valores.append(result[item][j])
    result2['diferencias'] = valores

    ## nuevo
    rango = {}
    interval = [-0.1, -0.07, -0.05, -0.02, 0.0, 0.02, 0.05, 0.07, 0.1]
    for i in range(len(interval)+1):
        rango[str(i+1)] = []
    for i in range(len(valores)):
        if valores[i]<= -0.10:
            rango['1'].append(valores[i])
        if (valores[i] > -0.10) & (valores[i] <= -0.07):
            rango['2'].append(valores[i])
        if (valores[i] > -0.07) & (valores[i] <= -0.05):
            rango['3'].append(valores[i])
        if (valores[i] > -0.05) & (valores[i] <= -0.02):
            rango['4'].append(valores[i])
        if (valores[i] > -0.02) & (valores[i] <= 0.00):
            rango['5'].append(valores[i])
        if (valores[i] > 0.00) & (valores[i] <= 0.02):
            rango['6'].append(valores[i])
        if (valores[i] > 0.02) & (valores[i] <= 0.05):
            rango['7'].append(valores[i])
        if (valores[i] > 0.05) & (valores[i] <= 0.07):
            rango['8'].append(valores[i])
        if (valores[i] > 0.07) & (valores[i] <= 0.10):
            rango['9'].append(valores[i])
        if (valores[i] > 0.10):
            rango['10'].append(valores[i])

    rangos = []
    percen = {}
    percen['rango'] = 'x < -10%'
    try:
        percen['percentual'] = (round((float(len(rango['1']))/len(valores)),4))
    except:
        percen['percentual'] = (0.0)
    rangos.append(percen)

    for i in range(1,len(interval),1):
        percen = {}
        percen['rango'] = str(interval[i-1]*10)+'% ' + '<= x < ' + str(interval[i]*10)+ '%'
        percen['percentual'] = (round((float(len(rango['%s' %(i+1)]))/len(valores)),4))
        rangos.append(percen)

    percen = {}
    percen['rango'] = 'x > 10%'
    try:
        percen['percentual'] = (round((float(len(rango['10']))/len(valores)),4))
    except:
        percen['percentual'] = (0.0)
    rangos.append(percen)
    per = {}
    per['rangos'] = rangos
    return json.dumps(per)

###################################
###################################

def var(p,c,ticker):
    from flask import Flask, request, render_template, jsonify
    import pandas.io.sql as sql
    import sqlite3
    import platform
    import datetime
    import numpy as np
    import pandas as pd
    import json
    #import pygal
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    from bokeh.charts import Histogram
    import plotly
    
    #from pandas.io.data import DataReader
    from pandas_datareader import wb, DataReader
    from sklearn.linear_model import LogisticRegression
    from sklearn.lda import LDA
    from sklearn.qda import QDA
    
    from bokeh.layouts import gridplot
    from bokeh.plotting import figure, show, output_file
    symbol = ticker
    def var_cov_var(P, c, mu, sigma):
        """
        Variance-Covariance calculation of daily Value-at-Risk
        using confidence level c, with mean of returns mu
        and standard deviation of returns sigma, on a portfolio
        of value P.
        """
        alpha = norm.ppf(1-c, mu, sigma)
        return P - P*(alpha + 1)

    #if __name__ == "__main__":
    historical_period_in_days = 365*7
    start = datetime.datetime.today() - datetime.timedelta(days=historical_period_in_days)
    end = datetime.datetime.today()

    citi = DataReader(symbol, "google", start, end)
    citi["rets"] = citi["Close"].pct_change()

    P = float(p)   # 1,000,000 USD
    c = float(c)  # 99% confidence interval
    mu = np.mean(citi["rets"])
    sigma = np.std(citi["rets"])

    varianza = var_cov_var(P, c, mu, sigma)
    #print "Value-at-Risk: $%0.2f" % varianza
    var1= {}
    var1['Value-at-Risk'] = "$%0.2f" % varianza
    return json.dumps(var1)
