Пример #1
0
def main():
    # Get the Google data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    goog_data = goog_data_raw.tail(620)
    # Use close price for this analysis
    close = goog_data['Close']
    # Calculate Bollinger Bands: default time period = 20; standard deviation
    # factor = 2
    bbands_df = bollinger_bands(close)
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    print(bbands_df)

    # Extract data to plot
    close_price = close
    mband = bbands_df['MBBand']
    uband = bbands_df['UBBand']
    lband = bbands_df['LBBand']

    # Plot the data
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    close_price.plot(ax=ax1, color='c', lw=2.0, legend=True)
    mband.plot(ax=ax1, color='b', lw=2.0, legend=True)
    uband.plot(ax=ax1, color='g', lw=2.0, legend=True)
    lband.plot(ax=ax1, color='r', lw=2.0, legend=True)

    plt.grid()
    plt.show()
Пример #2
0
def main():
    # Get the Google data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    goog_data = goog_data_raw.tail(620)
    # Use close price for this analysis
    close = goog_data['Close']
    # Calculate momentum of close price using default time period = 20
    mom_list = momentum(close)
    mom_df = pd.DataFrame(close)
    mom_df = mom_df.assign(mom=pd.Series(mom_list, index=close.index))
    print(mom_df)

    # Extract data to plot
    close_price = close
    mom = mom_df['mom']

    # Plot the data
    fig = plt.figure()
    ax1 = fig.add_subplot(211, ylabel='Google price in $')
    close_price.plot(ax=ax1, color='g', lw=2.0, legend=True)
    ax2 = fig.add_subplot(212, ylabel='Momentum in $')
    mom.plot(ax=ax2, color='b', lw=2.0, legend=True)

    ax1.grid()
    ax2.grid()
    plt.show()
Пример #3
0
def main():
    # Get the Google data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    goog_data = goog_data_raw.tail(620)
    # Use close price for this analysis
    close = goog_data['Close']
    # Calculate Relative Strength Index using default time period = 20
    rsi_df = relative_strength_index(close)
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    print(rsi_df)

    # Extract data to plot
    close_price = close
    rs_gain = rsi_df['RS_avg_gain']
    rs_loss = rsi_df['RS_avg_loss']
    rsi = rsi_df['RSI']

    # Plot the data
    fig = plt.figure()
    ax1 = fig.add_subplot(311, ylabel='Google price in $')
    close_price.plot(ax=ax1, color='k', lw=2.0, legend=True)
    ax2 = fig.add_subplot(312, ylabel='RS')
    rs_gain.plot(ax=ax2, color='g', lw=2.0, legend=True)
    rs_loss.plot(ax=ax2, color='r', lw=2.0, legend=True)
    ax3 = fig.add_subplot(313, ylabel='RSI')
    rsi.plot(ax=ax3, color='b', lw=2.0, legend=True)

    ax1.grid()
    ax2.grid()
    ax3.grid()
    plt.show()
Пример #4
0
def main():
    # Get the Google data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    goog_data = goog_data_raw.tail(620)
    # Use close price for this analysis
    close = goog_data['Close']
    apo_df = absolute_price_oscillator(close, time_period_fast=10,
                                       time_period_slow=40)

    close_price = close
    ema_fast = apo_df['ema_fast']
    ema_slow = apo_df['ema_slow']
    apo = apo_df['apo']

    # Plot the close price, APO and fast and slow EMAs
    fig = plt.figure()
    ax1 = fig.add_subplot(211, ylabel='Google price in $')
    close_price.plot(ax=ax1, color='g', lw=2.0, legend=True)
    ema_fast.plot(ax=ax1, color='b', lw=2.0, legend=True)
    ema_slow.plot(ax=ax1, color='r', lw=2.0, legend=True)
    ax2 = fig.add_subplot(212, ylabel='APO')
    apo.plot(ax=ax2, color='k', lw=2.0, legend=True)
    ax1.grid()
    ax2.grid()
    plt.show()
