Пример #1
0
    def __init__(self, sym='SPY', sd=dt.datetime(2008,1, 1), \
            ed=dt.datetime(2009,12,31),sv=100000,verbose=False):

        self.sym = sym
        self.verbose = verbose
        self.shares = 0
        self.position = 0
        self.sv = sv
        self.cash = sv
        self.pp = 0
        #period
        n = 28
        chart = False
        #take in, normalize data
        df = ut.get_data([sym], pd.date_range(sd - dt.timedelta(100), ed))[sym]
        normed = df / df.ix[0]

        #get features
        sma = ind.SMA(normed, n)
        smap = ind.standardize(normed / sma)
        bbp = ind.standardize(ind.bband(normed, n, chart)[0])
        stdev = ind.standardize(normed.rolling(window=n, min_periods=n).std())
        mom = ind.standardize(ind.momentum(normed, n, chart))
        momvol = ind.standardize(mom / stdev)

        #daily returns & combined features
        rets = pd.DataFrame(df)
        daily_rets = rets[sym].copy()
        daily_rets[1:] = (rets[sym].ix[1:] / rets[sym].ix[:-1].values) - 1
        daily_rets.ix[0] = 0
        #print df

        #df = pd.DataFrame(df).assign(normed = normed).assign(smap=smap).\
        #        assign(stdev=stdev).assign(bbp=bbp).assign(mom=mom)[sd:]
        df = pd.DataFrame(df).assign(normed = normed).assign(smap=smap).\
                assign(bbp=bbp).assign(mom=mom)[sd:]

        #print df
        daily_rets.ix[0] = 0
        df = df.assign(dr=daily_rets)

        #print df
        self.df = df
        self.market = df.iterrows()
        self.curr = self.market.next()
        self.action = self.Action()
        #self.features = ['smap', 'stdev', 'bbp', 'mom']
        self.features = ['smap', 'bbp', 'mom']
Пример #2
0
def testPolicy(symbol = "AAPL", sd=dt.datetime(2010,1,1), \
        ed = dt.datetime(2011,12,31), sv=100000):
    chart = False
    n = 14
    #symbol = [symbol]
    prices = get_data(symbol, pd.date_range(sd, ed))
    #print prices
    #ffill and drop SPY
    prices.fillna(method='ffill', inplace=True)
    prices.fillna(method='bfill', inplace=True)
    prices = prices[symbol]
    #Generate indicators
    sma = ind.SMA(prices, n)
    smap = ind.standardize(prices / sma)
    bbp = ind.standardize(ind.bband(prices, n, chart)[0])
    stdev = ind.standardize(prices.rolling(window=n, min_periods=n).std())
    mom = ind.standardize(ind.momentum(prices, n, chart))
    momvol = ind.standardize(mom / stdev)
    orders = prices.copy()
    orders.ix[:, :] = np.nan

    smap_cross = pd.DataFrame(0, index=smap.index, columns=smap.columns)
    smap_cross[smap >= 1] = 1
    smap_cross[1:] = smap_cross.diff()
    smap_cross.ix[0] = 0

    orders[(smap < 0.95) & (bbp < 0) & (stdev < 0.1) & (mom < 0)] = 1000
    orders[(smap > 1.05) & (bbp > 1) & (stdev > 0.3) & (mom > 0)] = -1000

    orders[(smap_cross != 0)] = 0
    orders.ffill(inplace=True)
    orders.fillna(0, inplace=True)
    orders[1:] = orders.diff()
    #orders.ix[0] = 1000
    #orders.ix[-1] = -1000
    #orders = orders.loc[(orders!=0).any(axis=1)]
    #orders.ix[0] = 0
    #orders.ix[-1] = orders.ix[-2]*-1
    #print orders
    return orders
