示例#1
0
def test():
    xdf = tstool.get_cont_data('rb1701', datetime.date(2016,1,1), datetime.date(2016,8,19), freq = '30m', nearby = 0, rollrule = '-10b')
    xdf['WPR'] = dh.WPR(xdf, 9)
    xdf["SAR"] = dh.SAR(xdf, incr = 0.01, maxaf = 0.1)
    xdf['RSI'] = dh.RSI(xdf, 14)
    xdf['MA10'] = dh.MA(xdf, 10)
    xdf['MA120'] = dh.MA(xdf, 120)
    ind_fields = [['SAR'], \
                  ['WPR', 'RSI'], \
                  ['close', 'MA10', 'MA120']]
    ind_levels = [[],\
                  [70, 30],\
                  []]
    plot_indicators(xdf, ind_fields, ind_levels)
示例#2
0
 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['ATR'] = dh.ATR(xdf, n=self.atr_len)
     xdf['ATRMA'] = dh.MA(xdf, n=self.atrma_len, field='ATR')
     xdf['RSI'] = dh.RSI(xdf, n=self.rsi_len)
     self.df = xdf
     self.df['datetime'] = self.df.index
     self.df['cost'] = 0.0
     self.df['pos'] = 0.0
     self.df['traded_price'] = self.df['open']
示例#3
0
 def process_data(self, mdf):
     xdf = self.proc_func(mdf, **self.proc_args)
     if self.win == -1:
         tr = pd.concat(
             [xdf.high - xdf.low,
              abs(xdf.close - xdf.close.shift(1))],
             join='outer',
             axis=1).max(axis=1)
     elif self.win == 0:
         tr = pd.concat(
             [(pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.close, 2)) *
              self.multiplier,
              (pd.rolling_max(xdf.close, 2) - pd.rolling_min(xdf.low, 2)) *
              self.multiplier, xdf.high - xdf.close, xdf.close - xdf.low],
             join='outer',
             axis=1).max(axis=1)
     else:
         tr = pd.concat([
             pd.rolling_max(xdf.high, self.win) -
             pd.rolling_min(xdf.close, self.win),
             pd.rolling_max(xdf.close, self.win) -
             pd.rolling_min(xdf.low, self.win)
         ],
                        join='outer',
                        axis=1).max(axis=1)
     xdf['TR'] = tr
     xdf['chanh'] = self.chan_high(xdf['high'], self.chan,
                                   **self.chan_func['high']['args'])
     xdf['chanl'] = self.chan_low(xdf['low'], self.chan,
                                  **self.chan_func['low']['args'])
     xdf['ATR'] = dh.ATR(xdf, n=self.atr_len)
     xdf['MA'] = dh.MA(xdf, n=self.atr_len, field='close')
     xdata = pd.concat([
         xdf['TR'].shift(1), xdf['MA'].shift(1), xdf['ATR'].shift(1),
         xdf['chanh'].shift(1), xdf['chanl'].shift(1), xdf['open']
     ],
                       axis=1,
                       keys=['tr', 'ma', 'atr', 'chanh', 'chanl',
                             'dopen']).fillna(0)
     self.df = mdf.join(xdata, how='left').fillna(method='ffill')
     self.df['datetime'] = self.df.index
     self.df['cost'] = 0
     self.df['pos'] = 0
     self.df['traded_price'] = self.df['open']