Пример #5
0
def main():
    # Get the Google data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    # Use close price for this analysis
    close = goog_data_raw['Close']
    # Calculate standard deviation of SMA using default time period 20 days
    signals.avg_sma_std_dev(close, tail=620)
    plt.show()
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    # Get daily trading data for 4 years
    SYMBOL = 'GOOG'
    goog_data = data.get_google_data(f'data/{SYMBOL}_data.pkl',
                                     start_date='2014-01-01',
                                     end_date='2018-01-01')

    # Use close price for this analysis
    close = goog_data.loc[:, 'Close']

    # Constants defining strategy behaviour/thresholds

    # APO trading signal value above which to enter buy orders/long position
    apo_value_for_buy_entry = 10
    # APO trading signal below above which to enter sell orders/short position
    apo_value_for_sell_entry = -10
    # Minimum price change since last trade before considering trading again.
    # This is to prevent over trading at around same prices
    min_price_move_from_last_trade = 10
    # Number of shares to buy/sell on every trade
    num_shares_per_trade = 10
    # Minimum open/unrealised profit at which to close and lock profits
    min_profit_to_close = 10 * num_shares_per_trade

    # Exponential moving average time periods for APO calculation
    ema_time_period_fast = 10
    ema_time_period_slow = 40

    # Calculate trading strategy
    df = signals.basic_trend_following(
        close,
        ema_time_period_fast,
        ema_time_period_slow,
        apo_value_for_buy_entry=apo_value_for_buy_entry,
        apo_value_for_sell_entry=apo_value_for_sell_entry,
        min_price_move_from_last_trade=min_price_move_from_last_trade,
        num_shares_per_trade=num_shares_per_trade,
        min_profit_to_close=min_profit_to_close)

    # Visualise
    plotting.visualise(df, apo_value_for_buy_entry, apo_value_for_sell_entry,
                       num_shares_per_trade)

    # Prepare DataFrame to save results to CSV
    goog_data = pd.concat([goog_data, df], axis=1)
    # Remove redundant close price column
    goog_data = goog_data.drop('ClosePrice', axis=1)
    goog_data.to_csv('ch05/basic_trend_following.csv')

    # Display plots and block
    plt.show()
Пример #7
0
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    goog_data = data.get_google_data('data/goog_data_large.pkl',
                                     start_date='2001-01-01',
                                     end_date='2018-01-01')
    # Features are open - close price and high - low price
    # Target is difference in daily close price
    goog_data, x, y = finml.create_regression_trading_condition(goog_data)

    # Split into train (80%) and test data sets
    x_train, x_test, y_train, y_test = finml.create_train_split_group(x, y)

    # Ridge regression model with regularisation parameter 0.1
    ridge = linear_model.Ridge(alpha=10000)
    ridge.fit(x_train, y_train)
    print('Coefficients:\n', ridge.coef_)

    # Evaluate model on training data
    print(f'Mean squared error on training data: '
          f'{mean_squared_error(y_train, ridge.predict(x_train))}')
    # Explained variance score: 1 is perfect prediction
    print(f'Variance score on training data: '
          f'{r2_score(y_train, ridge.predict(x_train))}')
    # Evaluate model on test data
    print(f'Mean squared error on test data: '
          f'{mean_squared_error(y_test, ridge.predict(x_test))}')
    # Explained variance score: 1 is perfect prediction
    print(f'Variance score on test data: '
          f'{r2_score(y_test, ridge.predict(x_test))}')

    # LASSO regression model to predict prices and calculate strategy returns
    goog_data['Predicted_signal'] = ridge.predict(x)
    goog_data['GOOG_Returns'] = \
        np.log(goog_data['Close'] / goog_data['Close'].shift(1))
    print(goog_data)

    # Calculate cumulative returns for the test data (train data onwards)
    cum_goog_return = \
        finml.calculate_return(goog_data, split_value=len(x_train),
                               symbol='GOOG')

    cum_strategy_return = \
        finml.calculate_strategy_return(goog_data, split_value=len(x_train))

    finml.plot_chart(cum_goog_return, cum_strategy_return, symbol='GOOG')

    sharpe = finml.sharpe_ratio(cum_strategy_return, cum_goog_return)
    print(f'Sharpe ratio: {sharpe}')

    # Display plots and block
    plt.show()
