示例#1
0
def main(function, start, end, tickers, file, provider, verbose):
    """Simple tool (based on https://github.com/pmorissette/ffn) for intermarket analysis.

    <function>: Available analysis methods:
    
    'average': display average combined returns

    'heat': display correlations heatmap

    'scatter': display scatter matrix

    """
    context = Context(start, end, tickers, file, provider, verbose)
    df_list = context.data_frames

    if len(df_list) < 1:
        click.echo("No dataframes. Exiting.")
        return

    closes = []
    for df in df_list:
        closes.append(df['Close'].rename(df['Ticker'][0]))

    if function == 'heat':
        g = ffn.GroupStats(*closes)
        g.plot_correlation()
        plt.show()

    elif function == 'scatter':
        g = ffn.GroupStats(*closes)
        axes = g.plot_scatter_matrix()
        plt.show()

    elif function == 'average':
        col = "Close"
        tickers = "Average: " + ", ".join([df['Ticker'][0] for df in df_list])
        rebased_merged = ffn.core.merge(*[ffn.core.rebase(c) for c in closes])

        average = pd.DataFrame(columns=[col])
        for index, row in rebased_merged.iterrows():
            average.set_value(index, col, row.values.mean())

        average = ta.add_ma(average, 200)

        average.plot()
        plt.title(tickers)
        plt.show()

    else:
        click.echo("{:s} not recognized".format(function))

    if context.data_provider.errors > 0:
        logger.warning("Missing data for {0} tickers.".format(provider.errors))
示例#2
0
def test_set_riskfree_rate():
    r = df.to_returns()

    performanceStats = ffn.PerformanceStats(df['MSFT'])
    groupStats = ffn.GroupStats(df)
    daily_returns = df['MSFT'].resample('D').last().dropna().pct_change()

    aae(
        performanceStats.daily_sharpe,
        daily_returns.dropna().mean() / (daily_returns.dropna().std()) *
        (np.sqrt(252)), 3)

    aae(performanceStats.daily_sharpe, groupStats['MSFT'].daily_sharpe, 3)

    monthly_returns = df['MSFT'].resample('M').last().pct_change()
    aae(
        performanceStats.monthly_sharpe,
        monthly_returns.dropna().mean() / (monthly_returns.dropna().std()) *
        (np.sqrt(12)), 3)
    aae(performanceStats.monthly_sharpe, groupStats['MSFT'].monthly_sharpe, 3)

    yearly_returns = df['MSFT'].resample('A').last().pct_change()
    aae(
        performanceStats.yearly_sharpe,
        yearly_returns.dropna().mean() / (yearly_returns.dropna().std()) *
        (np.sqrt(1)), 3)
    aae(performanceStats.yearly_sharpe, groupStats['MSFT'].yearly_sharpe, 3)

    performanceStats.set_riskfree_rate(0.02)
    groupStats.set_riskfree_rate(0.02)

    daily_returns = df['MSFT'].pct_change()
    aae(
        performanceStats.daily_sharpe,
        np.mean(daily_returns.dropna() - 0.02 / 252) /
        (daily_returns.dropna().std()) * (np.sqrt(252)), 3)
    aae(performanceStats.daily_sharpe, groupStats['MSFT'].daily_sharpe, 3)

    monthly_returns = df['MSFT'].resample('M').last().pct_change()
    aae(
        performanceStats.monthly_sharpe,
        np.mean(monthly_returns.dropna() - 0.02 / 12) /
        (monthly_returns.dropna().std()) * (np.sqrt(12)), 3)
    aae(performanceStats.monthly_sharpe, groupStats['MSFT'].monthly_sharpe, 3)

    yearly_returns = df['MSFT'].resample('A').last().pct_change()
    aae(
        performanceStats.yearly_sharpe,
        np.mean(yearly_returns.dropna() - 0.02 / 1) /
        (yearly_returns.dropna().std()) * (np.sqrt(1)), 3)
    aae(performanceStats.yearly_sharpe, groupStats['MSFT'].yearly_sharpe, 3)

    rf = np.zeros(df.shape[0])
    #annual rf is 2%
    rf[1:] = 0.02 / 252
    rf[0] = 0.
    #convert to price series
    rf = 100 * np.cumprod(1 + pd.Series(data=rf, index=df.index, name='rf'))

    performanceStats.set_riskfree_rate(rf)
    groupStats.set_riskfree_rate(rf)

    daily_returns = df['MSFT'].pct_change()
    rf_daily_returns = rf.pct_change()
    aae(
        performanceStats.daily_sharpe,
        np.mean(daily_returns - rf_daily_returns) /
        (daily_returns.dropna().std()) * (np.sqrt(252)), 3)
    aae(performanceStats.daily_sharpe, groupStats['MSFT'].daily_sharpe, 3)

    monthly_returns = df['MSFT'].resample('M').last().pct_change()
    rf_monthly_returns = rf.resample('M').last().pct_change()
    aae(
        performanceStats.monthly_sharpe,
        np.mean(monthly_returns - rf_monthly_returns) /
        (monthly_returns.dropna().std()) * (np.sqrt(12)), 3)
    aae(performanceStats.monthly_sharpe, groupStats['MSFT'].monthly_sharpe, 3)

    yearly_returns = df['MSFT'].resample('A').last().pct_change()
    rf_yearly_returns = rf.resample('A').last().pct_change()
    aae(
        performanceStats.yearly_sharpe,
        np.mean(yearly_returns - rf_yearly_returns) /
        (yearly_returns.dropna().std()) * (np.sqrt(1)), 3)
    aae(performanceStats.yearly_sharpe, groupStats['MSFT'].yearly_sharpe, 3)
