コード例 #1
0
def dual_thrust_sim(mdf, config):
    close_daily = config["close_daily"]
    marginrate = config["marginrate"]
    offset = config["offset"]
    k = config["k"]
    f = config["f"]
    start_equity = config["capital"]
    win = config["win"]
    multiplier = config["m"]
    tcost = config["trans_cost"]
    unit = config["unit"]
    SL = config["stoploss"]
    min_rng = config["min_range"]
    ma_fast = config["MA_fast"]
    ll = mdf.shape[0]
    mdf["min_idx"] = pd.Series(1, index=mdf.index)
    mdf.loc[mdf["min_id"] < 1500, "min_idx"] = 0
    mdf["date_idx"] = mdf.index.date
    xdf = mdf.groupby([mdf["date_idx"], mdf["min_idx"]]).apply(dh.ohlcsum).reset_index().set_index("datetime")
    if win == -1:
        tr = (
            pd.concat([xdf.high - xdf.low, abs(xdf.close - xdf.close.shift(1))], join="outer", axis=1)
            .max(axis=1)
            .shift(1)
        )
    elif win == -2:
        tr = pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.low, 2)
    elif win == 0:
        tr = (
            pd.concat(
                [
                    (pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.close, 2)) * multiplier,
                    (pd.rolling_max(xdf.close, 2) - pd.rolling_min(xdf.low, 2)) * multiplier,
                    xdf.high - xdf.close,
                    xdf.close - xdf.low,
                ],
                join="outer",
                axis=1,
            )
            .max(axis=1)
            .shift(1)
        )
    else:
        tr = (
            pd.concat(
                [
                    pd.rolling_max(xdf.high, win) - pd.rolling_min(xdf.close, win),
                    pd.rolling_max(xdf.close, win) - pd.rolling_min(xdf.low, win),
                ],
                join="outer",
                axis=1,
            )
            .max(axis=1)
            .shift(1)
        )
    xdf["TR"] = tr
    xdf["MA"] = pd.rolling_mean(xdf.close, ma_fast).shift(1)
    ddf = pd.concat(
        [xdf["TR"], xdf["MA"], xdf["open"], xdf["date_idx"]], axis=1, keys=["TR", "MA", "dopen", "date"]
    ).fillna(0)
    mdf = mdf.join(ddf, how="left").fillna(method="ffill")
    mdf["pos"] = pd.Series([0] * ll, index=mdf.index)
    mdf["cost"] = pd.Series([0] * ll, index=mdf.index)
    curr_pos = []
    closed_trades = []
    start_d = ddf.index[0]
    end_d = mdf.index[-1].date()
    # prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, "pos"] = pos
        if mslice.TR == 0 or mslice.MA == 0:
            continue
        d_open = mslice.dopen
        # if (prev_d < d):
        #    d_open = mslice.open
        # else:
        #    d_open = dslice.open
        rng = max(min_rng * d_open, k * mslice.TR)
        if d_open <= 0:
            continue
        buytrig = d_open + rng
        selltrig = d_open - rng
        if mslice.MA > mslice.close:
            buytrig += f * rng
        elif mslice.MA < mslice.close:
            selltrig -= f * rng
        if (min_id >= config["exit_min"]) and (close_daily or (mslice.date == end_d)):
            if 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 = []
                mdf.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
        else:
            if (pos != 0) and (SL > 0):
                curr_pos[0].trail_update(mslice.close)
                if curr_pos[0].trail_check(mslice.close, SL * mslice.close):
                    curr_pos[0].close(mslice.close - offset * misc.sign(pos), 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
            if (mslice.high >= buytrig) and (pos <= 0):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close + 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)
                new_pos = strat.TradePos([mslice.contract], [1], unit, mslice.close + offset, mslice.close + offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset, dd)
                curr_pos.append(new_pos)
                pos = unit
                mdf.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
            elif (mslice.low <= selltrig) and (pos >= 0):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close - 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)
                new_pos = strat.TradePos([mslice.contract], [1], -unit, mslice.close - offset, mslice.close - offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close - offset, dd)
                curr_pos.append(new_pos)
                pos = -unit
                mdf.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
        mdf.ix[dd, "pos"] = 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)
