Ejemplo n.º 1
0
def plot_price_model(seed=0, num_days=1000):

    # Create a simulation environment
    env = sca.MarketEnvironment()

    # Reset the enviroment with the given seed
    env.reset(seed)

    # Create an array to hold the daily stock price for the given number of days
    price_hist = np.zeros(num_days)

    # Get the simulated stock price movement from the environment
    for i in range(num_days):
        _, _, _, info = env.step(i)
        price_hist[i] = info.price

    # Print Average and Standard Deviation in Stock Price
    print('Average Stock Price: ${:,.2f}'.format(price_hist.mean()))
    print('Standard Deviation in Stock Price: ${:,.2f}'.format(
        price_hist.std()))
    #     print('Standard Deviation of Random Noise: {:,.5f}'.format(np.sqrt(env.singleStepVariance * env.tau)))

    # Plot the price history for the given number of days
    price_df = pd.DataFrame(data=price_hist,
                            columns=['Stock'],
                            dtype='float64')
    ax = price_df.plot(colormap='cool', grid=False)
    ax.set_facecolor(color='k')
    ax = plt.gca()
    yNumFmt = mticker.StrMethodFormatter('${x:,.2f}')
    ax.yaxis.set_major_formatter(yNumFmt)
    plt.ylabel('Stock Price')
    plt.xlabel('days')
    plt.show()
Ejemplo n.º 2
0
def get_optimal_vals(lq_time=60, nm_trades=60, tr_risk=1e-6, title=''):

    # Create a simulation environment
    env = sca.MarketEnvironment()

    # Reset the enviroment with the given parameters
    env.reset(liquid_time=lq_time, num_trades=nm_trades, lamb=tr_risk)

    # Set the title for the AC Optimal Strategy table
    if title == '':
        title = 'AC Optimal Strategy'
    else:
        title = 'AC Optimal Strategy for ' + title

    # Get the AC optimal values from the environment
    E = env.get_AC_expected_shortfall(env.total_shares)
    V = env.get_AC_variance(env.total_shares)
    U = env.compute_AC_utility(env.total_shares)

    left_col = [('Number of Days to Sell All the Shares:',
                 ['{}'.format(env.liquidation_time)]),
                ('Half-Life of The Trade:', ['{:,.1f}'.format(1 / env.kappa)]),
                ('Utility:', ['${:,.2f}'.format(U)])]

    right_col = [('Initial Portfolio Value:',
                  ['${:,.2f}'.format(env.total_shares * env.startingPrice)]),
                 ('Expected Shortfall:', ['${:,.2f}'.format(E)]),
                 ('Standard Deviation of Shortfall:',
                  ['${:,.2f}'.format(np.sqrt(V))])]

    # Generate the table with the AC optimal values
    val_table = generate_table(left_col, right_col, title)

    return val_table
Ejemplo n.º 3
0
def get_av_std(lq_time=60, nm_trades=60, tr_risk=1e-6, trs=100):

    # Create simulation environment
    env = sca.MarketEnvironment()

    # Reset the enviroment
    env.reset(liquid_time=lq_time, num_trades=nm_trades, lamb=tr_risk)

    # Get the trading list
    trl = env.get_trade_list()

    # Since we are not selling fractional shares we round up the shares in the trading list
    trade_list = round_trade_list(trl)

    # Set the initial shortfall to zero
    shortfall_hist = np.array([])

    for episode in range(trs):

        # Print current episode every 100 episodes
        if (episode + 1) % 100 == 0:
            print('Episode [{}/{}]'.format(episode + 1, trs),
                  end='\r',
                  flush=True)

        # Reset the enviroment
        env.reset(seed=episode,
                  liquid_time=lq_time,
                  num_trades=nm_trades,
                  lamb=tr_risk)

        # set the environment to make transactions
        env.start_transactions()

        for trade in trade_list:
            action = trade / env.shares_remaining
            _, _, _, info = env.step(action)

            if info.done:
                shortfall_hist = np.append(shortfall_hist,
                                           info.implementation_shortfall)
                break

    print('Average Implementation Shortfall: ${:,.2f}'.format(
        shortfall_hist.mean()))
    print(
        'Standard Deviation of the Implementation Shortfall: ${:,.2f}'.format(
            shortfall_hist.std()))

    plt.plot(shortfall_hist, 'cyan', label='')
    plt.xlim(0, trs)
    ax = plt.gca()
    ax.set_facecolor('k')
    ax.set_xlabel('Episode', fontsize=15)
    ax.set_ylabel('Implementation Shortfall (US $)', fontsize=15)
    ax.axhline(shortfall_hist.mean(), 0, 1, color='m', label='Average')
    yNumFmt = mticker.StrMethodFormatter('${x:,.0f}')
    ax.yaxis.set_major_formatter(yNumFmt)
    plt.legend()
    plt.show
