Beispiel #1
0
def get_results_4ticker(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    candle_frame = qd.get_continuous_bar_data(ticker=ticker, date_to=date_to, num_days_back=0)

    history_frame = gfp.get_futures_price_preloaded(ticker=ticker, settle_date_to=date_to)
    history_frame = history_frame.iloc[:-1]
    history_frame['ma9'] = history_frame['close_price'].rolling(window=9, center=False).mean()

    high_1 = history_frame['high_price'].iloc[-1]
    low_1 = history_frame['low_price'].iloc[-1]

    trend_direction = 0

    if history_frame['ma9'].iloc[-1] > history_frame['ma9'].iloc[-2]:
        trend_direction = 1
    elif history_frame['ma9'].iloc[-1] < history_frame['ma9'].iloc[-2]:
        trend_direction = -1
def get_crossover_duration(**kwargs):

    if 'boto_client' in kwargs.keys():
        boto_client = kwargs['boto_client']
    else:
        boto_client = qgd.get_boto_client()

    data_out = qgd.get_continuous_bar_data(ticker=kwargs['ticker'],
                                           date_to=kwargs['date_to'],
                                           num_days_back=20,
                                           boto_client=boto_client)

    data_out['ema10'] = data_out['close'].ewm(span=10,
                                              min_periods=6,
                                              adjust=False).mean()
    data_out['ema30'] = data_out['close'].ewm(span=30,
                                              min_periods=18,
                                              adjust=False).mean()

    data_out['ema10_30'] = data_out['ema10'] - data_out['ema30']
    data_out['ema10_30_1'] = data_out['ema10_30'].shift(1)

    clean_data = data_out[data_out['ema10_30'].notnull()
                          & data_out['ema10_30_1'].notnull()]
    crossover_index = np.sign(clean_data['ema10_30_1']) != np.sign(
        clean_data['ema10_30'])
    clean_data['num_obs'] = range(len(clean_data.index))

    crossover_data = clean_data[crossover_index]
    crossover_data['crossover_duration'] = crossover_data['num_obs'].diff()
    quantile_out = crossover_data['crossover_duration'].quantile([0.25, 0.75])

    return {
        'mean_duration': crossover_data['crossover_duration'].mean(),
        'duration_25': quantile_out[0.25],
        'duration_75': quantile_out[0.75],
        'num_crossovers': len(crossover_data.index)
    }
Beispiel #3
0
def get_results_4ticker(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    ticker_frame = gfp.get_futures_price_preloaded(ticker=ticker,
                                                   settle_date_to=date_to)
    ticker_frame['close_diff'] = ticker_frame['close_price'].diff()
    daily_sd = np.std(ticker_frame['close_diff'].iloc[-41:-1])

    ticker_frame['ma50'] = ticker_frame['close_price'].rolling(
        window=50, center=False).mean()
    ticker_frame['ma200'] = ticker_frame['close_price'].rolling(
        window=200, center=False).mean()

    if ticker_frame['close_price'].iloc[-2] > ticker_frame['ma50'].iloc[-2]:
        trend1 = 1
    else:
        trend1 = -1

    if ticker_frame['ma50'].iloc[-2] > ticker_frame['ma200'].iloc[-2]:
        trend2 = 1
    else:
        trend2 = -1

    candle_frame = qd.get_continuous_bar_data(ticker=ticker,
                                              date_to=date_to,
                                              num_days_back=20)

    ticker_head = cmi.get_contract_specs(ticker)['ticker_head']

    candle_frame['ewma300'] = candle_frame['close'].ewm(
        span=300, min_periods=250, adjust=True, ignore_na=False).mean()
    candle_frame['ewma50'] = candle_frame['close'].ewm(span=50,
                                                       min_periods=40,
                                                       adjust=True,
                                                       ignore_na=False).mean()
    candle_frame['ma5'] = candle_frame['close'].rolling(window=5,
                                                        center=False).mean()

    candle_frame['ewma300D'] = candle_frame['ewma300'] - candle_frame[
        'ewma300'].shift(60)
    candle_frame['ewma300DN'] = candle_frame['ewma300D'] / daily_sd
    candle_frame[
        'ewma50D'] = candle_frame['ewma50'] - candle_frame['ewma50'].shift(10)

    candle_frame['min14'] = candle_frame['low'].rolling(window=14,
                                                        center=False).min()
    candle_frame['max14'] = candle_frame['high'].rolling(window=14,
                                                         center=False).max()

    candle_frame['william'] = -100 * (
        candle_frame['max14'] - candle_frame['close']) / (
            candle_frame['max14'] - candle_frame['min14'])
    candle_frame['datetime'] = [
        x.replace(hour=0, second=0, minute=0) for x in candle_frame.index
    ]

    candle_frame['obs_no'] = range(len(candle_frame.index))

    candle_frame['bullishW'] = candle_frame['william'] > -20
    candle_frame['bearishW'] = candle_frame['william'] < -80

    candle_frame['bullishW'] = candle_frame['bullishW'].astype(int)
    candle_frame['bearishW'] = candle_frame['bearishW'].astype(int)

    candle_frame = candle_frame[np.isfinite(candle_frame['ewma300D'])]
    candle_frame['ewma300DS'] = np.sign(candle_frame['ewma300D'])
    candle_frame['ewma300DSDiff'] = abs(candle_frame['ewma300DS'].diff())

    turning_points = candle_frame[candle_frame['ewma300DSDiff'] != 0]
    turning_points['turning_points'] = turning_points['obs_no']

    merged_frame = pd.concat([candle_frame, turning_points['turning_points']],
                             axis=1)
    merged_frame['turning_points'].iloc[0] = 0
    merged_frame['turning_points'] = merged_frame['turning_points'].fillna(
        method='ffill')
    merged_frame[
        'trend_age'] = merged_frame['obs_no'] - merged_frame['turning_points']

    merged_frame['bullishWCumsum'] = merged_frame.groupby(
        'turning_points')['bullishW'].transform(pd.Series.cumsum)
    merged_frame['bearishWCumsum'] = merged_frame.groupby(
        'turning_points')['bearishW'].transform(pd.Series.cumsum)
    candle_frame = merged_frame

    candle_frame = candle_frame.dropna().reset_index(drop=True, inplace=False)
    date_timeto = cu.convert_doubledate_2datetime(date_to)

    daily_frame = candle_frame[candle_frame['datetime'] == date_timeto]
    daily_frame.reset_index(drop=True, inplace=True)

    tick_size = cmi.tick_size[ticker_head]
    latest_trade_exit_hour_minute = get_latest_trade_exit_hour_minute(
        ticker_head)

    current_position = 0

    direction_list = []
    entry_price_list = []
    exit_price_list = []
    entry_index_list = []
    exit_index_list = []
    entry_hour_minute_list = []
    stop_price_list = []
    target_price_list = []

    ewma300DN_list = []
    trend_age_list = []
    bullishWCumsum_list = []
    bearishWCumsum_list = []

    stop_adjustment_possible_Q = False
    long_trade_possible_Q = False
    short_trade_possible_Q = False
    breakout_price = np.nan

    for i in range(2, len(daily_frame.index)):

        if (daily_frame['ewma300D'].iloc[i] <
                0) | (daily_frame['william'].iloc[i] <= -80):
            long_trade_possible_Q = False

        if (daily_frame['ewma300D'].iloc[i] >
                0) | (daily_frame['william'].iloc[i] >= -20):
            short_trade_possible_Q = False

        if long_trade_possible_Q and (daily_frame['high'].iloc[i] > breakout_price + tick_size) \
                and (daily_frame['hour_minute'].iloc[i] <= 1100):

            long_trade_possible_Q = False
            current_position = 1
            direction_list.append(current_position)
            ewma300DN_list.append(daily_frame['ewma300DN'].iloc[i - 1])
            trend_age_list.append(daily_frame['trend_age'].iloc[i - 1])
            bullishWCumsum_list.append(daily_frame['bullishWCumsum'].iloc[i -
                                                                          1])
            bearishWCumsum_list.append(daily_frame['bearishWCumsum'].iloc[i -
                                                                          1])
            entry_index_list.append(i)
            entry_hour_minute_list.append(daily_frame['hour_minute'].iloc[i])
            entry_price = breakout_price + 1.5 * tick_size
            entry_price_list.append(entry_price)
            stop_price_list.append(swing_low - tick_size)
            target_price_list.append(2 * entry_price - swing_low)
            breakout_price = np.nan
            continue

        if (current_position == 0) and (daily_frame['ewma300D'].iloc[i] > 0) and (daily_frame['william'].iloc[i - 1] <= -80) \
                and (daily_frame['william'].iloc[i] > -80) and (daily_frame['hour_minute'].iloc[i] <= 1100) and (daily_frame['hour_minute'].iloc[i] >= 830):
            long_trade_possible_Q = True
            breakout_price = daily_frame['high'].iloc[i]

            for j in range(len(daily_frame.index)):
                if j == 0:
                    swing_low = daily_frame['low'].iloc[i - 1]
                elif daily_frame['low'].iloc[i - 1 - j] <= swing_low:
                    swing_low = daily_frame['low'].iloc[i - 1 - j]
                elif daily_frame['low'].iloc[i - 1 - j] > swing_low:
                    break

        if short_trade_possible_Q and (daily_frame['low'].iloc[i] < breakout_price - tick_size) \
            and (daily_frame['hour_minute'].iloc[i] <= 1100):

            short_trade_possible_Q = False
            current_position = -1
            direction_list.append(current_position)
            ewma300DN_list.append(daily_frame['ewma300DN'].iloc[i - 1])
            trend_age_list.append(daily_frame['trend_age'].iloc[i - 1])
            bullishWCumsum_list.append(daily_frame['bullishWCumsum'].iloc[i -
                                                                          1])
            bearishWCumsum_list.append(daily_frame['bearishWCumsum'].iloc[i -
                                                                          1])
            entry_index_list.append(i)
            entry_hour_minute_list.append(daily_frame['hour_minute'].iloc[i])
            entry_price = breakout_price - 1.5 * tick_size
            entry_price_list.append(entry_price)
            stop_price_list.append(swing_high + tick_size)
            target_price_list.append(2 * entry_price - swing_high)
            breakout_price = np.nan
            continue


        if (current_position == 0) and (daily_frame['ewma300D'].iloc[i] < 0) and (daily_frame['william'].iloc[i - 1] >= -20) \
            and (daily_frame['william'].iloc[i] < -20) and (daily_frame['hour_minute'].iloc[i] <= 1100) and (daily_frame['hour_minute'].iloc[i] >= 830):

            short_trade_possible_Q = True
            breakout_price = daily_frame['high'].iloc[i]

            for j in range(len(daily_frame.index)):
                if j == 0:
                    swing_high = daily_frame['high'].iloc[i - 1]
                elif daily_frame['high'].iloc[i - 1 - j] >= swing_high:
                    swing_high = daily_frame['high'].iloc[i - 1 - j]
                elif daily_frame['high'].iloc[i - 1 - j] < swing_high:
                    break

        if (current_position > 0) and stop_adjustment_possible_Q and (
                daily_frame['close'].iloc[i-2] < daily_frame['ma5'].iloc[i-2]) \
                and (daily_frame['close'].iloc[i-1] < daily_frame['ma5'].iloc[i-1]):
            stop_price_list[-1] = min(daily_frame['low'].iloc[i - 2],
                                      daily_frame['low'].iloc[i - 1])

        if (current_position < 0) and stop_adjustment_possible_Q and (
            daily_frame['close'].iloc[i-2] > daily_frame['ma5'].iloc[i-2]) \
            and (daily_frame['close'].iloc[i-1] > daily_frame['ma5'].iloc[i-1]):
            stop_price_list[-1] = max(daily_frame['high'].iloc[i - 2],
                                      daily_frame['high'].iloc[i - 1])

        if (current_position > 0) and ((daily_frame['hour_minute'].iloc[i] >=
                                        latest_trade_exit_hour_minute) |
                                       (i == len(daily_frame.index) - 1)):
            current_position = 0
            exit_price_list.append(daily_frame['open'].iloc[i] -
                                   0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position < 0) and ((daily_frame['hour_minute'].iloc[i] >=
                                        latest_trade_exit_hour_minute) |
                                       (i == len(daily_frame.index) - 1)):
            current_position = 0
            exit_price_list.append(daily_frame['open'].iloc[i] +
                                   0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position > 0) and (daily_frame['low'].iloc[i] <=
                                       stop_price_list[-1]):
            current_position = 0
            exit_price_list.append(stop_price_list[-1] - 0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position < 0) and (daily_frame['high'].iloc[i] >=
                                       stop_price_list[-1]):
            current_position = 0
            exit_price_list.append(stop_price_list[-1] + 0.5 * tick_size)
            exit_index_list.append(i)
            stop_adjustment_possible_Q = False

        if (current_position > 0) and (daily_frame['high'].iloc[i] >=
                                       target_price_list[-1]):
            stop_adjustment_possible_Q = True

        if (current_position < 0) and (daily_frame['low'].iloc[i] <=
                                       target_price_list[-1]):
            stop_adjustment_possible_Q = True

    trades_frame = pd.DataFrame.from_items([
        ('direction', direction_list), ('entry_price', entry_price_list),
        ('exit_price', exit_price_list), ('entry_index', entry_index_list),
        ('exit_index', exit_index_list),
        ('entry_hour_minute', entry_hour_minute_list),
        ('target_price', target_price_list), ('ewma300DN', ewma300DN_list),
        ('trend_age', trend_age_list), ('bullishWCumsum', bullishWCumsum_list),
        ('bearishWCumsum', bearishWCumsum_list)
    ])

    trades_frame['pnl'] = (
        trades_frame['exit_price'] -
        trades_frame['entry_price']) * trades_frame['direction']

    trades_frame['pnl_dollar'] = cmi.contract_multiplier[
        ticker_head] * trades_frame['pnl']
    trades_frame['stop_loss'] = abs(trades_frame['entry_price'] -
                                    trades_frame['target_price'])
    trades_frame['daily_sd'] = daily_sd
    trades_frame['normalized_stop_loss'] = trades_frame['stop_loss'] / daily_sd
    trades_frame['pnl_normalized'] = trades_frame['pnl'] / daily_sd

    trades_frame['ticker_head'] = ticker_head
    trades_frame['ticker'] = ticker
    trades_frame['trend1'] = trend1
    trades_frame['trend2'] = trend2
    trades_frame['trade_date'] = date_to

    return {'trades_frame': trades_frame, 'daily_frame': daily_frame}
def get_results_4ticker(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    ticker_head = cmi.get_contract_specs(ticker)['ticker_head']
    tick_size = cmi.tick_size[ticker_head]

    candle_frame = qd.get_continuous_bar_data(ticker=ticker,
                                              date_to=date_to,
                                              num_days_back=2)
    candle_frame['datetime'] = [
        x.replace(hour=0, second=0, minute=0) for x in candle_frame.index
    ]

    fractal_high = np.nan
    fractal_low = np.nan

    date_timeto = cu.convert_doubledate_2datetime(date_to)

    candle_frame['running_max'] = candle_frame['high'].rolling(
        window=10, min_periods=10, center=False).max()
    candle_frame['running_min'] = candle_frame['low'].rolling(
        window=10, min_periods=10, center=False).min()
    candle_frame['fib50'] = (candle_frame['running_max'] +
                             candle_frame['running_min']) / 2

    candle_frame['ma20'] = candle_frame['close'].rolling(window=20,
                                                         center=False).mean()
    candle_frame['ma20D'] = candle_frame['ma20'] - candle_frame['ma20'].shift(
        2)

    daily_frame = candle_frame[(candle_frame['datetime'] == date_timeto)
                               & (candle_frame['hour_minute'] >= 830)]
    daily_frame.reset_index(drop=True, inplace=True)

    ticker_frame = gfp.get_futures_price_preloaded(ticker=ticker,
                                                   settle_date_to=date_to)
    ticker_frame['close_diff'] = ticker_frame['close_price'].diff()
    daily_sd = np.std(ticker_frame['close_diff'].iloc[-41:-1])

    profit_target = daily_sd / 4
    stop_loss = daily_sd / 4

    trend_bias = 0
    current_position = 0

    direction_list = []
    entry_price_list = []
    exit_price_list = []
    entry_index_list = []
    exit_index_list = []

    for i in range(10, len(daily_frame.index)):

        high = daily_frame['high'].iloc[i]
        low = daily_frame['low'].iloc[i]
        running_max = daily_frame['running_max'].iloc[i]
        running_min = daily_frame['running_min'].iloc[i]
        fib50 = daily_frame['fib50'].iloc[i]
        fib50_1 = daily_frame['fib50'].iloc[i - 1]

        close_1 = daily_frame['close'].iloc[i - 1]
        close = daily_frame['close'].iloc[i]
        ma20D = daily_frame['ma20D'].iloc[i]

        if (current_position == 0) and (ma20D > 0) and (
                close_1 < fib50_1) and (close > fib50):
            current_position = 1
            direction_list.append(current_position)
            entry_price_list.append(close + tick_size)
            entry_index_list.append(i)
            target = close + tick_size + profit_target
            stop = close + tick_size - stop_loss

        if (current_position == 0) and (ma20D < 0) and (
                close_1 > fib50_1) and (close < fib50):
            current_position = -1
            direction_list.append(current_position)
            entry_price_list.append(close - tick_size)
            entry_index_list.append(i)
            target = close - tick_size - profit_target
            stop = close - tick_size + stop_loss

        if (current_position > 0):
            if high >= target + tick_size:
                exit_price_list.append(target)
                exit_index_list.append(i)
                target = np.nan
                stop = np.nan
                current_position = 0

            if ma20D < 0:
                exit_price_list.append(close - tick_size)
                exit_index_list.append(i)
                target = np.nan
                stop = np.nan
                current_position = 0

            if i == len(daily_frame) - 1:
                exit_price_list.append(daily_frame['open'].iloc[i] - tick_size)
                exit_index_list.append(i)
                target = np.nan
                stop = np.nan
                current_position = 0

        if (current_position < 0):
            if low <= target - tick_size:
                exit_price_list.append(target)
                exit_index_list.append(i)
                target = np.nan
                stop = np.nan
                current_position = 0

            if ma20D > 0:
                exit_price_list.append(close + tick_size)
                exit_index_list.append(i)
                target = np.nan
                stop = np.nan
                current_position = 0

            if i == len(daily_frame) - 1:
                exit_price_list.append(daily_frame['open'].iloc[i] + tick_size)
                exit_index_list.append(i)
                target = np.nan
                stop = np.nan
                current_position = 0

    trades_frame = pd.DataFrame.from_items([('direction', direction_list),
                                            ('entry_price', entry_price_list),
                                            ('exit_price', exit_price_list),
                                            ('entry_index', entry_index_list),
                                            ('exit_index', exit_index_list)])

    trades_frame['pnl'] = (
        trades_frame['exit_price'] -
        trades_frame['entry_price']) * trades_frame['direction']
    trades_frame['pnl_dollar'] = cmi.contract_multiplier[
        ticker_head] * trades_frame['pnl']

    return {'trades_frame': trades_frame, 'daily_frame': daily_frame}
Beispiel #5
0
def get_results_4ticker(**kwargs):

    ticker = kwargs['ticker']
    date_to = kwargs['date_to']

    wait4_eoc_volume_filter = kwargs['wait4_eoc_volume_filter']
    wait4_eoc = wait4_eoc_volume_filter[0]
    volume_filter = wait4_eoc_volume_filter[1]
    trend_filter_type = kwargs['trend_filter_type']
    stop_loss_multiplier = kwargs['stop_loss_multiplier']  # 0.3
    distance_multiplier = kwargs['distance_multiplier']  # 0.5
    time_section_no = kwargs['time_section_no']  # 1

    ticker_head = cmi.get_contract_specs(ticker)['ticker_head']
    tick_size = cmi.tick_size[ticker_head]
    latest_trade_exit_hour_minute = get_latest_trade_exit_hour_minute(
        ticker_head)

    settle_frame = gfp.get_futures_price_preloaded(ticker=ticker,
                                                   settle_date_to=date_to)
    settle_frame = settle_frame.iloc[:-1]

    settle_frame['ewma_3'] = settle_frame['close_price'].ewm(
        span=3, min_periods=3, adjust=True, ignore_na=False).mean()
    settle_frame['ewma_5'] = settle_frame['close_price'].ewm(
        span=5, min_periods=5, adjust=True, ignore_na=False).mean()
    settle_frame['ewma_10'] = settle_frame['close_price'].ewm(
        span=10, min_periods=10, adjust=True, ignore_na=False).mean()

    trend_direction = 0

    if trend_filter_type in ['3', '5', '10']:
        if settle_frame['close_price'].iloc[-1] > settle_frame[
                'ewma_' + trend_filter_type].iloc[-1]:
            trend_direction = 1
        else:
            trend_direction = -1

    avg_volume = np.mean(settle_frame['volume'].iloc[-40:])

    settle_frame['close_diff'] = settle_frame['close_price'].diff()
    daily_sd = np.std(settle_frame['close_diff'].iloc[-40:])

    distance_out = sibo.get_distance(settle_frame=settle_frame,
                                     distance_type='daily_sd',
                                     distance_multiplier=distance_multiplier)

    candle_frame = qd.get_continuous_bar_data(ticker=ticker,
                                              date_to=date_to,
                                              num_days_back=10)

    time_filter_output = sibo.get_time_filter(ticker_head=ticker_head,
                                              section_no=time_section_no)
    start_hour_minute = time_filter_output['start_hour_minute']
    end_hour_minute = time_filter_output['end_hour_minute']

    candle_frame['datetime'] = [
        x.replace(hour=0, second=0, minute=0) for x in candle_frame.index
    ]
    candle_frame['total_volume'] = candle_frame['buy_volume'] + candle_frame[
        'sell_volume'] + candle_frame['volume']

    candle_frame = candle_frame.dropna().reset_index(drop=True, inplace=False)
    date_timeto = cu.convert_doubledate_2datetime(date_to)

    hist_frame = candle_frame[
        (candle_frame['hour_minute'] >= start_hour_minute)
        & (candle_frame['hour_minute'] <= end_hour_minute) &
        (candle_frame['datetime'] < date_timeto)]

    hist_frame['normalized_volume'] = hist_frame['total_volume'] / avg_volume
    volume_filter_level = hist_frame['normalized_volume'].quantile(0.7)

    price_frame = candle_frame[(candle_frame['datetime'] == date_timeto)
                               & (candle_frame['hour_minute'] >= 830)]
    price_frame.reset_index(drop=True, inplace=True)

    poi_out = sibo.get_poi(candle_frame=price_frame, poi_type='open')

    poi = poi_out['poi']

    if not poi_out['success']:
        return {'trades_frame': pd.DataFrame(), 'price_frame': pd.DataFrame()}

    current_position = 0
    entry_price_list = []
    exit_price_list = []
    entry_index_list = []
    exit_index_list = []
    direction_list = []
    hour_minute_list = []
    volume_list = []

    for i in range(1, len(price_frame.index)):

        hour_minute = price_frame['hour_minute'].iloc[i]

        if wait4_eoc:
            long_breakoutQ = (price_frame['close'].iloc[i] >= poi + distance_out + tick_size) and \
            (price_frame['close'].iloc[i-1] < poi + distance_out + tick_size)
            short_breakoutQ = (price_frame['close'].iloc[i] <= poi - distance_out - tick_size) and \
                              (price_frame['close'].iloc[i-1] > poi - distance_out - tick_size)

            long_entry_price = price_frame['close'].iloc[i] + tick_size
            short_entry_price = price_frame['close'].iloc[i] - tick_size
        else:
            long_breakoutQ = (price_frame['high'].iloc[i] >= poi + distance_out + tick_size) and \
                             (price_frame['close'].iloc[i - 1] < poi + distance_out + tick_size)
            short_breakoutQ = (price_frame['low'].iloc[i] <= poi - distance_out - tick_size) and \
                              (price_frame['close'].iloc[i - 1] > poi - distance_out - tick_size)

            long_entry_price = poi + distance_out + 2 * tick_size
            short_entry_price = poi - distance_out - 2 * tick_size

        if volume_filter:
            if (price_frame['total_volume'].iloc[i] /
                    avg_volume) < volume_filter_level:
                long_breakoutQ = False
                short_breakoutQ = False

        # long breakout
        if (current_position==0) and long_breakoutQ \
                and (hour_minute>=start_hour_minute) and (hour_minute<=end_hour_minute) and (trend_direction>=0):
            current_position = 1
            entry_price = long_entry_price
            stop_price = entry_price - stop_loss_multiplier * distance_out
            entry_price_list.append(entry_price)
            direction_list.append(current_position)
            entry_index_list.append(i)
            hour_minute_list.append(hour_minute)
            volume_list.append(price_frame['total_volume'].iloc[i] /
                               avg_volume)
            continue

        # short breakout
        if (current_position==0) and (short_breakoutQ) \
                and (hour_minute>=start_hour_minute) and (hour_minute<=end_hour_minute)and (trend_direction<=0):
            current_position = -1
            entry_price = short_entry_price
            stop_price = entry_price + stop_loss_multiplier * distance_out
            entry_price_list.append(entry_price)
            direction_list.append(current_position)
            entry_index_list.append(i)
            hour_minute_list.append(hour_minute)
            volume_list.append(price_frame['total_volume'].iloc[i] /
                               avg_volume)
            continue

        # long stop out
        if (current_position
                == 1) and (price_frame['low'].iloc[i] <= stop_price):
            exit_price_list.append(stop_price - tick_size)
            exit_index_list.append(i)
            current_position = 0

        # short stop out
        if (current_position
                == -1) and (price_frame['high'].iloc[i] >= stop_price):
            exit_price_list.append(stop_price + tick_size)
            exit_index_list.append(i)
            current_position = 0

        if (current_position > 0) and (
            (hour_minute >= latest_trade_exit_hour_minute) or
            (i == len(price_frame.index) - 1)):
            exit_price_list.append(price_frame['open'].iloc[i] - tick_size)
            exit_index_list.append(i)
            break

        if (current_position < 0) and (
            (hour_minute >= latest_trade_exit_hour_minute) or
            (i == len(price_frame.index) - 1)):
            exit_price_list.append(price_frame['open'].iloc[i] + tick_size)
            exit_index_list.append(i)
            break

    trades_frame = pd.DataFrame.from_dict({
        'direction': direction_list,
        'hour_minute': hour_minute_list,
        'entry_price': entry_price_list,
        'exit_price': exit_price_list,
        'entry_index': entry_index_list,
        'exit_index': exit_index_list,
        'volume': volume_list
    })

    trades_frame['pnl'] = (
        trades_frame['exit_price'] -
        trades_frame['entry_price']) * trades_frame['direction']
    trades_frame['pnl_dollar'] = cmi.contract_multiplier[
        ticker_head] * trades_frame['pnl']
    trades_frame['pnl_normalized'] = trades_frame['pnl'] / daily_sd
    trades_frame['ticker_head'] = ticker_head
    trades_frame['ticker'] = ticker
    trades_frame['trade_date'] = date_to

    return {'trades_frame': trades_frame, 'price_frame': price_frame}