コード例 #2
0
def r_breaker_sim(ddf, mdf, config):
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['k']
    a = k[0]
    b = k[1]
    c = k[2]
    start_equity = config['capital']
    tcost = config['trans_cost']
    unit = config['unit']
    close_daily = config['close_daily']
    ddf['range'] = (ddf.high - ddf.low).shift(1)
    ddf['ssetup'] = (ddf.high + a * (ddf.close - ddf.low)).shift(1)
    ddf['bsetup'] = (ddf.low - a * (ddf.high - ddf.close)).shift(1)
    ddf['senter'] = ((1 + b) * (ddf.high + ddf.close) / 2.0 -
                     b * ddf.low).shift(1)
    ddf['benter'] = ((1 + b) * (ddf.low + ddf.close) / 2.0 -
                     b * ddf.high).shift(1)
    ddf['bbreak'] = ddf.ssetup + c * (ddf.ssetup - ddf.bsetup)
    ddf['sbreak'] = ddf.bsetup - c * (ddf.ssetup - ddf.bsetup)
    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 = ddf.index[0]
    end_d = mdf.index[-1].date()
    prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    cur_high = 0
    cur_low = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        if np.isnan(dslice.bbreak):
            continue
        if (prev_d < d):
            num_trades = 0
            cur_high = mslice.high
            cur_low = mslice.low
        else:
            cur_high = max([cur_high, mslice.high])
            cur_low = min([cur_low, mslice.low])
        prev_d = d
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos
        if (min_id >= config['exit_min']):
            if (pos != 0) and (close_daily or (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 = []
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
        elif (min_id <= config['start_min']):
            continue
        else:
            if num_trades >= 2:
                continue
            if ((cur_high < dslice.bbreak) and (cur_high >= dslice.ssetup) and (mslice.close < dslice.senter) and (pos >=0)) or \
                    ((cur_low > dslice.sbreak)  and (cur_low  <= dslice.bsetup) and (mslice.close > dslice.benter) and (pos <=0)):
                if len(curr_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 = []
                    mdf.ix[dd, 'cost'] -= abs(pos) * (offset +
                                                      mslice.close * tcost)
                new_pos = strat.TradePos([mslice.contract], [1],
                                         -unit * misc.sign(pos), mslice.close,
                                         0)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset * misc.sign(pos), dd)
                curr_pos.append(new_pos)
                pos = -unit * misc.sign(pos)
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                num_trades += 1
            elif ((mslice.close >= dslice.bbreak) or
                  (mslice.close <= dslice.sbreak)) and (pos == 0):
                if (mslice.close >= dslice.bbreak):
                    direction = 1
                else:
                    direction = -1
                new_pos = strat.TradePos([mslice.contract], [1],
                                         unit * direction, mslice.close, 0)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset * misc.sign(direction), dd)
                curr_pos.append(new_pos)
                pos = unit * direction
                mdf.ix[dd, 'cost'] -= abs(direction) * (offset +
                                                        mslice.close * tcost)
                num_trades += 1
        mdf.ix[dd, 'pos'] = 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)
コード例 #3
0
def dual_thrust_sim( ddf, mdf, config):
    close_daily = config['close_daily']
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['k']
    start_equity = config['capital']
    win = config['win']
    multiplier = config['m']
    tcost = config['trans_cost']
    unit = config['unit']
    SL = config['stoploss']
    min_rng = config['min_range']
    if win == -1:
        tr = (ddf.high - ddf.low).shift(1)
    elif win == 0:
        tr = pd.concat([(pd.rolling_max(ddf.high, 2) - pd.rolling_min(ddf.close, 2))*multiplier, 
                        (pd.rolling_max(ddf.close, 2) - pd.rolling_min(ddf.low, 2))*multiplier,
                        ddf.high - ddf.close, 
                        ddf.close - ddf.low], 
                        join='outer', axis=1).max(axis=1).shift(1)
    else:
        tr= pd.concat([pd.rolling_max(ddf.high, win) - pd.rolling_min(ddf.close, win), 
                       pd.rolling_max(ddf.close, win) - pd.rolling_min(ddf.low, win)], 
                       join='outer', axis=1).max(axis=1).shift(1)
    ddf['TR'] = tr
        
    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 = ddf.index[0]
    end_d = mdf.index[-1].date()
    #prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos    
        if np.isnan(dslice.TR):
            continue
        d_open = dslice.open
        #if (prev_d < d):
        #    d_open = mslice.open
        #else:
        #    d_open = dslice.open
        if (d_open <= 0):
            continue
        #prev_d = d
        buytrig  = d_open + max(min_rng, dslice.TR * k)
        selltrig = d_open - max(min_rng, dslice.TR * k)
        
        if (min_id >= config['exit_min']):
            if (pos != 0) and (close_daily or (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 = []
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost) 
                pos = 0
        else:
            if (pos!=0) and (SL>0) and (curr_pos[0].trail_loss(mslice.close, SL*mslice.close)):
                curr_pos[0].close(mslice.close-offset*misc.sign(pos), 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
            if (mslice.close >= buytrig) and (pos <=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close+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)
                new_pos = strat.TradePos([mslice.contract], [1], unit, buytrig, 0)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset, dd)
                curr_pos.append(new_pos)
                pos = unit
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost)
            elif (mslice.close <= selltrig) and (pos >=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close-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)
                new_pos = strat.TradePos([mslice.contract], [1], -unit, selltrig, 0)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close - offset, dd)
                curr_pos.append(new_pos)
                pos = -unit
                mdf.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close*tcost)
        mdf.ix[dd, 'pos'] = 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)