Ejemplo n.º 4
0
def implement_trade_list(seed=0, lq_time=60, nm_trades=60, tr_risk=1e-6):

    # Create simulation environment
    env = sca.MarketEnvironment()

    # Reset the environment with the given parameters
    env.reset(seed=seed,
              liquid_time=lq_time,
              num_trades=nm_trades,
              lamb=tr_risk)

    # Get the trading list from the environment
    trl = env.get_trade_list()

    # Since we are not selling fractional shares we round up the shares in the trading list
    trade_list = round_trade_list(trl)

    # set the environment to make transactions
    env.start_transactions()

    # Create an array to hold the impacted stock price
    price_hist = np.array([])

    # Implement the trading list in our similation environment
    for trade in trade_list:

        # Convert the number of shares to sell in each trade into an action
        action = trade / env.shares_remaining

        # Take a step in the environment my selling the number of shares in the current trade
        _, _, _, info = env.step(action)

        # Get the impacted price from the environment
        price_hist = np.append(price_hist, info.exec_price)

        # If all shares have been sold, stop making transactions and get the implementation sortfall
        if info.done:
            print('Implementation Shortfall: ${:,.2f} \n'.format(
                info.implementation_shortfall))
            break

    # Plot the impacted price
    price_df = pd.DataFrame(data=price_hist,
                            columns=['Stock'],
                            dtype='float64')
    ax = price_df.plot(colormap='cool', grid=False)
    ax.set_facecolor(color='k')
    ax.set_title('Impacted Stock Price')
    ax = plt.gca()
    yNumFmt = mticker.StrMethodFormatter('${x:,.2f}')
    ax.yaxis.set_major_formatter(yNumFmt)
    plt.plot(price_hist, 'o')
    plt.ylabel('Stock Price')
    plt.xlabel('Trade Number')
    plt.show()
def plot_efficient_frontier(tr_risk = 1e-6):
    
    # Create a simulation environment
    env = sca.MarketEnvironment()
    
    # Reset the enviroment with the given trader's risk aversion
    env.reset(lamb = tr_risk)

    # Get the expected shortfall and corresponding variance for the given trader's risk aversion
    tr_E = env.get_AC_expected_shortfall(env.total_shares)
    tr_V = env.get_AC_variance(env.total_shares)
    
    # Create empty arrays to hold our values of E, V, and U
    E = np.array([])
    V = np.array([])
    U = np.array([])
    
    # Set the number of plot points for our frontier
    num_points = 7000
    
    # Set the values of the trader's risk aversion to plot
    lambdas = np.linspace(1e-7, 1e-4, num_points)
    
    # Calclate E, V, U for each value of llambda
    for llambda in lambdas:
        env.reset(lamb = llambda)
        E = np.append(E, env.get_AC_expected_shortfall(env.total_shares))
        V = np.append(V, env.get_AC_variance(env.total_shares))
        U = np.append(U, env.compute_AC_utility(env.total_shares))
        
    # Plot E vs V and use U for the colorbar    
    cm = plt.cm.get_cmap('gist_rainbow')    
    sc = plt.scatter(V, E, s = 20, c = U, cmap = cm)
    plt.colorbar(sc, label = 'AC Utility', format = mticker.StrMethodFormatter('${x:,.0f}'))
    ax = plt.gca()
    ax.set_facecolor('k')
    ymin = E.min() * 0.7
    ymax = E.max() * 1.1
    plt.ylim(ymin, ymax)
    yNumFmt = mticker.StrMethodFormatter('${x:,.0f}')
    xNumFmt = mticker.StrMethodFormatter('{x:,.0f}')
    ax.yaxis.set_major_formatter(yNumFmt)
    ax.xaxis.set_major_formatter(xNumFmt)
    plt.xlabel('Variance of Shortfall')
    plt.ylabel('Expected Shortfall')
    
    # Get the annotation label and the correction factors
    an_st, xcrf, ycrf, scrf = get_crfs(tr_risk)
    
    # Plot the annotation in the above plot
    plt.annotate(an_st, xy = (tr_V, tr_E), xytext = (tr_V * xcrf, tr_E  * ycrf), color = 'w', size = 'large', 
                 arrowprops = dict(facecolor = 'cyan', shrink = scrf, width = 3, headwidth = 10))
    plt.show()