Пример #8
0
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    goog_data = get_google_data('data/goog_data_large.pkl',
                                start_date='2001-01-01',
                                end_date='2018-01-01')
    # Features are open - close price and high - low price
    # Target is difference in daily close price
    goog_data, x, y = finml.create_regression_trading_condition(goog_data)
    # Visualise the data
    pd.plotting.scatter_matrix(goog_data[['Open-Close', 'High-Low', 'Target']],
                               grid=True, diagonal='kde', alpha=0.5)

    # Display plots and block
    plt.show()
Пример #9
0
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    goog_data = data.get_google_data('data/goog_data_large.pkl',
                                     start_date='2001-01-01',
                                     end_date='2018-01-01')
    # Features are open - close price and high - low price
    # Target is based on difference in daily close price and is +1 if future
    # close price is higher than the current close price and -1 if the future
    # close price is lower than the current close price.
    goog_data, x, y = finml.create_classification_trading_condition(goog_data)

    # Split into train (80%) and test data sets
    x_train, x_test, y_train, y_test = finml.create_train_split_group(x, y)

    # KNN classification model using K=15
    knn = KNeighborsClassifier(n_neighbors=15)
    y_train_array = y_train.to_numpy().ravel()
    knn.fit(x_train, y_train_array)
    accuracy_train = accuracy_score(y_train, knn.predict(x_train))
    print('Training accuracy:', accuracy_train)
    accuracy_test = accuracy_score(y_test, knn.predict(x_test))
    print('Test accuracy:', accuracy_test)

    # Predict whether the price goes up or down
    goog_data['Predicted_signal'] = knn.predict(x)
    goog_data['GOOG_Returns'] = \
        np.log(goog_data['Close'] / goog_data['Close'].shift(1))
    print(goog_data)

    # Calculate cumulative returns for the test data (train data onwards)
    cum_goog_return = \
        finml.calculate_return(goog_data, split_value=len(x_train),
                               symbol='GOOG')
    cum_strategy_return = \
        finml.calculate_strategy_return(goog_data, split_value=len(x_train))

    finml.plot_chart(cum_goog_return, cum_strategy_return, symbol='GOOG')

    sharpe = finml.sharpe_ratio(cum_strategy_return, cum_goog_return)
    print(f'Sharpe ratio: {sharpe}')

    # Display plots and block
    plt.show()
Пример #10
0
def main():
    # Load Google financial data into a DataFrame
    goog_data = data.get_google_data(start_date='2001-01-01')
    # Run for loop backtester
    naive_backtester = ForLoopBackTester()
    for line in zip(goog_data.index, goog_data['Adj Close']):
        date = line[0]
        price = line[1]
        price_information = {'date': date, 'price': float(price)}
        is_tradable = naive_backtester.create_metrics(price_information)
        if is_tradable:
            naive_backtester.trade(price_information)

    # Plot output
    plt.plot(naive_backtester.list_total, label='Holdings+Cash')
    plt.title('For Loop Backtester')
    plt.grid()
    plt.legend()
    plt.show()
Пример #11
0
def main():
    # Load Google financial data into a DataFrame
    goog_data = data.get_google_data(start_date='2001-01-01')
    # Run event driven backtester
    edbt = EventDrivenBackTester()
    for line in zip(goog_data.index, goog_data['Adj Close']):
        date = line[0]
        price = line[1]
        price_information = {'date': date, 'price': float(price)}
        # Create orders from price (ticker) information
        edbt.create_orders(price_information['price'])
        # Run main trading loop
        edbt.process_events()

    # Plot output
    plt.plot(edbt.trading_strategy.list_paper_total,
             label='Paper Trading Using Event Driven Backtester')
    plt.plot(edbt.trading_strategy.list_total,
             label='Trading Using Event Driven Backtester')
    plt.grid()
    plt.legend()
    plt.show()