コード例 #4
0
def fisher_swing_sim(df, xdf, config):
    marginrate = config["marginrate"]
    offset = config["offset"]
    win = config["win"]
    start_equity = config["capital"]
    tcost = config["trans_cost"]
    unit = config["unit"]
    fisher = dh.FISHER(xdf, win[0])
    xdf["FISHER_I"] = fisher["FISHER_I"].shift(1)
    xdf = xdf.join(dh.BBANDS_STOP(xdf, win[1], 1.0).shift(1))
    ha_df = dh.HEIKEN_ASHI(xdf, win[2]).shift(1)
    xdf["HAopen"] = ha_df["HAopen"]
    xdf["HAclose"] = ha_df["HAclose"]
    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 = []
    end_d = df.index[-1].date()
    tradeid = 0
    for dd in 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.BBSTOP_lower) or np.isnan(mslice.FISHER_I) or np.isnan(mslice.HAclose):
            continue
        end_trading = (min_id >= config["exit_min"]) and (d == end_d)
        stop_loss = (pos > 0) and ((mslice.close < mslice.BBSTOP_lower) or (mslice.FISHER_I < 0))
        stop_loss = stop_loss or ((pos < 0) and ((mslice.close > mslice.BBSTOP_upper) or (mslice.FISHER_I > 0)))
        start_long = (mslice.FISHER_I > 0) and (mslice.HAclose > mslice.HAopen) and (mslice.BBSTOP_trend > 0)
        start_short = (mslice.FISHER_I < 0) and (mslice.HAclose < mslice.HAopen) and (mslice.BBSTOP_trend < 0)
        if pos != 0:
            if stop_loss or end_trading:
                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 (not end_trading) and (pos == 0):
            if start_long and start_short:
                print "warning: get both long and short signal, something is wrong!"
                print mslice
                continue
            pos = (start_long == True) * unit - (start_short == True) * unit
            if abs(pos) > 0:
                # target = (start_long == True) * mslice.close +(start_short == True) * mslice.close
                new_pos = strat.TradePos([mslice.contract], [1], pos, mslice.close, mslice.close)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + misc.sign(pos) * offset, dd)
                curr_pos.append(new_pos)
                df.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
        df.ix[dd, "pos"] = pos

    (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)
コード例 #5
0
def dual_thrust_sim( ddf, mdf, config):
    close_daily = config['close_daily']
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['k']
    start_equity = config['capital']
    win = config['win']
    multiplier = config['m']
    tcost = config['trans_cost']
    unit = config['unit']
    SL = config['stoploss']
    min_rng = config['min_range']
    if win == -1:
        tr= pd.concat([ddf.high - ddf.low, ddf.close - ddf.close.shift(1)], 
                       join='outer', axis=1).max(axis=1).shift(1)
    elif win == 0:
        tr = pd.concat([(pd.rolling_max(ddf.high, 2) - pd.rolling_min(ddf.close, 2))*multiplier, 
                        (pd.rolling_max(ddf.close, 2) - pd.rolling_min(ddf.low, 2))*multiplier,
                        ddf.high - ddf.close, 
                        ddf.close - ddf.low], 
                        join='outer', axis=1).max(axis=1).shift(1)
    else:
        tr= pd.concat([pd.rolling_max(ddf.high, win) - pd.rolling_min(ddf.close, win), 
                       pd.rolling_max(ddf.close, win) - pd.rolling_min(ddf.low, win)], 
                       join='outer', axis=1).max(axis=1).shift(1)
    ddf['TR'] = tr
    #ddf['prev_high'] = ddf.high.shift(1)
    #ddf['prev_low'] = ddf.low.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 = []
    closed_trades = []
    start_d = ddf.index[0]
    end_d = mdf.index[-1].date()
    prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos    
        if np.isnan(dslice.TR):
            continue
        d_open = dslice.open
        if (prev_d < d):
            d_open = mslice.open
            #d_high = mslice.high
            #d_low =  mslice.low
        else:
            d_open = dslice.open
            #d_high = max(d_high, mslice.high)
            #d_low  = min(d_low, mslice.low)
        if (d_open <= 0):
            continue
        prev_d = d
        buytrig  = d_open + max(min_rng * d_open, dslice.TR * k)
        selltrig = d_open - max(min_rng * d_open, dslice.TR * k)
        #d_high = max(d_high, dslice.prev_high)
        #d_low  = min(d_low, dslice.prev_low)
        if (min_id >= config['exit_min']):
            if (pos != 0) and (close_daily or (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 = []
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost) 
                pos = 0
        else:
            if (pos!=0) and (SL>0):
                curr_pos[0].trail_update(mslice.close)
                if (curr_pos[0].trail_check(mslice.close, SL*mslice.close)):
                    curr_pos[0].close(mslice.close-offset*misc.sign(pos), 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
            if (mslice.high >= buytrig) and (pos <=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close+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)
                new_pos = strat.TradePos([mslice.contract], [1], unit, mslice.close + offset, mslice.close + offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset, dd)
                curr_pos.append(new_pos)
                pos = unit
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost)
            elif (mslice.low <= selltrig) and (pos >=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close-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)
                new_pos = strat.TradePos([mslice.contract], [1], -unit, mslice.close - offset, mslice.close - offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close - offset, dd)
                curr_pos.append(new_pos)
                pos = -unit
                mdf.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close*tcost)
        mdf.ix[dd, 'pos'] = 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)
