예제 #1
0
 def process_data(self, df):
     if self.freq == 1:
         xdf = df
     else:
         freq_str = str(self.freq) + "min"
         xdf = dh.conv_ohlc_freq(df, freq_str, extra_cols=['contract'])
     xdf['band_wth'] = self.band_func(
         xdf, n=self.boll_len).fillna(method='bfill')
     xdf['band_mid'] = self.ma_func(xdf, n=self.boll_len)
     xdf['band_up'] = xdf['band_mid'] + xdf['band_wth'] * self.band_ratio
     xdf['band_dn'] = xdf['band_mid'] - xdf['band_wth'] * self.band_ratio
     xdf['filter_ind'] = self.filter_func(xdf, self.filter_len)
     xdf['chan_h'] = dh.DONCH_H(xdf, self.channel)
     xdf['chan_l'] = dh.DONCH_L(xdf, self.channel)
     xdf['tr_stop_h'] = xdf['chan_h'] - (
         xdf['band_wth'] * self.SL /
         self.tick_base).astype('int') * self.tick_base
     xdf['tr_stop_l'] = xdf['chan_l'] + (
         xdf['band_wth'] * self.SL /
         self.tick_base).astype('int') * self.tick_base
     xdata = pd.concat([xdf['band_up'].shift(1), xdf['band_dn'].shift(1), \
                        xdf['tr_stop_h'].shift(1), xdf['tr_stop_l'].shift(1), xdf['filter_ind'].shift(1)], axis=1, \
                        keys=['band_up','band_dn', 'tr_stop_h', 'tr_stop_l', 'filter_ind'])
     self.df = df.join(xdata, how='left').fillna(method='ffill').dropna()
     self.df['cost'] = 0.0
     self.df['pos'] = 0.0
     self.df['closeout'] = 0.0
     self.df['traded_price'] = self.df['open']
 def process_data(self, mdf):
     if self.freq == 1:
         xdf = mdf
     else:
         freq_str = str(self.freq) + "min"
         xdf = dh.conv_ohlc_freq(mdf, freq_str, extra_cols = ['contract'])
     xdf['band_wth'] = self.band_func(xdf, n = self.boll_len) * self.band_ratio
     xdf['band_mid'] = self.ma_func(xdf, n=self.boll_len)
     xdf['band_up'] = xdf['band_mid'] + xdf['band_wth']
     xdf['band_dn'] = xdf['band_mid'] - xdf['band_wth']
     if (self.chan_len > 0):
         xdf['chan_h'] = dh.DONCH_H(xdf, n = self.chan_len, field = 'high')
         xdf['chan_l'] = dh.DONCH_L(xdf, n = self.chan_len, field = 'low')
     else:
         xdf['chan_h'] = -10000000
         xdf['chan_l'] = 10000000
     xdata = pd.concat([xdf['band_up'].shift(1), xdf['band_dn'].shift(1), \
                        xdf['band_mid'].shift(1), xdf['band_wth'].shift(1), \
                        xdf['chan_h'].shift(1), xdf['chan_l'].shift(1)], axis=1, \
                        keys=['band_up','band_dn', 'band_mid', 'band_wth', \
                              'chan_h', 'chan_l'])
     self.df = mdf.join(xdata, how = 'left').fillna(method='ffill')
     self.df['datetime'] = self.df.index
     self.df['cost'] = 0.0
     self.df['pos'] = 0.0
     self.df['closeout'] = 0.0
     self.df['traded_price'] = self.df['open']