Пример #12
0
def main():
    # Get Google data from Yahoo from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    goog_data = goog_data_raw.tail(620)
    # Use close price for this analysis
    close = goog_data['Close']
    close_sma = simple_moving_average(close)
    goog_data = goog_data.assign(
        ClosePrice=pd.Series(close, index=goog_data.index))
    goog_data = goog_data.assign(
        Simple20DayMovingAverage=pd.Series(close_sma, index=goog_data.index))

    close_price = goog_data['ClosePrice']
    sma = goog_data['Simple20DayMovingAverage']

    # Plot the close price 20 day SMA
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    close_price.plot(ax=ax1, color='g', lw=2.0, legend=True)
    sma.plot(ax=ax1, color='r', lw=2.0, legend=True)
    plt.grid()
    plt.show()
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    goog_data = data.get_google_data('data/goog_data.pkl',
                                     start_date='2001-01-01',
                                     end_date='2018-01-01')
    # Turtle trading strategy
    ts = signals.turtle_trading(goog_data, 50)
    print('Turtle trading strategy:')
    print(ts)

    # Plot the adjusted close price
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    goog_data['Adj Close'].plot(ax=ax1, color='g', lw=0.5, label='Price')

    ts['high'].plot(ax=ax1, color='g', lw=0.5, label='Highs')
    ts['low'].plot(ax=ax1, color='r', lw=0.5, label='Lows')
    ts['avg'].plot(ax=ax1, color='b', lw=0.5, label='Average')

    # Plot buy signal
    ax1.plot(ts.loc[ts.orders == 1.0].index,
             goog_data['Adj Close'][ts.orders == 1.0],
             '^',
             markersize=7,
             color='k',
             label='Buy')
    # Plot sell signal
    ax1.plot(ts.loc[ts.orders == -1.0].index,
             goog_data['Adj Close'][ts.orders == -1.0],
             'v',
             markersize=7,
             color='k',
             label='Sell')

    plt.legend()
    plt.title('Turtle Trading Strategy')
    plt.grid()
    plt.show()
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    goog_data = data.get_google_data('data/goog_data.pkl',
                                     start_date='2001-01-01',
                                     end_date='2018-01-01')
    # Dual moving average trading signal
    ts = signals.dual_moving_average(goog_data, 20, 100)
    print('Dual moving average trading signal:')
    print(ts)

    # Plot curve representing orders for dual moving average strategy using
    # close price.
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    goog_data['Adj Close'].plot(ax=ax1, color='g', lw=0.5, label='Price')
    ts['short_mavg'].plot(ax=ax1, color='r', lw=2.0, label='Short mavg')
    ts['long_mavg'].plot(ax=ax1, color='b', lw=2.0, label='Long mavg')

    # Plot buy order
    ax1.plot(ts.loc[ts.orders == 1.0].index,
             goog_data['Adj Close'][ts.orders == 1.0],
             '^',
             markersize=7,
             color='k',
             label='Buy')

    # Plot sell order
    ax1.plot(ts.loc[ts.orders == -1.0].index,
             goog_data['Adj Close'][ts.orders == -1.0],
             'v',
             markersize=7,
             color='k',
             label='Sell')

    plt.legend()
    plt.title('Dual Moving Average Trading Strategy')
    plt.grid()
    plt.show()
Пример #15
0
def main():
    # Get the Google data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    goog_data = goog_data_raw.tail(620)
    # Use close price for this analysis
    close = goog_data['Close']
    # Calculate the MACD using default time periods: fast=10; slow=40; macd=20
    macd_df = moving_average_conv_div(close)
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    print(macd_df)

    # Extract data to plot
    close_price = close
    ema_f = macd_df['EMA_fast']
    ema_s = macd_df['EMA_slow']
    macd = macd_df['MACD']
    ema_macd = macd_df['EMA_MACD']
    macd_histogram = macd_df['MACD_histogram']

    # Plot the data
    fig = plt.figure()
    ax1 = fig.add_subplot(311, ylabel='Google price in $')
    close_price.plot(ax=ax1, color='g', lw=2.0, legend=True)
    ema_f.plot(ax=ax1, color='b', lw=2.0, legend=True)
    ema_s.plot(ax=ax1, color='r', lw=2.0, legend=True)
    ax2 = fig.add_subplot(312, ylabel='MACD')
    macd.plot(ax=ax2, color='k', lw=2.0, legend=True)
    ema_macd.plot(ax=ax2, color='g', lw=2.0, legend=True)
    ax3 = fig.add_subplot(313, ylabel='MACD')
    macd_histogram.plot(ax=ax3,
                        color='r',
                        kind='bar',
                        legend=True,
                        use_index=False)
    ax1.grid()
    ax2.grid()
    plt.show()
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    goog_data = data.get_google_data('data/goog_data.pkl',
                                     start_date='2001-01-01',
                                     end_date='2018-01-01')
    # Naive momentum based trading strategy
    ts = signals.naive_momentum_trading(goog_data, 5)
    print('Naive momentum based trading strategy:')
    print(ts)

    # Plot the adjusted close price
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    goog_data['Adj Close'].plot(ax=ax1, color='g', lw=0.5, label='Price')

    # Plot buy order
    ax1.plot(ts.loc[ts.orders == 1.0].index,
             goog_data['Adj Close'][ts.orders == 1],
             '^',
             markersize=7,
             color='k',
             label='Buy')

    # Plot sell order
    ax1.plot(ts.loc[ts.orders == -1.0].index,
             goog_data['Adj Close'][ts.orders == -1],
             'v',
             markersize=7,
             color='k',
             label='Sell')

    plt.legend()
    plt.title('Naive Momentum Trading Strategy')
    plt.grid()
    plt.show()