コード例 #6
0
def dual_thrust_sim( mdf, config):
    close_daily = config['close_daily']
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['k']
    f = config['f']
    start_equity = config['capital']
    win = config['win']
    multiplier = config['m']
    tcost = config['trans_cost']
    unit = config['unit']
    SL = config['stoploss']
    min_rng = config['min_range']
    ma_fast = config['MA_fast']
    ll = mdf.shape[0]
    mdf['min_idx'] = pd.Series(1, index = mdf.index)
    mdf.loc[mdf['min_id']<1500, 'min_idx'] = 0
    mdf['date_idx'] = mdf.index.date
    xdf = mdf.groupby([mdf['date_idx'], mdf['min_idx']]).apply(dh.ohlcsum).reset_index().set_index('datetime')
    if win == -1:
        tr= pd.concat([xdf.high - xdf.low, abs(xdf.close - xdf.close.shift(1))], 
                       join='outer', axis=1).max(axis=1).shift(1)
    elif win == -2:
        tr= pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.low, 2)                       
    elif win == 0:
        tr = pd.concat([(pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.close, 2))*multiplier, 
                        (pd.rolling_max(xdf.close, 2) - pd.rolling_min(xdf.low, 2))*multiplier,
                        xdf.high - xdf.close, 
                        xdf.close - xdf.low], 
                        join='outer', axis=1).max(axis=1).shift(1)
    else:
        tr= pd.concat([pd.rolling_max(xdf.high, win) - pd.rolling_min(xdf.close, win), 
                       pd.rolling_max(xdf.close, win) - pd.rolling_min(xdf.low, win)], 
                       join='outer', axis=1).max(axis=1).shift(1)
    xdf['TR'] = tr
    xdf['MA'] = pd.rolling_mean(xdf.close, ma_fast).shift(1)
    ddf = pd.concat([xdf['TR'], xdf['MA'], xdf['open'], xdf['date_idx']], axis=1, keys=['TR','MA','dopen', 'date']).fillna(0)
    mdf = mdf.join(ddf, how = 'left').fillna(method='ffill')
    mdf['pos'] = pd.Series([0]*ll, index = mdf.index)
    mdf['cost'] = pd.Series([0]*ll, index = mdf.index)
    curr_pos = []
    closed_trades = []
    start_d = ddf.index[0]
    end_d = mdf.index[-1].date()
    #prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos    
        if mslice.TR == 0 or mslice.MA == 0:
            continue
        d_open = mslice.dopen
        #if (prev_d < d):
        #    d_open = mslice.open
        #else:
        #    d_open = dslice.open
        rng = max(min_rng * d_open, k * mslice.TR)
        if (d_open <= 0):
            continue
        buytrig  = d_open + rng
        selltrig = d_open - rng
        if mslice.MA > mslice.close:
            buytrig  += f * rng
        elif mslice.MA < mslice.close:
            selltrig -= f * rng
        if (min_id >= config['exit_min']) and (close_daily or (mslice.date == end_d)):
            if (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 = []
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost) 
                pos = 0
        else:
            if (pos!=0) and (SL>0):
                curr_pos[0].trail_update(mslice.close)
                if (curr_pos[0].trail_check(mslice.close, SL*mslice.close)):
                    curr_pos[0].close(mslice.close-offset*misc.sign(pos), 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
            if (mslice.high >= buytrig) and (pos <=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close+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)
                new_pos = strat.TradePos([mslice.contract], [1], unit, mslice.close + offset, mslice.close + offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset, dd)
                curr_pos.append(new_pos)
                pos = unit
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost)
            elif (mslice.low <= selltrig) and (pos >=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close-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)
                new_pos = strat.TradePos([mslice.contract], [1], -unit, mslice.close - offset, mslice.close - offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close - offset, dd)
                curr_pos.append(new_pos)
                pos = -unit
                mdf.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close*tcost)
        mdf.ix[dd, 'pos'] = 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 dual_thrust_sim( mdf, config):
    ddf = config['ddf']
    close_daily = config['close_daily']
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['param'][0]
    win = config['param'][1]
    multiplier = config['param'][2]
    f = config['param'][3]
    ep_enabled = config['EP']
    start_equity = config['capital']
    chan = config['chan']
    chan_func = config['chan_func']
    tcost = config['trans_cost']
    unit = config['unit']
    SL = config['stoploss']
    min_rng = config['min_range']
    no_trade_set = config['no_trade_set']
    if win == -1:
        tr= pd.concat([ddf.high - ddf.low, ddf.close - ddf.close.shift(1)], 
                       join='outer', axis=1).max(axis=1).shift(1)
    elif win == 0:
        tr = pd.concat([(pd.rolling_max(ddf.high, 2) - pd.rolling_min(ddf.close, 2))*multiplier, 
                        (pd.rolling_max(ddf.close, 2) - pd.rolling_min(ddf.low, 2))*multiplier,
                        ddf.high - ddf.close, 
                        ddf.close - ddf.low], 
                        join='outer', axis=1).max(axis=1).shift(1)
    else:
        tr= pd.concat([pd.rolling_max(ddf.high, win) - pd.rolling_min(ddf.close, win), 
                       pd.rolling_max(ddf.close, win) - pd.rolling_min(ddf.low, win)], 
                       join='outer', axis=1).max(axis=1).shift(1)
    ddf['TR'] = tr
    ddf['H1'] = eval(chan_func['high']['func'])(ddf, chan, **chan_func['high']['args']).shift(1)
    ddf['L1'] = eval(chan_func['low']['func'])(ddf, chan, **chan_func['low']['args']).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 = []
    closed_trades = []
    start_d = ddf.index[0]
    end_d = mdf.index[-1].date()
    prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        if np.isnan(dslice.TR) or (mslice.close == 0):
            continue
        if (mslice.low == 0):
            mslice.low = mslice.close
        if mslice.high >= mslice.open * 1.2:
            mslice.high = mslice.close
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos
        d_open = dslice.open
        if (prev_d < d):
            d_open = mslice.open
            d_high = mslice.high
            d_low =  mslice.low
        else:
            d_open = dslice.open
            d_high = max(d_high, mslice.high)
            d_low  = min(d_low, mslice.low)
        if (d_open <= 0):
            continue
        prev_d = d
        buytrig  = d_open + max(min_rng * d_open, dslice.TR * k)
        selltrig = d_open - max(min_rng * d_open, dslice.TR * k)
        if ep_enabled:
            buytrig = max(buytrig, d_high)
            selltrig = min(selltrig, d_low)
        if (min_id >= config['exit_min']) :
            if (pos != 0) and (close_daily or (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 = []
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost) 
                pos = 0
        elif min_id not in no_trade_set:
            if (pos!=0) and (SL>0):
                curr_pos[0].trail_update(mslice.close)
                if curr_pos[0].check_exit(mslice.close, SL*mslice.close):
                    curr_pos[0].close(mslice.close-offset*misc.sign(pos), 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
            if (mslice.high >= buytrig) and (pos <=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close+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)
                if mslice.high >= dslice.H1:
                    new_pos = strat.TradePos([mslice.contract], [1], unit, mslice.close + offset, mslice.close + offset)
                    tradeid += 1
                    new_pos.entry_tradeid = tradeid
                    new_pos.open(mslice.close + offset, dd)
                    curr_pos.append(new_pos)
                    pos = unit
                    mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost)
            elif (mslice.low <= selltrig) and (pos >=0 ):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close-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)
                if mslice.low <= dslice.L1:
                    new_pos = strat.TradePos([mslice.contract], [1], -unit, mslice.close - offset, mslice.close - offset)
                    tradeid += 1
                    new_pos.entry_tradeid = tradeid
                    new_pos.open(mslice.close - offset, dd)
                    curr_pos.append(new_pos)
                    pos = -unit
                    mdf.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close*tcost)
        mdf.ix[dd, 'pos'] = 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)