Ejemplo n.º 6
0
def get_env_param():

    # Create a simulation environment
    env = sca.MarketEnvironment()

    # Set the title for the financial parameters table
    fp_title = 'Financial Parameters'

    # Get the default financial parameters from the simulation environment
    fp_left_col = [('Annual Volatility:', ['{:.0f}%'.format(env.anv * 100)]),
                   ('Daily Volatility:', ['{:.1f}%'.format(env.dpv * 100)])]

    fp_right_col = [('Bid-Ask Spread:', ['{:.3f}'.format(env.basp)]),
                    ('Daily Trading Volume:', ['{:,.0f}'.format(env.dtv)])]

    # Set the title for the Almgren and Chriss Model parameters table
    acp_title = 'Almgren and Chriss Model Parameters'

    # Get the default Almgren and Chriss Model Parameters from the simulation environment
    acp_left_col = [('Total Number of Shares for Agent1 to Sell:',
                     ['{:,}'.format(env.total_shares1)]),
                    ('Total Number of Shares for Agent2 to Sell:',
                     ['{:,}'.format(env.total_shares2)]),
                    ('Starting Price per Share:',
                     ['${:.2f}'.format(env.startingPrice)]),
                    ('Price Impact for Each 1% of Daily Volume Traded:',
                     ['${}'.format(env.eta)]),
                    ('Number of Days to Sell All the Shares:',
                     ['{}'.format(env.liquidation_time)]),
                    ('Number of Trades:', ['{}'.format(env.num_n)])]

    acp_right_col = [
        ('Fixed Cost of Selling per Share:', ['${:.3f}'.format(env.epsilon)]),
        ('Trader\'s Risk Aversion for Agent 1:', ['{}'.format(env.llambda1)]),
        ('Trader\'s Risk Aversion for Agent 2:', ['{}'.format(env.llambda2)]),
        ('Permanent Impact Constant:', ['{}'.format(env.gamma)]),
        ('Single Step Variance:', ['{:.3f}'.format(env.singleStepVariance)]),
        ('Time Interval between trades:', ['{}'.format(env.tau)])
    ]

    # Generate tables with the default financial and AC Model parameters
    fp_table = generate_table(fp_left_col, fp_right_col, fp_title)
    acp_table = generate_table(acp_left_col, acp_right_col, acp_title)

    return fp_table, acp_table