def main():
    # Get GOOG data from Yahoo Finance from 2001-01-01 to 2018-01-01
    start_date = '2001-01-01'
    goog_data_file = 'data/goog_data_large.pkl'
    goog_data = get_google_data(goog_data_file, start_date=start_date)
    print(goog_data)

    # Calculate the average monthly percentage change of the daily adjusted
    # close price.
    goog_monthly_return = goog_data['Adj Close'].pct_change().groupby([
        goog_data['Adj Close'].index.year, goog_data['Adj Close'].index.month
    ]).mean()
    goog_monthly_return_list = []

    for i in range(len(goog_monthly_return)):
        goog_monthly_return_list.append({
            'month':
            goog_monthly_return.index[i][1],
            'monthly_return':
            goog_monthly_return[i]
        })

    goog_monthly_return_df = pd.DataFrame(goog_monthly_return_list,
                                          columns=['month', 'monthly_return'])
    print(goog_monthly_return_df)
    goog_monthly_return_df.boxplot(column='monthly_return', by='month')

    ax = plt.gca()
    labels = [
        'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
        'Nov', 'Dec'
    ]
    ax.set_xticklabels(labels)
    ax.set_ylabel('GOOG return')
    plt.title('GOOG Monthly Return 2001-2018')
    plt.suptitle('')

    # With trend
    plot_rolling_statistics_ts(
        goog_monthly_return, 'GOOG prices rolling mean and standard deviation',
        'Monthly return')
    plot_rolling_statistics_ts(
        goog_data['Adj Close'],
        'GOOG prices rolling mean and standard deviation', 'Daily prices', 365)

    # Without trend (stationary)
    plot_stationary_ts(goog_data['Adj Close'],
                       'GOOG prices without trend',
                       'Daily prices',
                       window_size=365)

    # Augmented Dickey-Fuller test
    df = augmented_dickey_fuller(goog_data['Adj Close'])
    print('Augmented Dickey-Fuller test for adjusted close price:')
    print(df)
    df = augmented_dickey_fuller(goog_monthly_return)
    print('Augmented Dickey-Fuller test for monthly return:')
    print(df)

    # Forecast time series using Auto-Regression Integrated Moving Averages
    # (ARIMA) model
    plt.figure()
    plt.subplot(211)
    # Plot autocorrelation function (ACF) for monthly returns
    plot_acf(goog_monthly_return, ax=plt.gca(), lags=10)
    # Plot partial autocorrelation function (PACF) for monthly returns
    plt.subplot(212)
    plot_pacf(goog_monthly_return, ax=plt.gca(), lags=10)
    # The Autoregressive term AR(p) is the number of lags of dependent variable.
    # The lag value is p=1 when the PACF crosses the upper confidence interval
    # for the first time.
    # The Moving Average term MA(q) is the number of lags for errors in
    # prediction; error = (moving average) - (actual value)
    # The lag value is q=1 when the ACF plot crosses the upper confidence
    # interval for the first time.
    model = ARIMA(goog_monthly_return, order=(2, 0, 2))
    fitted_results = model.fit()
    plt.figure()
    goog_monthly_return.plot(label='GOOG Monthly Return $', lw=0.5)
    fitted_results.fittedvalues.plot(label='Forecast', color='red')
    plt.grid()
    plt.legend()

    plt.show()
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    # Get daily trading data for 4 years
    SYMBOL = 'GOOG'
    goog_data = data.get_google_data(f'data/{SYMBOL}_data.pkl',
                                     start_date='2014-01-01',
                                     end_date='2018-01-01')

    # Use close price for this analysis
    close = goog_data.loc[:, 'Close']

    # Preliminary analysis

    # Calculate and plot SMA to determine average SMA standard deviation
    # To avoid complications with stock split, we only take dates without
    # splits. Therefore only keep 620 days.
    sma_time_periods = 20  # look back period
    avg_std_dev = signals.avg_sma_std_dev(close, tail=620,
                                          sma_time_periods=sma_time_periods)
    print(f'\nAverage stdev of prices SMA over {sma_time_periods} day '
          f'look back period: {avg_std_dev}')

    # Average standard deviation of prices SMA over look back period
    avg_std_dev = 15
    print(f'\nApproximate average stdev of prices SMA over '
          f'{sma_time_periods} day look back period: {avg_std_dev}')

    # Constants defining strategy behaviour/thresholds

    # APO trading signal value above which to enter buy orders/long position
    apo_value_for_buy_entry = 10
    # APO trading signal value below which to enter sell orders/short position
    apo_value_for_sell_entry = -10
    # Minimum price change since last trade before considering trading again.
    # This is to prevent over trading at around same prices
    min_price_move_from_last_trade = 10
    # Number of shares to buy/sell on every trade
    num_shares_per_trade = 10
    # Minimum open/unrealised profit at which to close and lock profits
    min_profit_to_close = 10 * num_shares_per_trade

    # Exponential moving average time periods for APO calculation
    ema_time_period_fast = 10
    ema_time_period_slow = 40

    # Calculate trading strategy
    print('\nTrading strategy:')
    df = signals.volatility_trend_following(
        close, sma_time_periods, avg_std_dev, ema_time_period_fast,
        ema_time_period_slow, apo_value_for_buy_entry, apo_value_for_sell_entry,
        min_price_move_from_last_trade, num_shares_per_trade,
        min_profit_to_close)

    # Visualise
    plotting.visualise(df, apo_value_for_buy_entry, apo_value_for_sell_entry,
                       num_shares_per_trade)

    # Prepare DataFrame to save results to CSV
    goog_data = pd.concat([goog_data, df], axis=1)
    # Remove redundant close price column
    goog_data = goog_data.drop('ClosePrice', axis=1)
    goog_data.to_csv('ch05/volatility_trend_following.csv')

    # Display plots and block
    plt.show()