コード例 #9
0
def chanbreak_sim(mdf, ddf, config):
    freq = config['freq']
    str_freq = str(freq) + 'Min'
    xdf = dh.conv_ohlc_freq(mdf, str_freq)
    start_equity = config['capital']
    tcost = config['trans_cost']
    unit = config['unit']
    k = config['scaler']
    marginrate = config['marginrate']
    offset = config['offset']
    win = config['win']
    chan_func = config['channel_func']
    upper_chan_func = chan_func[0]
    lower_chan_func = chan_func[1]
    entry_chan = win
    exit_chan = int(entry_chan / k[1])
    xdf['H1'] = upper_chan_func(xdf, entry_chan).shift(1)
    xdf['L1'] = lower_chan_func(xdf, entry_chan).shift(1)
    xdf['H2'] = upper_chan_func(xdf, exit_chan).shift(1)
    xdf['L2'] = lower_chan_func(xdf, exit_chan).shift(1)
    ddf['ATR'] = dh.ATR(ddf, entry_chan)
    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 = []
    end_d = mdf.index[-1].date()
    tradeid = 0
    x_idx = 0
    max_idx = len(xdf.index)
    for idx, dd in enumerate(mdf.index):
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        while (x_idx < max_idx - 1) and (xdf.index[x_idx + 1] < dd):
            x_idx += 1
        xslice = xdf.iloc[x_idx]
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos
        if np.isnan(dslice.ATR):
            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 = []
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
            continue
        else:
            if (pos != 0):
                curr_pos[0].trail_update(mslice.close)
                if curr_pos[0].trail_check(mslice.close, dslice.ATR * k[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])
                    pos = 0
                    curr_pos = []
            if ((mslice.close >= xslice.H2) and
                (pos < 0)) or ((mslice.close <= xslice.L2) 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 = []
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
            if ((mslice.close >= xslice.H1) and
                (pos <= 0)) or ((mslice.close <= xslice.L1) and (pos >= 0)):
                if (pos == 0):
                    target_pos = (mslice.close >= xslice.H1) * unit - (
                        mslice.close <= xslice.L1) * unit
                    new_pos = strat.TradePos([mslice.contract], [1],
                                             target_pos, mslice.close,
                                             mslice.close)
                    tradeid += 1
                    new_pos.entry_tradeid = tradeid
                    new_pos.open(mslice.close + misc.sign(target_pos) * offset,
                                 dd)
                    curr_pos.append(new_pos)
                    mdf.ix[dd,
                           'cost'] -= abs(target_pos) * (offset +
                                                         mslice.close * tcost)
                    mdf.ix[dd, 'pos'] = pos
                else:
                    print "something wrong with position=%s, close =%s, upBnd=%s, lowBnd=%s" % (
                        pos, mslice.close, xslice.H1, xslice.L1)

    (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)
コード例 #10
0
def r_breaker_sim( ddf, mdf, config):
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['k']
    a = k[0]
    b = k[1]
    c = k[2]
    start_equity = config['capital']
    tcost = config['trans_cost']
    unit = config['unit']
    close_daily = config['close_daily']
    ddf['range'] = (ddf.high - ddf.low).shift(1)
    ddf['ssetup'] = (ddf.high+a*(ddf.close - ddf.low)).shift(1)
    ddf['bsetup'] = (ddf.low-a*(ddf.high - ddf.close)).shift(1)
    ddf['senter'] = ((1+b)*(ddf.high+ddf.close)/2.0 - b * ddf.low).shift(1)
    ddf['benter'] = ((1+b)*(ddf.low+ddf.close)/2.0 - b * ddf.high).shift(1)
    ddf['bbreak'] = ddf.ssetup + c * (ddf.ssetup - ddf.bsetup)
    ddf['sbreak'] = ddf.bsetup - c * (ddf.ssetup - ddf.bsetup)
    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 = ddf.index[0]
    end_d = mdf.index[-1].date()
    prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    cur_high = 0
    cur_low = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        if np.isnan(dslice.bbreak):
            continue
        if (prev_d < d):
            num_trades = 0
            cur_high = mslice.high
            cur_low = mslice.low
        else:
            cur_high = max([cur_high, mslice.high])
            cur_low = min([cur_low, mslice.low])
        prev_d = d
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos    
        if (min_id >= config['exit_min']):
            if (pos != 0) and (close_daily or (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 = []
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost) 
                pos = 0
        elif (min_id <= config['start_min']):
            continue
        else:
            if num_trades >=2:
                continue
            if ((cur_high < dslice.bbreak) and (cur_high >= dslice.ssetup) and (mslice.close < dslice.senter) and (pos >=0)) or \
                    ((cur_low > dslice.sbreak)  and (cur_low  <= dslice.bsetup) and (mslice.close > dslice.benter) and (pos <=0)):
                if len(curr_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 = []
                    mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost)
                new_pos = strat.TradePos([mslice.contract], [1], -unit*misc.sign(pos), mslice.close, 0)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset*misc.sign(pos), dd)
                curr_pos.append(new_pos)
                pos = -unit*misc.sign(pos)
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost)
                num_trades += 1
            elif ((mslice.close >= dslice.bbreak) or (mslice.close <= dslice.sbreak)) and (pos == 0):
                if (mslice.close >= dslice.bbreak):
                    direction = 1
                else:
                    direction = -1
                new_pos = strat.TradePos([mslice.contract], [1], unit*direction, mslice.close, 0)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset*misc.sign(direction), dd)
                curr_pos.append(new_pos)
                pos = unit*direction
                mdf.ix[dd, 'cost'] -=  abs(direction) * (offset + mslice.close*tcost)
                num_trades += 1                
        mdf.ix[dd, 'pos'] = 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)