def bband_chan_sim(mdf, config):
    start_equity = config['capital']
    marginrate = config['marginrate']
    offset = config['offset']
    pos_class = config['pos_class']
    pos_args = config['pos_args']
    param = config['param']
    #tick_base = config['tick_base']
    close_daily = config['close_daily']
    win = param[0]
    k = param[1]
    chan = param[2]
    if chan > 0:
        chan_func = config['chan_func']
    tcost = config['trans_cost']
    filter_func = config['filter_func']['func']
    filter_args = config['filter_func']['args']
    filter_param = config['filter_func']['param']
    unit = config['unit']
    freq = config['freq']
    xdf = dh.conv_ohlc_freq(mdf, freq)
    xdf['boll_ma'] = dh.MA(xdf, win).shift(1)
    boll_std = dh.STDEV(xdf, win).shift(1)
    xdf['upbnd'] = xdf['boll_ma'] + boll_std * k
    xdf['lowbnd'] = xdf['boll_ma'] - boll_std * k
    if chan > 0:
        xdf['chan_h'] = eval(chan_func['high']['func'])(
            xdf, chan, **chan_func['high']['args']).shift(1)
        xdf['chan_l'] = eval(chan_func['low']['func'])(
            xdf, chan, **chan_func['low']['args']).shift(1)
    else:
        xdf['chan_h'] = 0
        xdf['chan_l'] = 10000000
    xdf['high_band'] = xdf[['chan_h', 'upbnd']].max(axis=1)
    xdf['low_band'] = xdf[['chan_l', 'lowbnd']].min(axis=1)
    xdf['filter'] = eval(filter_func)(xdf, filter_param[0], **filter_args)
    xdf['filter_ma'] = pd.rolling_mean(xdf['filter'], filter_param[1])
    xdf['filter_ind'] = xdf['filter_ma'] >= filter_param[2]
    xdf['prev_close'] = xdf['close'].shift(1)
    xdf['close_ind'] = np.isnan(xdf['close'].shift(-1))
    if close_daily:
        daily_end = (xdf['date'] != xdf['date'].shift(-1))
        xdf['close_ind'] = xdf['close_ind'] | daily_end
    ll = xdf.shape[0]
    xdf['pos'] = 0
    xdf['cost'] = 0
    xdf['traded_price'] = xdf.open
    curr_pos = []
    closed_trades = []
    tradeid = 0
    for idx, dd in enumerate(xdf.index):
        mslice = xdf.loc[dd]
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        xdf.set_value(dd, 'pos', pos)
        if np.isnan(mslice.boll_ma) or np.isnan(mslice.chan_h):
            continue
        if mslice.close_ind:
            if pos != 0:
                curr_pos[0].close(mslice.open - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                xdf.set_value(
                    dd, 'cost',
                    xdf.at[dd, 'cost'] - abs(pos) * (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open - misc.sign(pos) * offset)
                pos = 0
        else:
            if ((mslice.open > mslice.boll_ma) and
                (pos < 0)) or ((mslice.open < mslice.boll_ma) and (pos > 0)):
                curr_pos[0].close(mslice.open - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                xdf.set_value(
                    dd, 'cost',
                    xdf.at[dd, 'cost'] - abs(pos) * (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open - misc.sign(pos) * offset)
                pos = 0
            if ((mslice.open >= mslice.high_band) or
                (mslice.open <= mslice.low_band)) and (pos == 0):
                target_pos = (mslice.open >= mslice.high_band) * unit - (
                    mslice.open <= mslice.low_band) * unit
                new_pos = pos_class([mslice.contract], [1], target_pos,
                                    mslice.open, mslice.open, **pos_args)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.open + misc.sign(target_pos) * offset, dd)
                curr_pos.append(new_pos)
                pos = target_pos
                xdf.set_value(
                    dd, 'cost', xdf.at[dd, 'cost'] - abs(target_pos) *
                    (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open + misc.sign(target_pos) * offset)
        xdf.set_value(dd, 'pos', pos)
    return (xdf, closed_trades)
def turtle_sim(mdf, config):
    ddf = config['ddf']
    marginrate = config['marginrate']
    offset = config['offset']
    start_equity = config['capital']
    tcost = config['trans_cost']
    chan = config['chan']
    unit = config['unit']
    param = config['param']
    max_pos = param[1]
    max_loss = param[0]
    ma_ratio = config['ma_ratio']
    use_ma = config['use_ma']
    chan_func = config['chan_func']
    pos_update = config['pos_update']
    ddf['ATR'] = dh.ATR(ddf, n=chan[0]).shift(1)
    ddf['OL_1'] = eval(chan_func['high']['func'])(ddf, chan[0]).shift(1)
    ddf['OS_1'] = eval(chan_func['low']['func'])(ddf, chan[0]).shift(1)
    ddf['CL_1'] = eval(chan_func['low']['func'])(ddf, chan[1]).shift(1)
    ddf['CS_1'] = eval(chan_func['high']['func'])(ddf, chan[1]).shift(1)
    ddf['MA1'] = dh.MA(ddf, ma_ratio * chan[0]).shift(1)
    ddf['MA2'] = dh.MA(ddf, chan[1]).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 = []
    end_d = mdf.index[-1].date()
    curr_atr = 0
    for idx, dd in enumerate(mdf.index):
        mslice = mdf.ix[dd]
        min_id = mslice.min_id
        d = mslice.date
        dslice = ddf.ix[d]
        tot_pos = sum([trade.pos for trade in curr_pos])
        mdf.ix[dd, 'pos'] = tot_pos
        if np.isnan(dslice.ATR):
            continue
        if (min_id >= config['exit_min']):
            if (tot_pos != 0) and (d == end_d):
                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 = []
                tot_pos = 0
        else:
            if tot_pos == 0:
                curr_atr = dslice.ATR
                direction = 0
                dol = dslice.OL_1
                dos = dslice.OS_1
                if (mslice.close >= dol) and ((use_ma == False) or
                                              (mslice.MA1 >= mslice.MA2)):
                    direction = 1
                elif (mslice.close <= dos) and ((use_ma == False) or
                                                (mslice.MA1 <= mslice.MA2)):
                    direction = -1
                pos = direction * unit
                if direction != 0:
                    new_pos = strat.TradePos([mslice.contract], [1], pos,
                                             mslice.close, mslice.close)
                    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)
            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].check_exit(mslice.close,
                                             curr_atr * max_loss):
                    for trade_pos in curr_pos:
                        if trade_pos.check_exit(mslice.close,
                                                curr_atr * max_loss):
                            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 * max_loss:
                    for trade_pos in curr_pos:
                        #trade.exit_target += curr_atr/max_pos*max_loss * direction
                        trade_pos.set_exit(mslice.close)
                    new_pos = strat.TradePos([mslice.contract], [1],
                                             direction * unit, mslice.close,
                                             mslice.close)
                    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)
                if (len(curr_pos) > 0) and pos_update:
                    for trade_pos in curr_pos:
                        trade_pos.update_price(mslice.close)
        mdf.ix[dd, 'pos'] = sum([trade.pos for trade in curr_pos])
    return (mdf, closed_trades)
示例#6
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)
示例#7
0
def aberration_sim(df, config):
    marginrate = config['marginrate']
    offset = config['offset']
    win = config['win']
    start_equity = config['capital']
    tcost = config['trans_cost']
    unit = config['unit']
    k = config['scaler']
    df['ma'] = dh.MA(df, win).shift(1)
    std = dh.STDDEV(df, win).shift(1)
    df['upbnd'] = df['ma'] + std * k[0]
    df['lowbnd'] = df['ma'] - std * k[0]
    ll = df.shape[0]
    df['pos'] = pd.Series([0] * ll, index=df.index)
    df['cost'] = pd.Series([0] * ll, index=df.index)
    curr_pos = []
    closed_trades = []
    start_d = df.index[0].date()
    end_d = df.index[-1].date()
    tradeid = 0
    for idx, dd in enumerate(df.index):
        mslice = df.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        df.ix[dd, 'pos'] = pos
        if np.isnan(mslice.ma):
            continue
        if (min_id >= config['exit_min']):
            if (pos != 0) and (d == end_d):
                curr_pos[0].close(mslice.close - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                df.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close * tcost)
            continue
        else:
            if ((mslice.close >= mslice.ma) and
                (pos < 0)) or (mslice.close <= mslice.ma) and (pos > 0):
                curr_pos[0].close(mslice.close - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                df.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
            if (mslice.close >= mslice.upbnd) or (mslice.close <=
                                                  mslice.lowbnd):
                if (pos == 0):
                    target_pos = (mslice.close >= mslice.upbnd) * unit - (
                        mslice.close <= mslice.lowbnd) * unit
                    target = (mslice.close >= mslice.upbnd) * mslice.upbnd + (
                        mslice.close <= mslice.lowbnd) * mslice.lowbnd
                    new_pos = strat.TradePos([mslice.contract], [1],
                                             target_pos, target, mslice.upbnd +
                                             mslice.lowbnd - target)
                    tradeid += 1
                    new_pos.entry_tradeid = tradeid
                    new_pos.open(mslice.close + misc.sign(target_pos) * offset,
                                 dd)
                    curr_pos.append(new_pos)
                    df.ix[dd,
                          'cost'] -= abs(target_pos) * (offset +
                                                        mslice.close * tcost)
                    df.ix[dd, 'pos'] = pos
                else:
                    print "something wrong with position=%s, close =%s, MA=%s, upBnd=%s, lowBnd=%s" % (
                        pos, mslice.close, mslice.ma, mslice.upbnd,
                        mslice.lowbnd)

    (res_pnl, ts) = backtest.get_pnl_stats(df, 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)
示例#8
0
def bband_chan_sim(mdf, config):
    offset = config['offset']
    pos_class = config['pos_class']
    pos_args = config['pos_args']
    pos_update = config.get('pos_update', False)
    stoploss = config.get('stoploss', 0.0)
    param = config['param']
    bar_func = config.get('bar_conv_func', 'dh.bar_conv_func2')
    bar_func = eval(bar_func)
    std_func = eval(config['std_func'])
    #tick_base = config['tick_base']
    close_daily = config['close_daily']
    win = param[0]
    k = param[1]
    chan = param[2]
    stop_ratio = config.get('exit_stop', 0.0)
    k_e = k * stop_ratio
    if chan > 0:
        chan_func = config['chan_func']
    tcost = config['trans_cost']
    unit = config['unit']
    freq = config['freq']
    xdf = dh.conv_ohlc_freq(mdf,
                            freq,
                            extra_cols=['contract'],
                            bar_func=bar_func)
    xdf['boll_ma'] = dh.MA(xdf, win).shift(1)
    xdf['boll_std'] = std_func(xdf, win).shift(1)
    xdf['upbnd'] = xdf['boll_ma'] + xdf['boll_std'] * k
    xdf['lowbnd'] = xdf['boll_ma'] - xdf['boll_std'] * k
    xdf['up_exit'] = xdf['boll_ma'] + xdf['boll_std'] * k_e
    xdf['dn_exit'] = xdf['boll_ma'] - xdf['boll_std'] * k_e
    if chan > 0:
        xdf['chan_h'] = eval(chan_func['high']['func'])(
            xdf, chan, **chan_func['high']['args']).shift(2)
        xdf['chan_l'] = eval(chan_func['low']['func'])(
            xdf, chan, **chan_func['low']['args']).shift(2)
    else:
        xdf['chan_h'] = -10000000
        xdf['chan_l'] = 10000000
    xdf['high_band'] = xdf[['chan_h', 'upbnd']].max(axis=1)
    xdf['low_band'] = xdf[['chan_l', 'lowbnd']].min(axis=1)
    xdf['prev_close'] = xdf['close'].shift(1)
    xdf['close_ind'] = np.isnan(xdf['close'].shift(-1))
    if close_daily:
        daily_end = (xdf['date'] != xdf['date'].shift(-1))
        xdf['close_ind'] = xdf['close_ind'] | daily_end
    long_signal = pd.Series(np.nan, index=xdf.index)
    long_signal[(xdf['open'] >= xdf['high_band'])
                & (xdf['boll_ma'].notnull())] = 1
    long_signal[(xdf['open'] <= xdf['dn_exit'])
                & (xdf['boll_ma'].notnull())] = 0
    long_signal[xdf['close_ind']] = 0
    long_signal = long_signal.fillna(method='ffill').fillna(0)
    short_signal = pd.Series(np.nan, index=xdf.index)
    short_signal[(xdf['open'] <= xdf['low_band'])
                 & (xdf['boll_ma'].notnull())] = -1
    short_signal[(xdf['open'] >= xdf['up_exit'])
                 & (xdf['boll_ma'].notnull())] = 0
    short_signal[xdf['close_ind']] = 0
    short_signal = short_signal.fillna(method='ffill').fillna(0)
    if len(xdf[(long_signal > 0) & (short_signal < 0)]) > 0:
        print xdf[(long_signal > 0) & (short_signal < 0)]
        print "something wrong with the position as long signal and short signal happen the same time"
    xdf['pos'] = long_signal + short_signal
    xdf['cost'] = abs(xdf['pos'] - xdf['pos'].shift(1)) * (offset +
                                                           xdf['open'] * tcost)
    xdf['cost'] = xdf['cost'].fillna(0.0)
    xdf['traded_price'] = xdf.open + (xdf['pos'] -
                                      xdf['pos'].shift(1)) * offset
    closed_trades = backtest.simdf_to_trades1(xdf, slippage=offset)
    return (xdf, closed_trades)
示例#9
0
def aberration_sim(mdf, config):
    start_equity = config['capital']
    marginrate = config['marginrate']
    offset = config['offset']
    pos_class = config['pos_class']
    pos_args = config['pos_args']
    param = config['param']
    tick_base = config['tick_base']
    close_daily = config['close_daily']
    win = param[0]
    k = param[1]
    chan = param[2]
    if chan > 0:
        chan_func = config['chan_func']
    tcost = config['trans_cost']
    unit = config['unit']
    freq = config['freq']
    #freq_min = int(freq[:-3])
    mode = config.get('mode', 'close')
    xdf = dh.conv_ohlc_freq(mdf, freq)
    boll_ma = dh.MA(xdf, win).shift(1)
    boll_std = dh.STDDEV(xdf, win).shift(1)
    upbnd = np.ceil((boll_ma + boll_std * k) / tick_base) * tick_base
    lowbnd = np.floor((boll_ma - boll_std * k) / tick_base) * tick_base
    boll_ma = np.floor(boll_ma / tick_base + 0.5) * tick_base
    xdata = [boll_ma, boll_std, upbnd, lowbnd, xdf['min_id']]
    xkeys = ['ma', 'stdev', 'upbnd', 'lowbnd', 'xmin_id']
    if chan > 0:
        chan_h = eval(chan_func['high']['func'])(xdf, chan,
                                                 **chan_func['high']['args'])
        chan_l = eval(chan_func['low']['func'])(xdf, chan,
                                                **chan_func['low']['args'])
        xdata = xdata + [chan_h, chan_l]
        xkeys = xkeys + ['chan_h', 'chan_l']
    xdf = pd.concat(xdata, axis=1, keys=xkeys).fillna(0)
    mdf = mdf.join(xdf, how='left').fillna(method='ffill')
    mdf['is_new'] = (mdf['xmin_id'].shift(1) != mdf['xmin_id'])
    ll = mdf.shape[0]
    mdf['pos'] = pd.Series([0] * ll, index=mdf.index)
    mdf['cost'] = pd.Series([0] * ll, index=mdf.index)
    curr_pos = []
    closed_trades = []
    start_d = mdf.date[0]
    end_d = mdf.date[-1]
    tradeid = 0
    for idx, dd in enumerate(mdf.index):
        mslice = mdf.ix[dd]
        min_id = mslice.min_id
        d = mslice.date
        if len(curr_pos) == 0:
            pos = 0
            start_pos = 0
        else:
            pos = curr_pos[0].pos
            start_pos = pos
        mdf.ix[dd, 'pos'] = pos
        if mslice.ma == 0:
            continue
        upbnd = mslice.upbnd
        lowbnd = mslice.lowbnd
        if chan > 0:
            if mslice.chan_h == 0:
                continue
            else:
                upbnd = max(mslice.chan_h, upbnd)
                lowbnd = min(mslice.chan_l, lowbnd)
        if min_id >= config['exit_min']:
            if (pos != 0) and ((d == end_d) or close_daily):
                curr_pos[0].close(mslice.close - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
        else:
            if mode == 'close':
                high_trig = mslice.close
                low_trig = mslice.close
                trade_price = mslice.close
            else:
                high_trig = mslice.high
                low_trig = mslice.low
                trade_price = mslice.open
            if ((high_trig >= mslice.ma) and
                (pos < 0)) or ((low_trig <= mslice.ma) and (pos > 0)):
                if pos < 0:
                    exec_price = max(trade_price, mslice.ma)
                else:
                    exec_price = min(trade_price, mslice.ma)
                curr_pos[0].close(exec_price - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                mdf.ix[dd, 'cost'] -= abs(pos) * (offset + exec_price * tcost)
                pos = 0
            if ((high_trig > upbnd) and (pos <= 0)) or ((low_trig < lowbnd) and
                                                        (pos >= 0)):
                target_pos = (high_trig > upbnd) * unit - (low_trig <
                                                           lowbnd) * unit
                if target_pos == 0:
                    print "the min bar hit both up and low bounds, need to think about how to handle it", start_pos, mslice
                    if mslice.close > mslice.ma:
                        target_pos = (high_trig > upbnd) * unit
                        target = max(trade_price, upbnd)
                    else:
                        trade_pos = -(low_trig < lowbnd) * unit
                        target = min(trade_price, lowbnd)
                else:
                    target = (high_trig > upbnd) * max(trade_price, upbnd) + (
                        low_trig < lowbnd) * min(trade_price, lowbnd)
                new_pos = pos_class([mslice.contract], [1], target_pos, target,
                                    target, **pos_args)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(target + misc.sign(target_pos) * offset, dd)
                curr_pos.append(new_pos)
                pos = target_pos
                mdf.ix[dd,
                       'cost'] -= abs(target_pos) * (offset + target * tcost)
        mdf.ix[dd, 'pos'] = pos
    return (mdf, closed_trades)
def bband_chan_sim(mdf, config):
    offset = config['offset']
    pos_class = config['pos_class']
    pos_args = config['pos_args']
    pos_update = config.get('pos_update', False)
    stoploss = config.get('stoploss', 0.0)
    param = config['param']
    bar_func = eval(config['bar_conv_func'])
    std_func = eval(config['std_func'])
    #tick_base = config['tick_base']
    close_daily = config['close_daily']
    win = param[0]
    k = param[1]
    chan = param[2]
    stop_ratio = config.get('exit_stop', 0.0)
    k_e = k * stop_ratio
    if chan > 0:
        chan_func = config['chan_func']
    tcost = config['trans_cost']
    unit = config['unit']
    freq = config['freq']
    xdf = dh.conv_ohlc_freq(mdf,
                            freq,
                            extra_cols=['contract'],
                            bar_func=bar_func)
    xdf['boll_ma'] = dh.MA(xdf, win).shift(1)
    xdf['boll_std'] = std_func(xdf, win).shift(1)
    xdf['upbnd'] = xdf['boll_ma'] + xdf['boll_std'] * k
    xdf['lowbnd'] = xdf['boll_ma'] - xdf['boll_std'] * k
    xdf['up_exit'] = xdf['boll_ma'] + xdf['boll_std'] * k_e
    xdf['dn_exit'] = xdf['boll_ma'] - xdf['boll_std'] * k_e
    if chan > 0:
        xdf['chan_h'] = eval(chan_func['high']['func'])(
            xdf, chan, **chan_func['high']['args']).shift(2)
        xdf['chan_l'] = eval(chan_func['low']['func'])(
            xdf, chan, **chan_func['low']['args']).shift(2)
    else:
        xdf['chan_h'] = 0
        xdf['chan_l'] = 10000000
    xdf['high_band'] = xdf[['chan_h', 'upbnd']].max(axis=1)
    xdf['low_band'] = xdf[['chan_l', 'lowbnd']].min(axis=1)
    xdf['prev_close'] = xdf['close'].shift(1)
    xdf['close_ind'] = np.isnan(xdf['close'].shift(-1))
    if close_daily:
        daily_end = (xdf['date'] != xdf['date'].shift(-1))
        xdf['close_ind'] = xdf['close_ind'] | daily_end
    ll = xdf.shape[0]
    xdf['pos'] = 0
    xdf['cost'] = 0
    xdf['traded_price'] = xdf.open
    curr_pos = []
    closed_trades = []
    tradeid = 0
    for idx, dd in enumerate(xdf.index):
        mslice = xdf.loc[dd]
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        xdf.set_value(dd, 'pos', pos)
        if np.isnan(mslice.boll_ma) or np.isnan(mslice.chan_h):
            continue
        if mslice.close_ind:
            if pos != 0:
                curr_pos[0].close(mslice.open - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                xdf.set_value(
                    dd, 'cost',
                    xdf.at[dd, 'cost'] - abs(pos) * (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open - misc.sign(pos) * offset)
                pos = 0
        else:
            if ((mslice.open > mslice.up_exit) and
                (pos < 0)) or ((mslice.open < mslice.dn_exit) and (pos > 0)):
                curr_pos[0].close(mslice.open - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                xdf.set_value(
                    dd, 'cost',
                    xdf.at[dd, 'cost'] - abs(pos) * (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open - misc.sign(pos) * offset)
                pos = 0
            if ((mslice.open >= mslice.high_band) or
                (mslice.open <= mslice.low_band)) and (pos == 0):
                target_pos = (mslice.open >= mslice.high_band) * unit - (
                    mslice.open <= mslice.low_band) * unit
                new_pos = pos_class([mslice.contract], [1], target_pos,
                                    mslice.open, mslice.open, **pos_args)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.open + misc.sign(target_pos) * offset, dd)
                curr_pos.append(new_pos)
                pos = target_pos
                xdf.set_value(
                    dd, 'cost', xdf.at[dd, 'cost'] - abs(target_pos) *
                    (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open + misc.sign(target_pos) * offset)
        if pos_update and pos != 0:
            if curr_pos[0].check_exit(mslice.open, stoploss * mslice.boll_std):
                curr_pos[0].close(mslice.open - misc.sign(pos) * offset, dd)
                tradeid += 1
                curr_pos[0].exit_tradeid = tradeid
                closed_trades.append(curr_pos[0])
                curr_pos = []
                xdf.set_value(
                    dd, 'cost',
                    xdf.at[dd, 'cost'] - abs(pos) * (mslice.open * tcost))
                xdf.set_value(dd, 'traded_price',
                              mslice.open - misc.sign(pos) * offset)
                pos = 0
            else:
                curr_pos[0].update_bar(mslice)
        xdf.set_value(dd, 'pos', pos)
    return (xdf, closed_trades)
示例#11
0
            trades.to_csv(fname)
            fname = file_prefix + str(idx) + '_dailydata.csv'
            ts.to_csv(fname)
    fname = file_prefix + 'stats.csv'
    res = pd.DataFrame.from_dict(output)
    res.to_csv(fname)
    return 

def aberration_sim( xdf, mdf, config):
    marginrate = config['marginrate']
    offset = config['offset']
	win = config['win']
    start_equity = config['capital']
    tcost = config['trans_cost']
	unit = config['unit']
    df['ma'] = dh.MA(df, win).shift(1)
	std = dh.STDDEV(df, win).shift(1)
	df['upbnd'] = df['ma'] + std
	df['lowbnd'] = df['ma'] - std
    ll = df.shape[0]
    df['pos'] = pd.Series([0]*ll, index = mdf.index)
    df['cost'] = pd.Series([0]*ll, index = mdf.index)
    curr_pos = []
    closed_trades = []
    start_d = df.index[0].date()
    end_d = df.index[-1].date()
    tradeid = 0
    for idx, dd in enumerate(df.index):
        mslice = df.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()