Пример #19
0
def main():
    # Load Google finance data from Yahoo from 2014-01-01 to 2018-01-01
    goog_data_raw = get_google_data()
    # To avoid complications with stock split, we only take dates without
    # splits. Therefore only keep 620 days.
    goog_data = goog_data_raw.tail(620)
    lows = goog_data['Low']
    highs = goog_data['High']
    # Plot the data
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    highs.plot(ax=ax1, color='c', lw=2.0)
    lows.plot(ax=ax1, color='y', lw=2.0)
    # Plot resistance limit
    plt.hlines(highs.head(200).max(),
               lows.index.values[0],
               lows.index.values[-1],
               linewidth=2,
               color='g',
               label='Resistance')
    # Plot support limit
    plt.hlines(lows.head(200).min(),
               lows.index.values[0],
               lows.index.values[-1],
               linewidth=2,
               color='r',
               label='Support')
    plt.axvline(x=lows.index.values[200],
                linewidth=2,
                color='b',
                linestyle=':')
    plt.grid()
    plt.legend()

    # Support and Resistance Trading Strategy
    goog_data = goog_data_raw
    goog_data_signal = pd.DataFrame(index=goog_data.index)
    goog_data_signal['price'] = goog_data['Adj Close']
    trading_support_resistance(goog_data_signal)
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price in $')
    # Plot support, resistance and price
    goog_data_signal['sup'].plot(ax=ax1, color='g', lw=2.0)
    goog_data_signal['res'].plot(ax=ax1, color='b', lw=2.0)
    goog_data_signal['price'].plot(ax=ax1, color='r', lw=2.0)
    ax1.plot(goog_data_signal.loc[goog_data_signal.positions == 1.0].index,
             goog_data_signal.price[goog_data_signal.positions == 1.0],
             '^',
             markersize=7,
             color='k',
             label='buy')
    ax1.plot(goog_data_signal.loc[goog_data_signal.positions == -1.0].index,
             goog_data_signal.price[goog_data_signal.positions == -1.0],
             'v',
             markersize=7,
             color='k',
             label='sell')
    plt.legend()
    plt.grid()

    # Display plot and block
    plt.show()