コード例 #11
0
def dual_thrust_sim(mdf, config):
    close_daily = config['close_daily']
    marginrate = config['marginrate']
    offset = config['offset']
    k = config['k']
    f = config['f']
    start_equity = config['capital']
    win = config['win']
    multiplier = config['m']
    tcost = config['trans_cost']
    unit = config['unit']
    SL = config['stoploss']
    min_rng = config['min_range']
    ma_fast = config['MA_fast']
    ll = mdf.shape[0]
    mdf['min_idx'] = pd.Series(1, index=mdf.index)
    mdf.loc[mdf['min_id'] < 1500, 'min_idx'] = 0
    mdf['date_idx'] = mdf.index.date
    xdf = mdf.groupby([mdf['date_idx'], mdf['min_idx']
                       ]).apply(dh.ohlcsum).reset_index().set_index('datetime')
    if win == -1:
        tr = pd.concat(
            [xdf.high - xdf.low,
             abs(xdf.close - xdf.close.shift(1))],
            join='outer',
            axis=1).max(axis=1).shift(1)
    elif win == -2:
        tr = pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.low, 2)
    elif win == 0:
        tr = pd.concat(
            [(pd.rolling_max(xdf.high, 2) - pd.rolling_min(xdf.close, 2)) *
             multiplier,
             (pd.rolling_max(xdf.close, 2) - pd.rolling_min(xdf.low, 2)) *
             multiplier, xdf.high - xdf.close, xdf.close - xdf.low],
            join='outer',
            axis=1).max(axis=1).shift(1)
    else:
        tr = pd.concat([
            pd.rolling_max(xdf.high, win) - pd.rolling_min(xdf.close, win),
            pd.rolling_max(xdf.close, win) - pd.rolling_min(xdf.low, win)
        ],
                       join='outer',
                       axis=1).max(axis=1).shift(1)
    xdf['TR'] = tr
    xdf['MA'] = pd.rolling_mean(xdf.close, ma_fast).shift(1)
    ddf = pd.concat([xdf['TR'], xdf['MA'], xdf['open'], xdf['date_idx']],
                    axis=1,
                    keys=['TR', 'MA', 'dopen', 'date']).fillna(0)
    mdf = mdf.join(ddf, how='left').fillna(method='ffill')
    mdf['pos'] = pd.Series([0] * ll, index=mdf.index)
    mdf['cost'] = pd.Series([0] * ll, index=mdf.index)
    curr_pos = []
    closed_trades = []
    start_d = ddf.index[0]
    end_d = mdf.index[-1].date()
    #prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos
        if mslice.TR == 0 or mslice.MA == 0:
            continue
        d_open = mslice.dopen
        #if (prev_d < d):
        #    d_open = mslice.open
        #else:
        #    d_open = dslice.open
        rng = max(min_rng * d_open, k * mslice.TR)
        if (d_open <= 0):
            continue
        buytrig = d_open + rng
        selltrig = d_open - rng
        if mslice.MA > mslice.close:
            buytrig += f * rng
        elif mslice.MA < mslice.close:
            selltrig -= f * rng
        if (min_id >= config['exit_min']) and (close_daily or
                                               (mslice.date == end_d)):
            if (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 = []
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
        else:
            if (pos != 0) and (SL > 0):
                curr_pos[0].trail_update(mslice.close)
                if (curr_pos[0].trail_check(mslice.close, SL * mslice.close)):
                    curr_pos[0].close(mslice.close - offset * misc.sign(pos),
                                      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
            if (mslice.high >= buytrig) and (pos <= 0):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close + 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)
                new_pos = strat.TradePos([mslice.contract], [1], unit,
                                         mslice.close + offset,
                                         mslice.close + offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset, dd)
                curr_pos.append(new_pos)
                pos = unit
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
            elif (mslice.low <= selltrig) and (pos >= 0):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close - 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)
                new_pos = strat.TradePos([mslice.contract], [1], -unit,
                                         mslice.close - offset,
                                         mslice.close - offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close - offset, dd)
                curr_pos.append(new_pos)
                pos = -unit
                mdf.ix[dd,
                       'cost'] -= abs(pos) * (offset + mslice.close * tcost)
        mdf.ix[dd, 'pos'] = 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)