Ejemplo n.º 7
0
def plot_trade_list(lq_time=60, nm_trades=60, tr_risk=1e-6, show_trl=False):

    # Create simulation environment
    env = sca.MarketEnvironment()

    # Reset the environment with the given parameters
    env.reset(liquid_time=lq_time, num_trades=nm_trades, lamb=tr_risk)

    # Get the trading list from the environment
    trade_list = env.get_trade_list()

    # Add a zero at the beginning of the trade list to indicate that at time 0 we don't sell any stocks
    new_trl = np.insert(trade_list, 0, 0)

    # We create a dataframe with the trading list and trading trajectory
    df = pd.DataFrame(data=list(range(nm_trades + 1)),
                      columns=['Trade Number'],
                      dtype='float64')
    df['Stocks Sold'] = new_trl
    df['Stocks Remaining'] = (np.ones(nm_trades + 1) *
                              env.total_shares) - np.cumsum(new_trl)

    # Create a figure with 2 plots in 1 row
    fig, axes = plt.subplots(nrows=1, ncols=2)

    # Make a scatter plot of the trade list
    df.iloc[1:].plot.scatter(x='Trade Number',
                             y='Stocks Sold',
                             c='Stocks Sold',
                             colormap='gist_rainbow',
                             alpha=1,
                             sharex=False,
                             s=50,
                             colorbar=False,
                             ax=axes[0])

    # Plot a line through the points of the scatter plot of the trade list
    axes[0].plot(df['Trade Number'].iloc[1:],
                 df['Stocks Sold'].iloc[1:],
                 linewidth=2.0,
                 alpha=0.5)
    axes[0].set_facecolor(color='k')
    yNumFmt = mticker.StrMethodFormatter('{x:,.0f}')
    axes[0].yaxis.set_major_formatter(yNumFmt)
    axes[0].set_title('Trading List')

    # Make a scatter plot of the number of stocks remaining after each trade
    df.plot.scatter(x='Trade Number',
                    y='Stocks Remaining',
                    c='Stocks Remaining',
                    colormap='gist_rainbow',
                    alpha=1,
                    sharex=False,
                    s=50,
                    colorbar=False,
                    ax=axes[1])

    # Plot a line through the points of the scatter plot of the number of stocks remaining after each trade
    axes[1].plot(df['Trade Number'],
                 df['Stocks Remaining'],
                 linewidth=2.0,
                 alpha=0.5)
    axes[1].set_facecolor(color='k')
    yNumFmt = mticker.StrMethodFormatter('{x:,.0f}')
    axes[1].yaxis.set_major_formatter(yNumFmt)
    axes[1].set_title('Trading Trajectory')

    # Set the spacing between plots
    plt.subplots_adjust(wspace=0.4)
    plt.show()

    print('\nNumber of Shares Sold: {:,.0f}\n'.format(new_trl.sum()))

    if show_trl:

        # Since we are not selling fractional shares we round up the shares in the trading list
        rd_trl = round_trade_list(new_trl)
        #         rd_trl = new_trl

        # We create a dataframe with the modified trading list and trading trajectory
        df2 = pd.DataFrame(data=list(range(nm_trades + 1)),
                           columns=['Trade Number'],
                           dtype='float64')
        df2['Stocks Sold'] = rd_trl
        df2['Stocks Remaining'] = (np.ones(nm_trades + 1) *
                                   env.total_shares) - np.cumsum(rd_trl)

        df2.set_index('Trade Number', inplace=True)

        #         return df2.style.hide_index().format({'Trade Number': '{:.0f}', 'Stocks Sold': '{:,.0f}', 'Stocks Remaining': '{:,.0f}'})
        return df2.style.format({
            'Stocks Sold': '{:,.0f}',
            'Stocks Remaining': '{:,.0f}'
        })
Ejemplo n.º 8
0
import utils

# Get the default financial and AC Model parameters
financial_params, ac_params = utils.get_env_param()
financial_params
ac_params
import numpy as np

import syntheticChrissAlmgren as sca
from ddpg_agent import Agent

from collections import deque

# Create simulation environment
env = sca.MarketEnvironment()

# Initialize Feed-forward DNNs for Actor and Critic models. 
agent = Agent(state_size=env.observation_space_dimension(), action_size=env.action_space_dimension(), random_seed=0)

# Set the liquidation time
lqt = 60

# Set the number of trades
n_trades = 60

# Set trader's risk aversion
tr = 1e-6

# Set the number of episodes to run the simulation
episodes = 10000