Пример #20
0
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    # Get daily trading data for 4 years
    SYMBOL = 'GOOG'
    goog_data = data.get_google_data(f'data/{SYMBOL}_data.pkl',
                                     start_date='2014-01-01',
                                     end_date='2018-01-01')

    # Use close price for this analysis
    close = goog_data.loc[:, 'Close']

    # Preliminary analysis

    # Calculate and plot SMA to determine average SMA standard deviation
    # To avoid complications with stock split, we only take dates without
    # splits. Therefore only keep 620 days.
    sma_time_periods = 20  # look back period
    avg_std_dev = signals.avg_sma_std_dev(close,
                                          tail=620,
                                          sma_time_periods=sma_time_periods)
    print(f'\nAverage stdev of prices SMA over {sma_time_periods} day '
          f'look back period: {avg_std_dev}')

    # Average standard deviation of prices SMA over look back period
    avg_std_dev = 15
    print(f'\nApproximate average stdev of prices SMA over '
          f'{sma_time_periods} day look back period: {avg_std_dev}')

    # Constants defining strategy behaviour/thresholds

    # APO trading signal value below which to enter buy orders/long position
    apo_value_for_buy_entry = -10
    # APO trading signal value above which to enter sell orders/short position
    apo_value_for_sell_entry = 10
    # Minimum price change since last trade before considering trading again.
    # This is to prevent over trading at around same prices
    min_price_move_from_last_trade = 10
    # Range of number of shares to buy/sell on every trade
    min_num_shares_per_trade = 1
    max_num_shares_per_trade = 50
    increment_num_shares_per_trade = 2
    # Beginning number of shares to buy/sell on every trade
    num_shares_per_trade = min_num_shares_per_trade
    # Minimum open/unrealised profit at which to close and lock profits
    min_profit_to_close = 10 * num_shares_per_trade

    # Performance and risk limits
    risk_limit_weekly_stop_loss = -6000
    increment_risk_limit_weekly_stop_loss = -12000
    risk_limit_monthly_stop_loss = -15000
    increment_risk_limit_monthly_stop_loss = -30000
    risk_limit_max_positions = 5
    increment_risk_limit_max_positions = 3
    risk_limit_max_positions_holding_time_days = 120 * risk_limit_max_positions
    risk_limit_max_trade_size = 5
    increment_risk_limit_max_trade_size = 2

    # Exponential moving average time periods for APO calculation
    ema_time_period_fast = 10
    ema_time_period_slow = 40

    # Calculate trading strategy
    print('\nTrading strategy:')
    df = signals.volatility_mean_reversion_dynamic_risk(
        close, risk_limit_weekly_stop_loss,
        increment_risk_limit_weekly_stop_loss, risk_limit_monthly_stop_loss,
        increment_risk_limit_monthly_stop_loss, risk_limit_max_positions,
        increment_risk_limit_max_positions,
        risk_limit_max_positions_holding_time_days, risk_limit_max_trade_size,
        increment_risk_limit_max_trade_size, sma_time_periods, avg_std_dev,
        ema_time_period_fast, ema_time_period_slow, apo_value_for_buy_entry,
        apo_value_for_sell_entry, min_price_move_from_last_trade,
        min_num_shares_per_trade, max_num_shares_per_trade,
        increment_num_shares_per_trade, min_profit_to_close)

    # Visualise
    plotting.visualise(df, apo_value_for_buy_entry, apo_value_for_sell_entry,
                       num_shares_per_trade)
    # Additional plots
    plt.figure()
    plt.title('Number of Shares and Maximum Trade Size')
    df['NumShares'].plot(color='b', lw=3.0)
    df['MaxTradeSize'].plot(color='g', lw=1.0)
    plt.legend()
    plt.grid()

    plt.figure()
    plt.title('Absolute and Maximum Positions')
    df['AbsPosition'].plot(color='b', lw=1.0)
    df['MaxPosition'].plot(color='g', lw=1.0)
    plt.legend()
    plt.grid()

    # Prepare DataFrame to save results to CSV
    goog_data = pd.concat([goog_data, df], axis=1)
    # Remove redundant close price column
    goog_data = goog_data.drop('ClosePrice', axis=1)
    goog_data.to_csv('ch06/volatility_mean_reversion_dynamic_risk.csv')

    # Display plots and block
    plt.show()