コード例 #12
0
def fisher_swing_sim(df, xdf, config):
    marginrate = config['marginrate']
    offset = config['offset']
    win = config['win']
    start_equity = config['capital']
    tcost = config['trans_cost']
    unit = config['unit']
    fisher = dh.FISHER(xdf, win[0])
    xdf['FISHER_I'] = fisher['FISHER_I'].shift(1)
    xdf = xdf.join(dh.BBANDS_STOP(xdf, win[1], 1.0).shift(1))
    ha_df = dh.HEIKEN_ASHI(xdf, win[2]).shift(1)
    xdf['HAopen'] = ha_df['HAopen']
    xdf['HAclose'] = ha_df['HAclose']
    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 = []
    end_d = df.index[-1].date()
    tradeid = 0
    for dd in 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.BBSTOP_lower) or np.isnan(
                mslice.FISHER_I) or np.isnan(mslice.HAclose):
            continue
        end_trading = (min_id >= config['exit_min']) and (d == end_d)
        stop_loss = (pos > 0) and ((mslice.close < mslice.BBSTOP_lower) or
                                   (mslice.FISHER_I < 0))
        stop_loss = stop_loss or ((pos < 0) and
                                  ((mslice.close > mslice.BBSTOP_upper) or
                                   (mslice.FISHER_I > 0)))
        start_long = (mslice.FISHER_I > 0) and (
            mslice.HAclose > mslice.HAopen) and (mslice.BBSTOP_trend > 0)
        start_short = (mslice.FISHER_I < 0) and (
            mslice.HAclose < mslice.HAopen) and (mslice.BBSTOP_trend < 0)
        if pos != 0:
            if stop_loss or end_trading:
                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 (not end_trading) and (pos == 0):
            if start_long and start_short:
                print "warning: get both long and short signal, something is wrong!"
                print mslice
                continue
            pos = (start_long == True) * unit - (start_short == True) * unit
            if abs(pos) > 0:
                #target = (start_long == True) * mslice.close +(start_short == True) * mslice.close
                new_pos = strat.TradePos([mslice.contract], [1], pos,
                                         mslice.close, mslice.close)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + misc.sign(pos) * offset, dd)
                curr_pos.append(new_pos)
                df.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close * tcost)
        df.ix[dd, 'pos'] = pos

    (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)