示例#3
0
def app():
    selection = ["Stock Market Analysis", "Portfolio Assessment"]  # Selections
    choice = st.sidebar.selectbox("Dashboard Selection", selection)
    if choice == 'Stock Market Analysis':

        # Building both our selectbox and URL from the JSE's website
        st.title('Jamaica Stock Exchange Quantitative DashBoard 📈')
        st.write(
            '**Contact the author: Samuel Lawrence - ** http://www.samuel-lawrence.co.uk'
        )
        st.write(
            "More About the Jamaica Stock Exchange: https://www.jamstockex.com/ "
        )
        Index = 'https://www.jamstockex.com/market-data/download-data/price-history/'
        df_index = pd.read_html(Index)
        df_index = df_index[0]
        Stock_Select = df_index['Instrument']

        # Creating Select Box
        Stock_Selection = st.multiselect('Select multiple stocks',
                                         Stock_Select)
        try:
            # Date selection for Analysis
            date = st.date_input(
                "Analysis Dates",
                (datetime.date(2019, 1, 3), datetime.date(2020, 1, 10)))

            # We need these datse to pass into our URl
            since_date = str(date[0])
            until_date = str(date[1])

            # We need dates in datetime format for our calculations
            # until_date_calender  = date[1]
            # since_date_calender = date[0]

        except (IndexError, NameError, UnboundLocalError):
            pass

        for x in range(
                0, 10
        ):  # Multiple attempts because the JSE website gives us HTTP errors randomly
            try:
                try:
                    # Extracting Data from the JSE based on stock chosen
                    JSE_URL = 'https://www.jamstockex.com/market-data/download-data/price-history/{}/' + since_date + '/' + until_date

                    stock_dfs = []
                    for stock in Stock_Selection:
                        dfs = pd.read_html(JSE_URL.format(stock))
                        if not dfs:
                            st.write(f'No tables found for {stock}')
                            continue
                        stock_dfs.append(dfs[0])

                    full_df = pd.concat(stock_dfs)
                    display_columns = [
                        "Date",
                        "Instrument",
                        # "Volume  (non block) ($)",
                        "Close  Price ($)"
                    ]

                    # Creating Dataframe for stocks
                    sub_df = full_df[display_columns]
                    sub_pivot = sub_df.pivot(index='Date',
                                             columns='Instrument')
                    # st.write(sub_pivot)

                    data = pd.DataFrame(sub_pivot.to_records(
                    ))  # Turning our pivot table back into a dataframe

                    # Cleaning Data for readability
                    data.columns = [
                        hdr.replace("('Close  Price ($)',", "").replace(")", "").replace("'", "").replace("'",
                                                                                                          "").replace(
                            " ", "") \
                        for hdr in data.columns]  # Turning columns back into ticker names

                    # Readable format for FFN
                    data['Date'] = pd.to_datetime(data.Date,
                                                  infer_datetime_format=True)
                    data = data.set_index('Date')

                    # Prepping for analysis
                    GS = ffn.GroupStats(data)
                    GS.set_riskfree_rate(.03)
                    perf = data.calc_stats()
                    returns = data.to_log_returns().dropna()

                    st.subheader(" Prices History: ")
                    st.write(data.tail())

                    st.subheader("Graph of stocks: ")
                    st.line_chart(data)

                    # Breaking up calculations for easier analysis
                    Analyzer_choice = st.selectbox("Analysis Type", [
                        "Ratios", "Returns", "Look Back Returns",
                        "Portfolio Weights", "Change Analysis",
                        "Machine Learning - Clustering", "Correlation",
                        "Stocks Summary"
                    ])

                    # Analysis Choices start here
                    if Analyzer_choice == "Correlation":
                        st.subheader("Correlation of returns:")
                        st.write(
                            "**More about this analysis:** https://en.wikipedia.org/wiki/Heat_map "
                        )
                        st.pyplot(ffn.plot_corr_heatmap(returns))

                    if Analyzer_choice == "Stocks Summary":
                        st.subheader('Stocks Summary:')
                        General_stats = perf.stats
                        st.write(General_stats)

                    if Analyzer_choice == "Ratios":
                        st.subheader('Calmar Ratio')
                        st.write(
                            "**More about this ratio:** https://www.investopedia.com/terms/c/calmarratio.asp"
                        )
                        st.write(ffn.calc_calmar_ratio(data))

                        st.subheader("Risk / Return Ratio ")
                        st.write(ffn.calc_risk_return_ratio(data))
                        st.write(
                            "**More about this ratio:** https://www.investopedia.com/terms/r/riskrewardratio.asp"
                            "#:~:text=The%20risk%2Freward%20ratio%20marks,"
                            "undertake%20to%20earn%20these%20returns.")

                        st.subheader("Sortino ratio")  # Experimental
                        # Number of periods
                        # num_years = (until_date_calender.year - since_date_calender.year)

                        st.write(
                            ffn.calc_sortino_ratio(returns,
                                                   rf=0.0,
                                                   annualize=True))
                        st.write(
                            "**More about this ratio:** https://www.investopedia.com/terms/s/sortinoratio.asp "
                        )

                        st.subheader("Sharpe Ratio")  # Experimental
                        st.write(ffn.calc_sharpe(data, rf=0.0, annualize=True))
                        st.write(
                            "**More about this ratio:** https://www.investopedia.com/terms/s/sharperatio.asp "
                        )

                        st.subheader('Max Drawdown')
                        st.write(
                            "**More about this ratio:** https://www.investopedia.com/terms/m/maximum-drawdown-mdd"
                            ".asp#:~:text=A%20maximum%20drawdown%20(MDD)%20is,"
                            "over%20a%20specified%20time%20period. ")
                        st.write(ffn.calc_max_drawdown(data))

                    if Analyzer_choice == "Portfolio Weights":
                        st.subheader("ERC Risk Parity Portfolio Weights")
                        st.write(
                            ffn.calc_erc_weights(
                                returns=returns).as_format('.2%'))
                        st.write(
                            '**About this ratio:** A calculation of the equal risk contribution / risk parity '
                            'weights given the portfolio returns.')

                        st.subheader("Inverse Volatility Weights")
                        st.write(
                            ffn.calc_inv_vol_weights(returns).as_format('.2%'))
                        st.write(
                            "**About this ratio:** A calculation of weights proportional to the inverse volatility of "
                            "each stock ")

                        st.subheader("Mean Variance Weights")
                        st.write(
                            returns.calc_mean_var_weights().as_format('.2%'))
                        st.write(
                            "**About this ratio:** optimal portolio based on classic Markowitz Mean/Variance "
                            "Optimisation methods")
                        st.write(
                            "**More information at:** https://www.investopedia.com/terms/m/meanvariance-analysis"
                            ".asp")

                    if Analyzer_choice == "Returns":
                        st.subheader('Total returns over the period')
                        st.write(ffn.calc_total_return(data).as_format('.2%'))

                        st.subheader('CAGR - compound annual growth rate.')
                        st.write(
                            "**More about this ratio:** https://www.investopedia.com/terms/c/cagr.asp"
                        )
                        st.write(ffn.calc_cagr(data).as_format('.2%'))

                        st.subheader("Distribution of returns")
                        st.pyplot(ax=returns.hist(figsize=(20, 10), bins=30),
                                  clear_figure=True)

                    if Analyzer_choice == "Look Back Returns":
                        st.subheader('Look Back Returns over the period:')
                        st.write(GS.display_lookback_returns())

                    if Analyzer_choice == "Machine Learning - Clustering":  ##
                        st.subheader("Threshold Clustering Algorithm (FTCA)")
                        st.write(
                            "Grouping Stocks based on similar characteristics")
                        thresh = returns.calc_ftca(threshold=0.1)
                        thresh_df = pd.DataFrame.from_dict(thresh,
                                                           orient='index')

                        st.write(thresh_df)
                        st.write(
                            "**More info about this :** http://cssanalytics.wordpress.com/2013/11/26/fast-threshold"
                            "-clustering-algorithm-ftca/")

                    # if Analyzer_choice == "Change Analysis":
                    # Counting the amout of changes in dataframe
                    #     def Change(Data):
                    #         if x > -0.5 and x <= 0.5:
                    #             return 'Slight or No change'
                    #         elif x > 0.5 and x <= 1:
                    #             return 'Slight Positive'
                    #         elif x > -1 and x <= -0.5:
                    #             return 'Slight Negative'
                    #         elif x > 1 and x <= 3:
                    #             return 'Positive'
                    #         elif x > -3 and x <= -1:
                    #             return 'Negative'
                    #         elif x > 3 and x <= 7:
                    #             return 'Among top gainers'
                    #         elif x > -7 and x <= -3:
                    #             return 'Among top losers'
                    #         elif x > 7:
                    #             return 'Bull run'
                    #         elif x <= -7:
                    #             return
                    #
                    #     test = data
                    #     for stock in test.columns:
                    # #         test[stock] = test[stock].apply(Change)
                    #
                    #     for Categorical_Values in test.columns:
                    #         cat_num = test[Categorical_Values].value_counts().plot(kind='pie', figsize=(10, 5))
                    #         st.write(cat_num)

                    #st.write(test)

                    # if Analyzer_choice == "Volume Analysis":
                    #    st.subheader("Coming Soon")
                    # https://www.investopedia.com/terms/v/volume-analysis.asp#:~:text=What%20is%20Volume%20Analysis,
                    # in%20a%20given%20time%20period.&text=By%20analyzing%20trends%20in%20volume,
                    # changes%20in%20a%20security's%20price.

                except HTTPError:
                    sleep(1)
                else:

                    break
                # st.error('Try again later')

            except (ValueError, UnboundLocalError):
                pass
    st.write(
        "Github repo: https://github.com/SamuelLawrence876/JSE-Quant-Webapp")

    if choice == 'Portfolio Assessment':
        st.title('Under Construction!')
示例#4
0
plt.show()

ax = data.rebase().plot(figsize=(12,5))
plt.show()

perf = data.calc_stats()
perf.plot()
plt.show()
print (perf.display())

# we can also use perf[2] in this case
perf[2].stats

returns.calc_mean_var_weights().as_format('.2%')

groupstats = ffn.GroupStats(data)
groupstats.display()
groupstats.display_lookback_returns()
groupstats.plot()
plt.show()

#%%
import ffn
eurusd = myPjMT5.getsymboldata("EURUSD","TIMEFRAME_D1",[2010,1,1,0,0,0],[2020,1,1,0,0,0],index_time=True)
data = eurusd[["open","high","low","close"]]

prices = data["close"]
prices.plot()
plt.show()

r = data["close"].to_returns().dropna()