Пример #21
0
def main():
    # Prevent truncating display of DataFrame
    pd.set_option('display.width', None)
    # Get GOOG data from Yahoo Finance from 2014-01-01 to 2018-01-01
    goog_data = get_google_data()
    print('Raw GOOG data from Yahoo Finance:')
    print(goog_data)
    goog_data_signal = pd.DataFrame(index=goog_data.index)
    # Use the adjusted closing price of the stock which is closing price
    # adjusted for corporate actions. Takes into account stock splits and
    # dividends.
    goog_data_signal['price'] = goog_data['Adj Close']
    # Signal based on price difference between consecutive days
    goog_data_signal['daily_difference'] = goog_data_signal['price'].diff()
    # Initialise signal column
    goog_data_signal['signal'] = 0.0
    # Trading signal: If the daily price difference is positive (price has
    # increased) then set signal=1.0 (sell) else set signal=0.0 (buy)
    goog_data_signal['signal'][:] = \
        np.where(goog_data_signal['daily_difference'][:] > 0, 1.0, 0.0)
    # Limit number of order by restricting to the number of positions on the
    # market to prevent constantly buying if the market keeps moving down, or
    # constantly selling when the market is moving up. Position is the
    # inventory of stocks or assets that we have on the market, e.g. if we
    # buy one Google share it means we have a position of one share on the
    # market. If we sell this share we will not have any positions on the
    # market.
    goog_data_signal['positions'] = goog_data_signal['signal'].diff()
    print('\nGoogle data signal:')
    print(goog_data_signal)

    # Plot the GOOG price
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Google price $')
    goog_data_signal['price'].plot(ax=ax1, color='r', lw=2.0)
    # Draw up arrow to indicate when we buy
    ax1.plot(goog_data_signal.loc[goog_data_signal.positions == 1.0].index,
             goog_data_signal.price[goog_data_signal.positions == 1.0],
             '^',
             markersize=5,
             color='m')
    # Draw a down arrow to indicate when we sell
    ax1.plot(goog_data_signal.loc[goog_data_signal.positions == -1.0].index,
             goog_data_signal.price[goog_data_signal.positions == -1.0],
             'v',
             markersize=5,
             color='k')
    plt.grid()

    # Backtesting - relies on the assumption that the past predicts the future
    # Test the strategy with an initial capital over a given period of time.
    initial_capital = 1000.0
    # Create DataFrame for the positions and the portfolio
    positions = pd.DataFrame(index=goog_data_signal.index).fillna(0.0)
    portfolio = pd.DataFrame(index=goog_data_signal.index).fillna(0.0)
    # Store GOOG positions
    positions['GOOG'] = goog_data_signal['signal']
    # Store the amount of GOOG positions in $ for the portfolio
    portfolio['positions'] = \
        positions.multiply(goog_data_signal['price'], axis=0)
    # Calculate the non-invested money (cash)
    portfolio['cash'] = \
        initial_capital - (positions.diff().multiply(goog_data_signal['price'],
                                                     axis=0)).cumsum()
    # Total investment is sum of positions in $ and cash
    portfolio['total'] = portfolio['positions'] + portfolio['cash']
    portfolio.plot()

    # Plot portfolio total value
    fig = plt.figure()
    ax1 = fig.add_subplot(111, ylabel='Portfolio value in $')
    portfolio['total'].plot(ax=ax1, lw=2.0)
    ax1.plot(portfolio.loc[goog_data_signal.positions == 1.0].index,
             portfolio.total[goog_data_signal.positions == 1.0],
             '^',
             markersize=10,
             color='m')
    ax1.plot(portfolio.loc[goog_data_signal.positions == -1.0].index,
             portfolio.total[goog_data_signal.positions == -1.0],
             'v',
             markersize=10,
             color='k')
    plt.grid()

    # Display plots and block
    plt.show()