Пример #3
0
    def __init__(self, sym='SPY', sd=dt.datetime(2008,1, 1), \
            ed=dt.datetime(2009,12,31),sv=100000,verbose=False, experiment=False, impact=0.0):

        self.sym = sym
        self.verbose = verbose
        self.shares = 0
        self.position = 2
        self.sv = sv
        self.cash = sv
        self.pp = 0
        self.impact = impact
        self.experiment = experiment
        #n = 3  #period
        chart = False
        #take in, normalize data
        df = ut.get_data([sym], pd.date_range(sd - dt.timedelta(100), ed))[sym]
        #print df
        #print sd, ed
        normed = df / df.ix[0]
        #print normed
        #daily returns & combined features
        rets = pd.DataFrame(df)
        daily_rets = rets[sym].copy()
        daily_rets[1:] = (rets[sym].ix[1:] / rets[sym].ix[:-1].values) - 1
        daily_rets.ix[0] = 0

        #Simple moving average
        sma5 = normed.rolling(5).mean()
        sma15 = normed.rolling(15).mean()
        sma20 = normed.rolling(20).mean()
        sma25 = normed.rolling(25).mean()
        sma30 = normed.rolling(30).mean()
        sma40 = normed.rolling(40).mean()
        #print sma5
        # Volatility
        vol5 = normed.rolling(5).std()
        vol10 = normed.rolling(10).std()
        vol20 = normed.rolling(20).std()
        vol30 = normed.rolling(30).std()

        # Bollinger bands
        sma_bb = normed.rolling(5).mean()
        sma_bb_std = normed.rolling(5).std()
        bb = (normed -
              (sma_bb - 2 * sma_bb_std)) / ((sma_bb + 2 * sma_bb_std) -
                                            (sma_bb - 2 * sma_bb_std))

        # Moving average convergence/divergence
        #ema12 = pd.ewma(np.asarray(normed), span=12)
        #ema26 = pd.ewma(np.asarray(normed), span=26)
        #macd = ema12 - ema26

        # Momentum
        momentum2 = normed / normed.shift(2) - 1
        momentum5 = normed / normed.shift(5) - 1
        momentum10 = normed / normed.shift(10) - 1

        # Combine into new dataframe
        df = pd.DataFrame(df).assign(sma5=normed / sma5 - 1).assign(\
            bb=bb).assign(momentum2=momentum2).assign(normed=normed).\
            assign(vol10=vol10).assign(vol20=vol20).assign(vol30=vol30).assign(vol10=vol10)\
            .assign(vol5=vol5).assign(\
            momentum5=momentum5).assign(momentum10=momentum10)[sd:]

        df = df.assign(dr=daily_rets)
        #print df
        # Determine optimal features for states
        corr_df = df.corr().abs()
        corr = corr_df['dr'][:]
        corr.ix[0] = 0
        corr['normed'] = 0
        icorr = np.asarray(corr)
        scorr = icorr.argsort(
        )[-4:][::-1]  # select top 3 features and daily returns
        scorr = scorr[1:]  # remove daily returns from possible features
        optimal_ftrs = []
        for i in scorr:
            optimal_ftrs.append(corr_df.columns[i])

        if experiment:
            #print "Experiment 1 ACTIVATED"
            n = 14
            sma = ind.SMA(normed, n)
            smap = ind.standardize(normed / sma)
            bbp = ind.standardize(ind.bband(normed, n, chart)[0])
            stdev = ind.standardize(
                normed.rolling(window=n, min_periods=n).std())
            mom = ind.standardize(ind.momentum(normed, n, chart))
            momvol = ind.standardize(mom / stdev)
            df = pd.DataFrame(df).assign(normed=normed).assign(
                smap=smap).assign(stdev=stdev).assign(bbp=bbp).assign(
                    mom=mom)[sd:]
            optimal_ftrs = ['smap', 'stdev', 'bbp', 'mom']

        #df = pd.DataFrame(df).assign(normed = normed).assign(smap=smap).assign(bbp=bbp).assign(mom=mom)[sd:]
        #df = pd.DataFrame(df).assign(normed = normed)[sd:]

        self.df = df
        self.market = df.iterrows()
        self.curr = self.market.next()
        self.action = self.Action()
        self.features = optimal_ftrs
Пример #4
0
    # generate a buy signal (1) if price falls significantly below sma
    # generate a sell signal (-1) if prices rises significantly above sma
    smaSignal = 1 * (smaIndicator < -smaThreshold) + -1 * (smaIndicator >
                                                           smaThreshold)

    momIndicator, momWindow = getMomIndicator(data)
    momThreshold = 0.06  # 0.055 optimized value on manual trading strategy 1
    # generate a buy/sell signal if momentum is greatly positive/negative
    momSignal = -1 * (momIndicator < -momThreshold) + 1 * (momIndicator >
                                                           momThreshold)

    bbWindow = 10  # 48 NOT OPTIMIZED
    bbIndicator = getBb(data, bbWindow)
    bbThreshold = 0  # 0.2 NOT OPTIMIZED
    # generate a buy/sell signal if indicator is below/above the BB and the indicator is rising/falling significantly
    bbSignal = -1 * ((bbIndicator > 1) & (standardize(data).diff(1) < -bbThreshold)) + \
               1 * ((bbIndicator < -1) & (standardize(data).diff(1) > bbThreshold))

    crossIndicator, crossWindow = getCrossIndicator(data)
    crossThreshold = 0.08  # 0.08 optimized value on manual trading strategy 1
    # generate a buy/sell signal if indicator is close to 0.5/-0.5
    crossSignal = 1 * ((crossIndicator - 0.5).abs() < crossThreshold) + \
                  -1 * ((crossIndicator + 0.5).abs() < crossThreshold)

    # Combine individual signals. bbSignal is neglected here since including it
    # with the other signals did not result in label-free trading using strategy 1
    signal = 1 * ((smaSignal == 1) & (momSignal ==1) & (crossSignal == 1)) \
             + -1 * ((smaSignal == -1) & (momSignal == -1) & (crossSignal == -1))

    order = tradingStrategy(signal, holdTime)
    createOrder(order, 'rule_based')