예제 #3
0
def turtle_sim(ddf, mdf, config):
    marginrate = config['marginrate']
    offset = config['offset']
    start_equity = config['capital']
    tcost = config['trans_cost']
    signals = config['signals']
    unit = config['unit']
    NN = config['max_loss']
    max_pos = config['max_pos']
    start_idx = 0
    ddf['ATR'] = pd.Series(dh.ATR(ddf, n=signals[0]).shift(1))
    ddf['OL_1'] = pd.Series(dh.DONCH_H(ddf, signals[0]).shift(1))
    ddf['OS_1'] = pd.Series(dh.DONCH_L(ddf, signals[0]).shift(1))
    ddf['CL_1'] = pd.Series(dh.DONCH_L(ddf, signals[1]).shift(1))
    ddf['CS_1'] = pd.Series(dh.DONCH_H(ddf, signals[1]).shift(1))
    ddf['MA1'] = pd.Series(dh.MA(ddf, signals[2]).shift(1))
    ddf['MA2'] = pd.Series(dh.MA(ddf, signals[3]).shift(1))
    ll = mdf.shape[0]
    mdf['pos'] = pd.Series([0] * ll, index=mdf.index)
    mdf['cost'] = pd.Series([0] * ll, index=mdf.index)
    curr_pos = []
    tradeid = 0
    closed_trades = []
    curr_atr = 0
    for idx, dd in enumerate(mdf.index):
        mslice = mdf.ix[dd]
        d = dd.date()
        dslice = ddf.ix[d]
        tot_pos = sum([trade.pos for trade in curr_pos])
        mdf.ix[dd, 'pos'] = tot_pos
        if (idx < start_idx) or np.isnan(dslice.ATR):
            continue
        if len(curr_pos) == 0 and idx < len(mdf.index) - NO_OPEN_POS_PROTECT:
            curr_atr = dslice.ATR
            direction = 0
            up_MA = False
            down_MA = False
            if np.isnan(dslice.MA1) or (dslice.MA1 < dslice.MA2):
                up_MA = True
            if np.isnan(dslice.MA1) or (dslice.MA1 > dslice.MA2):
                down_MA = True
            if (mslice.close >= dslice.OL_1) and up_MA:
                direction = 1
            elif (mslice.close <= dslice.OS_1) and down_MA:
                direction = -1
            pos = direction * unit
            if direction != 0:
                new_pos = strat.TradePos([mslice.contract], [1], pos,
                                         mslice.close, mslice.close -
                                         direction * curr_atr * NN)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + direction * offset, dd)
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                curr_pos.append(new_pos)
                curr_atr = dslice.ATR
        elif (idx >= len(mdf.index) - NO_OPEN_POS_PROTECT):
            if len(curr_pos) > 0:
                for trade_pos in curr_pos:
                    trade_pos.close(
                        mslice.close - misc.sign(trade_pos.pos) * offset, dd)
                    tradeid += 1
                    trade_pos.exit_tradeid = tradeid
                    closed_trades.append(trade_pos)
                    mdf.ix[dd, 'cost'] -= abs(
                        trade_pos.pos) * (offset + mslice.close * tcost)
                curr_pos = []
        else:
            direction = curr_pos[0].direction
            #exit position out of channel
            if (direction == 1 and mslice.close <= dslice.CL_1) or \
                    (direction == -1 and mslice.close >= dslice.CS_1):
                for trade_pos in curr_pos:
                    trade_pos.close(
                        mslice.close - misc.sign(trade_pos.pos) * offset, dd)
                    tradeid += 1
                    trade_pos.exit_tradeid = tradeid
                    closed_trades.append(trade_pos)
                    mdf.ix[dd, 'cost'] -= abs(
                        trade_pos.pos) * (offset + mslice.close * tcost)
                curr_pos = []
            #stop loss position partially
            elif (curr_pos[-1].exit_target - mslice.close) * direction >= 0:
                for trade_pos in curr_pos:
                    if (trade_pos.exit_target - mslice.close) * direction > 0:
                        trade_pos.close(
                            mslice.close - misc.sign(trade_pos.pos) * offset,
                            dd)
                        tradeid += 1
                        trade_pos.exit_tradeid = tradeid
                        closed_trades.append(trade_pos)
                        mdf.ix[dd, 'cost'] -= abs(
                            trade_pos.pos) * (offset + mslice.close * tcost)
                curr_pos = [trade for trade in curr_pos if not trade.is_closed]
            #add positions
            elif (len(curr_pos) <
                  max_pos) and (mslice.close - curr_pos[-1].entry_price
                                ) * direction > curr_atr / max_pos * NN:
                for trade_pos in curr_pos:
                    #trade.exit_target += curr_atr/max_pos*NN * direction
                    trade_pos.exit_target = mslice.close - direction * curr_atr * NN
                new_pos = strat.TradePos(
                    [mslice.contract], [1], direction * unit, mslice.close,
                    mslice.close - direction * curr_atr * NN)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + direction * offset, dd)
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                curr_pos.append(new_pos)
        mdf.ix[dd, 'pos'] = sum([trade.pos for trade in curr_pos])

    (res_pnl, ts) = backtest.get_pnl_stats(mdf, start_equity, marginrate, 'm')
    res_trade = backtest.get_trade_stats(closed_trades)
    res = dict(res_pnl.items() + res_trade.items())
    return (res, closed_trades, ts)