コード例 #13
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)
コード例 #14
0
def dual_thrust_sim(ddf, mdf, config):
    close_daily = config["close_daily"]
    marginrate = config["marginrate"]
    offset = config["offset"]
    k = config["k"]
    start_equity = config["capital"]
    win = config["win"]
    multiplier = config["m"]
    tcost = config["trans_cost"]
    unit = config["unit"]
    SL = config["stoploss"]
    min_rng = config["min_range"]
    no_trade_set = config["no_trade_set"]
    if win == -1:
        tr = pd.concat([ddf.high - ddf.low, ddf.close - ddf.close.shift(1)], join="outer", axis=1).max(axis=1).shift(1)
    elif win == 0:
        tr = (
            pd.concat(
                [
                    (pd.rolling_max(ddf.high, 2) - pd.rolling_min(ddf.close, 2)) * multiplier,
                    (pd.rolling_max(ddf.close, 2) - pd.rolling_min(ddf.low, 2)) * multiplier,
                    ddf.high - ddf.close,
                    ddf.close - ddf.low,
                ],
                join="outer",
                axis=1,
            )
            .max(axis=1)
            .shift(1)
        )
    else:
        tr = (
            pd.concat(
                [
                    pd.rolling_max(ddf.high, win) - pd.rolling_min(ddf.close, win),
                    pd.rolling_max(ddf.close, win) - pd.rolling_min(ddf.low, win),
                ],
                join="outer",
                axis=1,
            )
            .max(axis=1)
            .shift(1)
        )
    ddf["TR"] = tr
    # ddf['prev_high'] = ddf.high.shift(1)
    # ddf['prev_low'] = ddf.low.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 = []
    closed_trades = []
    start_d = ddf.index[0]
    end_d = mdf.index[-1].date()
    prev_d = start_d - datetime.timedelta(days=1)
    tradeid = 0
    for dd in mdf.index:
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        if min_id in no_trade_set or np.isnan(dslice.TR):
            continue

        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, "pos"] = pos
        d_open = dslice.open
        if prev_d < d:
            d_open = mslice.open
            # d_high = mslice.high
            # d_low =  mslice.low
        else:
            d_open = dslice.open
            # d_high = max(d_high, mslice.high)
            # d_low  = min(d_low, mslice.low)
        if d_open <= 0:
            continue
        prev_d = d
        buytrig = d_open + max(min_rng * d_open, dslice.TR * k)
        selltrig = d_open - max(min_rng * d_open, dslice.TR * k)
        # d_high = max(d_high, dslice.prev_high)
        # d_low  = min(d_low, dslice.prev_low)
        if min_id >= config["exit_min"]:
            if (pos != 0) and (close_daily or (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 = []
                mdf.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
                pos = 0
        else:
            if (pos != 0) and (SL > 0):
                curr_pos[0].trail_update(mslice.close)
                if curr_pos[0].trail_check(mslice.close, SL * mslice.close):
                    curr_pos[0].close(mslice.close - offset * misc.sign(pos), 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
            if (mslice.high >= buytrig) and (pos <= 0):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close + 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)
                new_pos = strat.TradePos([mslice.contract], [1], unit, mslice.close + offset, mslice.close + offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close + offset, dd)
                curr_pos.append(new_pos)
                pos = unit
                mdf.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
            elif (mslice.low <= selltrig) and (pos >= 0):
                if len(curr_pos) > 0:
                    curr_pos[0].close(mslice.close - 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)
                new_pos = strat.TradePos([mslice.contract], [1], -unit, mslice.close - offset, mslice.close - offset)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(mslice.close - offset, dd)
                curr_pos.append(new_pos)
                pos = -unit
                mdf.ix[dd, "cost"] -= abs(pos) * (offset + mslice.close * tcost)
        mdf.ix[dd, "pos"] = 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)
コード例 #15
0
def chanbreak_sim( mdf, ddf, config):
    freq = config['freq']
    str_freq = str(freq) + 'Min'
    xdf = dh.conv_ohlc_freq(mdf, str_freq)
    start_equity = config['capital']
    tcost = config['trans_cost']
    unit = config['unit']
    k = config['scaler']
    marginrate = config['marginrate']
    offset = config['offset']
    win = config['win']
    chan_func = config['channel_func']
    upper_chan_func = chan_func[0]
    lower_chan_func = chan_func[1]
    entry_chan = win    
    exit_chan = int(entry_chan/k[1])
    xdf['H1'] = upper_chan_func(xdf, entry_chan).shift(1)
    xdf['L1'] = lower_chan_func(xdf, entry_chan).shift(1)
    xdf['H2'] = upper_chan_func(xdf, exit_chan).shift(1)
    xdf['L2'] = lower_chan_func(xdf, exit_chan).shift(1)
    ddf['ATR'] = dh.ATR(ddf, entry_chan)
    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 = []
    end_d = mdf.index[-1].date()
    tradeid = 0
    x_idx = 0
    max_idx = len(xdf.index)
    for idx, dd in enumerate(mdf.index):
        mslice = mdf.ix[dd]
        min_id = agent.get_min_id(dd)
        d = dd.date()
        dslice = ddf.ix[d]
        while (x_idx<max_idx-1) and (xdf.index[x_idx + 1] < dd):
            x_idx += 1
        xslice = xdf.iloc[x_idx]
        if len(curr_pos) == 0:
            pos = 0
        else:
            pos = curr_pos[0].pos
        mdf.ix[dd, 'pos'] = pos
        if np.isnan(dslice.ATR):
            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 = []
                mdf.ix[dd, 'cost'] -=  abs(pos) * (offset + mslice.close*tcost) 
            continue
        else:
            if (pos !=0):
                curr_pos[0].trail_update(mslice.close)
                if curr_pos[0].trail_check(mslice.close, dslice.ATR*k[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])
                    pos = 0
                    curr_pos = []                    
            if ((mslice.close >= xslice.H2) and (pos<0)) or ((mslice.close <= xslice.L2) 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 = []
                mdf.ix[dd, 'cost'] -= abs(pos) * (offset + mslice.close*tcost)
                pos = 0
            if ((mslice.close>=xslice.H1) and (pos<=0)) or ((mslice.close <= xslice.L1) and (pos>=0)):
                if (pos ==0 ):
                    target_pos = (mslice.close>=xslice.H1) * unit -(mslice.close<=xslice.L1) * unit
                    new_pos = strat.TradePos([mslice.contract], [1], target_pos, mslice.close, mslice.close)
                    tradeid += 1
                    new_pos.entry_tradeid = tradeid
                    new_pos.open(mslice.close + misc.sign(target_pos)*offset, dd)
                    curr_pos.append(new_pos)
                    mdf.ix[dd, 'cost'] -=  abs(target_pos) * (offset + mslice.close*tcost)
                    mdf.ix[dd, 'pos'] = pos
                else:
                    print "something wrong with position=%s, close =%s, upBnd=%s, lowBnd=%s" % ( pos, mslice.close, xslice.H1, xslice.L1)
            
    (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)
コード例 #16
0
	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()
        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 >=2054):
			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 = []