Пример #5
0
def testcode():

    data = defineData()  # get AAPL between the in-sample dates set as default
    holdTime = 21  # in days

    smaIndicator, smaWindow = getSmaIndicator(data)
    smaThreshold = 0.012  #0.012 # optimized value on manual trading strategy 1
    # generate a buy signal (1) if price falls significantly below sma
    # generate a sell signal (-1) if prices rises significantly above sma
    smaSignal = 1 * (smaIndicator < -smaThreshold)  +  \
            -1 * (smaIndicator > smaThreshold)

    momIndicator, momWindow = getMomIndicator(data)
    momThreshold = 0.06  #0.055 # optimized value on manual trading strategy 1
    # generate a buy/sell signal if momentum is greatly positive/negative
    momSignal = -1 * (momIndicator < -momThreshold)  +  \
            1 * (momIndicator > momThreshold)

    bbWindow = 10  #48 NOT OPTIMIZED
    bbIndicator = getBb(data, bbWindow)
    bbThreshold = 0  #0.2 NOT OPTIMIZED
    # generate a buy/sell signal if indicator is below/above the lower/upper BB
    # and the indicator is rising/falling significantly
    bbSignal = -1 * ((bbIndicator > 1) & \
                     (standardize(data).diff(1) < -bbThreshold)) + \
                 1 * ((bbIndicator < -1) & \
                     (standardize(data).diff(1) > bbThreshold))

    crossIndicator, crossWindow = getCrossIndicator(data)
    crossThreshold = 0.08  #0.08 # optimized value on manual trading strategy 1
    # generate a buy/sell signal if indicator is close to 0.5/-0.5
    crossSignal = 1 * ( (crossIndicator - 0.5).abs() < crossThreshold) + \
            -1 * ( (crossIndicator + 0.5).abs() < crossThreshold )

    # Combine individual signals. bbSignal is neglected here since including it
    # with the other signals did not result in label-free trading using strategy 1
    signal = 1 * ( (smaSignal == 1) & (momSignal ==1 ) & (crossSignal == 1) ) \
        + -1 * ( (smaSignal == -1) & (momSignal == -1) & (crossSignal == -1) )

    order = tradingStrategy(signal, holdTime)
    createOrder(order, 'rule_based')
    cumReturn, portVals = testcode_marketsim('rule_based', verbose=False)
    print('Cumulative return [%]: ', round(cumReturn * 100, 4))

    plt.figure(figsize=(10, 10))
    plt.subplot(311)
    plt.plot(data / data[0], label='benchmark', color='k')
    plt.plot(portVals / portVals[0], label='rule-based')
    plt.xticks(rotation=30)
    plotVline(order)
    plt.title('rule-based with sma + mom + crossover indicators')
    lg = plt.legend(loc='best')
    lg.draw_frame(False)
    plt.ylabel('normalized')

    plt.subplot(312)
    plt.plot(smaSignal / 2, label='sma')
    plt.plot(momSignal / 1.3, '.', label='mom')
    plt.plot(crossSignal / 1.1, '.', label='crossover')
    plt.plot(signal, label='overall signal')
    plt.xticks(rotation=30)
    plt.ylabel('indicator signals [a.u.]')
    lg = plt.legend(loc='center right')
    lg.draw_frame(False)

    plt.subplot(313)
    plt.scatter(momIndicator[signal==0], crossIndicator[signal==0], \
                           color = 'k', label = 'hold')
    plt.scatter(momIndicator[signal==1], crossIndicator[signal==1], \
                           color = 'g', label = 'buy')
    plt.scatter(momIndicator[signal==-1], crossIndicator[signal==-1], \
                           color = 'r', label = 'sell')
    lg = plt.legend(loc='best')
    lg.draw_frame(True)
    plt.xlabel('Momentum Indicator')
    plt.ylabel('Crossover Indicator')