Exemple #1
0
 def add_instrument(self, name):
     self.tick_data[name] = []        
     dtypes = [(field, dtype_map[field]) for field in day_data_list]
     self.day_data[name]  = data_handler.DynamicRecArray(dtype = dtypes)
     dtypes = [(field, dtype_map[field]) for field in min_data_list]
     self.min_data[name]  = {1: data_handler.DynamicRecArray(dtype = dtypes)}
     self.cur_day[name]   = dict([(item, 0) for item in day_data_list])
     self.cur_min[name]   = dict([(item, 0) for item in min_data_list])
     self.day_data_func[name] = []
     self.min_data_func[name] = {}
     self.cur_min[name]['datetime'] = datetime.datetime.fromordinal(self.scur_day.toordinal())
     self.cur_min[name]['date'] = self.scur_day
     self.cur_day[name]['date'] = self.scur_day
Exemple #2
0
 def run_loop_sim(self):
     dra = dh.DynamicRecArray(dataframe=self.df)
     sim_data = dra.data
     nlen = len(dra)
     self.scur_day = sim_data['date'][0]
     for n in range(1, nlen-1):
         self.timestamp = datetime.datetime.utcfromtimestamp(sim_data['datetime'][n].astype('O')/1e9)
         self.traded_vol = self.traded_cost = self.closeout_pnl = 0
         self.traded_price = sim_data['open'][n]
         sim_data['pos'][n] = sim_data['pos'][n - 1]
         if not self.check_data_invalid(sim_data, n-1):
             if (n >= nlen - 2) or (sim_data['contract'][n]!=sim_data['contract'][n+1]):
                 for tradepos in self.positions:
                     self.close_tradepos(tradepos, sim_data['open'][n])
                 self.positions = []
             else:
                 self.on_bar(sim_data, n - 1)
                 self.check_curr_pos(sim_data, n)
         sim_data['pos'][n] += self.traded_vol
         sim_data['cost'][n] = self.traded_cost
         sim_data['closeout'][n] = self.closeout_pnl
         sim_data['traded_price'][n] = self.traded_price
         if self.scur_day != sim_data['date'][n+1]:
             self.daily_initialize(sim_data, n)
             self.scur_day = sim_data['date'][n + 1]
     #pos = pd.Series(sim_data['pos'], index = self.df.index, name = 'pos')
     #closeout = pd.Series(sim_data['closeout'], index = self.df.index, name = 'closeout')
     #tp = pd.Series(sim_data['traded_price'], index=self.df.index, name='traded_price')
     #cost = pd.Series(sim_data['cost'], index=self.df.index, name='cost')
     #out_df = pd.concat([self.df.open, self.df.high, self.df.low, self.df.close, self.df.date, self.df.min_id, pos, tp, cost, closeout], \
     #                   join='outer', axis = 1)
     out_df = pd.DataFrame(sim_data)
     return out_df, self.closed_trades
Exemple #3
0
 def __init__(self, config, agent = None):
     self.load_config(config)
     self.underliers = self.products.keys()                
     self.option_dict = self.get_option_dict(self.products)
     self.option_insts = self.option_dict.values()
     self.instIDs = self.underliers + self.option_insts        
     self.underlying = [None] * len(self.instIDs)
     self.expiry_map = {}
     self.inst_map = dict([(instID, i) for i, instID in enumerate(self.instIDs)])
     self.risk_table = dh.DynamicRecArray( \
         dtype = [('name', '|S50'), ('product', '|S50'), \
                 ('under', '|S50'), ('cont_mth', 'i8'), ('otype', '|S50'), \
                 ('strike', 'f8'), ('multiple', 'i8'), ('df', 'f8'), \
                 ('margin_long', 'f8'), ('margin_short', 'f8'), ('under_price', 'f8'), \
                 ('pos_long', 'i8'), ('pos_short', 'i8'), ('out_long', 'i8'), ('out_short', 'i8'), \
                 ('pv', 'f8'), ('delta', 'f8'), ('gamma', 'f8'), ('vega', 'f8'), ('theta', 'f8'), \
                 ('ppv', 'f8'), ('pdelta', 'f8'), ('pgamma', 'f8'), ('pvega', 'f8'), ('ptheta', 'f8')], \
         nlen = len(self.instIDs))
     self.risk_table.data['name'] = self.instIDs
     self.risk_table.data['under'] = self.risk_table.data['name']
     self.risk_table.data['df'] = 1.0
     self.agent = agent
     self.folder = ''
     self.submitted_pos = dict([(inst, []) for inst in self.instIDs])
     self.hedge_config = {'delta_algo': 'ExecAlgo1DFixT', 'delta_args': {'time_period': 50, 'tick_num': 1}, \
                          'vega_algo': 'ExecAlgo1DFixT', 'vega_args': {'time_period': 50, 'tick_num': 1}, }
Exemple #4
0
 def run_loop_sim(self):
     sim_data = dh.DynamicRecArray(dataframe=self.df)
     nlen = len(sim_data)
     positions = []
     closed_trades = []
     tradeid = 0
     curr_date = None
     for n in range(nlen - 3):
         cost = 0
         pos = sim_data['pos'][n]
         if sim_data['ma'][n] == 0 or sim_data['chan_h'][
                 n] == 0 or sim_data['dopen'][n] == 0:
             continue
         if curr_date != sim_data['date'][n]:
             curr_date = sim_data['date'][n]
             dopen = sim_data['dopen'][n]
             rng = max(self.min_rng * dopen, self.k * sim_data['tr'][n])
             buytrig = dopen + rng
             selltrig = dopen - rng
             if sim_data['ma'][n] > dopen:
                 buytrig += self.f * rng
             else:
                 selltrig -= self.f * rng
             continue
         if self.price_mode == 'TP':
             ref_long = ref_short = (sim_data['close'][n] +
                                     sim_data['high'][n] +
                                     sim_data['low'][n]) / 3.0
         elif self.price_mode == 'HL':
             ref_long = sim_data['high'][n]
             ref_short = sim_data['low'][n]
         elif self.price_mode == 'CL':
             ref_long = ref_short = sim_data['close'][n]
         else:
             ref_long = ref_short = sim_data['open'][n + 1]
         target_pos = (ref_long > buytrig) - (ref_short < selltrig)
         if len(positions) > 0:
             need_close = (self.close_daily or
                           (curr_date == sim_data['date'][-1])) and (
                               sim_data['min_id'][n] >= config['exit_min'])
             for tradepos in positions:
                 ep = sim_data['low'][n] if tradepos.pos > 0 else sim_data[
                     'high'][n]
                 if need_close or tradepos.check_exit(
                         sim_data['open'][n + 1],
                         0) or (tradepos.pos * target_pos < 0):
                     tradepos.close(
                         sim_data['open'][n + 1] -
                         self.offset * misc.sign(tradepos.pos),
                         sim_data['datetime'][n + 1])
                     tradepos.exit_tradeid = tradeid
                     tradeid += 1
                     pos -= tradepos.pos
                     cost += abs(tradepos.pos) * (
                         self.offset + sim_data['open'][n + 1] * self.tcost)
                     closed_trades.append(tradepos)
                 elif self.pos_update:
                     tradepos.update_price(ep)
             positions = [pos for pos in positions if not pos.is_closed]
             if need_close:
                 continue
         if target_pos != 0:
             if (not self.use_chan) or (
                 ((ref_long > sim_data['chanh'][n]) and target_pos > 0) or
                 ((ref_short < sim_data['chanl'][n]) and target_pos < 0)):
                 new_pos = self.pos_class(
                     [sim_data['contract'][n]], [1], self.unit * target_pos,
                     sim_data['open'][n + 1] + target_pos * self.offset,
                     buytrig, **self.pos_args)
                 tradeid += 1
                 new_pos.entry_tradeid = tradeid
                 new_pos.open(
                     sim_data['open'][n + 1] + target_pos * self.offset,
                     sim_data['datetime'][n + 1])
                 positions.append(new_pos)
                 pos += self.unit * target_pos
                 cost += abs(target_pos) * (
                     self.offset + sim_data['open'][n + 1] * self.tcost)
         sim_data['cost'][n + 1] = cost
         sim_data['pos'][n + 1] = pos
     out_df = pd.concat([])
     return out_df, closed_trades
Exemple #5
0
def run_sim(config):
    mdf = config['mdf']
    close_daily = config['close_daily']
    offset = config['offset']
    k = config['param'][0]
    win = config['param'][1]
    multiplier = config['param'][2]
    f = config['param'][3]
    price_mode = config.get('price_mode', 'TP')
    pos_update = config['pos_update']
    pos_class = config['pos_class']
    pos_args = config['pos_args']
    proc_func = config['proc_func']
    proc_args = config['proc_args']
    chan_func = config['chan_func']
    chan_high = eval(chan_func['high']['func'])
    chan_low = eval(chan_func['low']['func'])
    tcost = config['trans_cost']
    unit = config['unit']
    SL = config['stoploss']
    min_rng = config['min_range']
    chan = config['chan']
    use_chan = config['use_chan']
    no_trade_set = config['no_trade_set']
    pos_freq = config.get('pos_freq', 1)
    xdf = proc_func(mdf, **proc_args)
    if win == -1:
        tr = pd.concat(
            [xdf.high - xdf.low,
             abs(xdf.close - xdf.close.shift(1))],
            join='outer',
            axis=1).max(axis=1)
    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)
    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)
    xdf['TR'] = tr
    xdf['chan_h'] = chan_high(xdf['high'], chan, **chan_func['high']['args'])
    xdf['chan_l'] = chan_low(xdf['low'], chan, **chan_func['low']['args'])
    xdata = pd.concat([
        xdf['TR'].shift(1), xdf['MA'].shift(1), xdf['chan_h'].shift(1),
        xdf['chan_l'].shift(1), xdf['open']
    ],
                      axis=1,
                      keys=['tr', 'ma', 'chanh', 'chanl', 'dopen']).fillna(0)
    df = mdf.join(xdata, how='left').fillna(method='ffill')
    df['pos'] = 0
    df['cost'] = 0
    df['traded_price'] = df['open']
    sim_data = dh.DynamicRecArray(dataframe=df)
    nlen = len(sim_data)
    positions = []
    closed_trades = []
    tradeid = 0
    curr_date = None
    buytrig = selltrig = 0.0
    for n in range(nlen - 3):
        cost = 0
        pos = sim_data['pos'][n]
        if sim_data['ma'][n] == 0 or sim_data['chan_h'][n] == 0 or sim_data[
                'dopen'][n] == 0:
            continue
        if curr_date != sim_data['date'][n]:
            curr_date = sim_data['date'][n]
            dopen = sim_data['dopen'][n]
            rng = max(min_rng * dopen, k * sim_data['tr'][n])
            buytrig = dopen + rng
            selltrig = dopen - rng
            if sim_data['ma'][n] > dopen:
                buytrig += f * rng
            else:
                selltrig -= f * rng
            continue
        if price_mode == 'TP':
            ref_long = ref_short = (sim_data['close'][n] + sim_data['high'][n]
                                    + sim_data['low'][n]) / 3.0
        elif price_mode == 'HL':
            ref_long = sim_data['high'][n]
            ref_short = sim_data['low'][n]
        elif price_mode == 'CL':
            ref_long = ref_short = sim_data['close'][n]
        else:
            ref_long = ref_short = sim_data['open'][n + 1]
        target_pos = (ref_long > buytrig) - (ref_short < selltrig)
        if len(positions) > 0:
            need_close = (close_daily or
                          (curr_date == sim_data['date'][-1])) and (
                              sim_data['min_id'][n] >= config['exit_min'])
            for tradepos in positions:
                ep = sim_data['low'][n] if tradepos.pos > 0 else sim_data[
                    'high'][n]
                if need_close or tradepos.check_exit(
                        sim_data['open'][n + 1],
                        0) or (tradepos.pos * target_pos < 0):
                    tradepos.close(
                        sim_data['open'][n + 1] -
                        offset * misc.sign(tradepos.pos),
                        sim_data['datetime'][n + 1])
                    tradepos.exit_tradeid = tradeid
                    tradeid += 1
                    pos -= tradepos.pos
                    cost += abs(tradepos.pos) * (
                        offset + sim_data['open'][n + 1] * tcost)
                    closed_trades.append(tradepos)
                elif pos_update:
                    tradepos.update_price(ep)
            positions = [pos for pos in positions if not pos.is_closed]
            if need_close:
                continue
        if target_pos != 0:
            if (not use_chan) or (
                ((ref_long > sim_data['chanh'][n]) and target_pos > 0) or
                ((ref_short < sim_data['chanl'][n]) and target_pos < 0)):
                new_pos = pos_class(
                    [sim_data['contract'][n]], [1], unit * target_pos,
                    sim_data['open'][n + 1] + target_pos * offset, buytrig,
                    **pos_args)
                tradeid += 1
                new_pos.entry_tradeid = tradeid
                new_pos.open(sim_data['open'][n + 1] + target_pos * offset,
                             sim_data['datetime'][n + 1])
                positions.append(new_pos)
                pos += unit * target_pos
                cost += abs(target_pos) * (offset +
                                           sim_data['open'][n + 1] * tcost)
        sim_data['cost'][n + 1] = cost
        sim_data['pos'][n + 1] = pos
    out_df = pd.concat([])
    return out_df, closed_trades
Exemple #6
0
 def prepare_data_env(self, inst, mid_day=True):
     if self.instruments[inst].ptype == instrument.ProductType.Option:
         return
     if self.daily_data_days > 0 or mid_day:
         #self.logger.debug('Updating historical daily data for %s' % self.scur_day.strftime('%Y-%m-%d'))
         daily_start = workdays.workday(self.scur_day,
                                        -self.daily_data_days, CHN_Holidays)
         daily_end = self.scur_day
         ddf = mysqlaccess.load_daily_data_to_df('fut_daily',
                                                 inst,
                                                 daily_start,
                                                 daily_end,
                                                 index_col=None)
         if len(ddf) > 0:
             self.instruments[inst].price = ddf['close'].iloc[-1]
             self.instruments[inst].last_update = 0
             self.instruments[inst].prev_close = ddf['close'].iloc[-1]
             for fobj in self.day_data_func[inst]:
                 ts = fobj.sfunc(ddf)
                 if type(ts).__name__ == 'Series':
                     if ts.name in ddf.columns:
                         self.logger.warning(
                             'TimeSeries name %s is already in the columns for inst = %s'
                             % (ts.name, inst))
                     ddf[ts.name] = ts
                 elif type(ts).__name__ == 'DataFrame':
                     for col_name in ts.columns:
                         if col_name in ddf.columns:
                             self.logger.warning(
                                 'TimeSeries name %s is already in the columns for inst = %s'
                                 % (col_name, inst))
                         ddf[col_name] = ts[col_name]
         self.day_data[inst] = data_handler.DynamicRecArray(dataframe=ddf)
     if self.min_data_days > 0 or mid_day:
         #self.logger.debug('Updating historical min data for %s' % self.scur_day.strftime('%Y-%m-%d'))
         d_start = workdays.workday(self.scur_day, -self.min_data_days,
                                    CHN_Holidays)
         d_end = self.scur_day
         min_start = int(self.instruments[inst].start_tick_id / 1000)
         min_end = int(self.instruments[inst].last_tick_id / 1000) + 1
         mdf = mysqlaccess.load_min_data_to_df('fut_min',
                                               inst,
                                               d_start,
                                               d_end,
                                               minid_start=min_start,
                                               minid_end=min_end,
                                               database='blueshale',
                                               index_col=None)
         mdf = backtest.cleanup_mindata(mdf,
                                        self.instruments[inst].product,
                                        index_col=None)
         mdf['bar_id'] = self.conv_bar_id(mdf['min_id'], inst)
         if len(mdf) > 0:
             min_date = mdf['date'].iloc[-1]
             if (len(self.day_data[inst]) == 0) or (
                     min_date > self.day_data[inst].data['date'][-1]):
                 ddf = data_handler.conv_ohlc_freq(mdf, 'd', index_col=None)
                 self.cur_day[inst]['open'] = float(ddf.open[-1])
                 self.cur_day[inst]['close'] = float(ddf.close[-1])
                 self.cur_day[inst]['high'] = float(ddf.high[-1])
                 self.cur_day[inst]['low'] = float(ddf.low[-1])
                 self.cur_day[inst]['volume'] = int(ddf.volume[-1])
                 self.cur_day[inst]['openInterest'] = int(
                     ddf.openInterest[-1])
                 self.cur_min[inst]['datetime'] = pd.datetime(
                     *mdf['datetime'].iloc[-1].timetuple()[0:-3])
                 self.cur_min[inst]['date'] = mdf['date'].iloc[-1]
                 self.cur_min[inst]['open'] = float(mdf['open'].iloc[-1])
                 self.cur_min[inst]['close'] = float(mdf['close'].iloc[-1])
                 self.cur_min[inst]['high'] = float(mdf['high'].iloc[-1])
                 self.cur_min[inst]['low'] = float(mdf['low'].iloc[-1])
                 self.cur_min[inst]['volume'] = self.cur_day[inst]['volume']
                 self.cur_min[inst]['openInterest'] = self.cur_day[inst][
                     'openInterest']
                 self.cur_min[inst]['min_id'] = int(mdf['min_id'].iloc[-1])
                 self.cur_min[inst]['bar_id'] = self.conv_bar_id(
                     self.cur_min[inst]['min_id'], inst)
                 self.instruments[inst].price = float(mdf['close'].iloc[-1])
                 self.instruments[inst].last_update = 0
                 #self.logger.debug('inst=%s tick data loaded for date=%s' % (inst, min_date))
             if 1 not in self.min_data_func[inst]:
                 self.min_data[inst][1] = data_handler.DynamicRecArray(
                     dataframe=mdf)
             for m in sorted(self.min_data_func[inst]):
                 if m != 1:
                     bar_func = lambda ts: self.conv_bar_id(ts, inst)
                     mdf_m = data_handler.conv_ohlc_freq(
                         mdf,
                         str(m) + 'min',
                         index_col=None,
                         bar_func=bar_func,
                         extra_cols=['bar_id'])
                 else:
                     mdf_m = mdf
                 for fobj in self.min_data_func[inst][m]:
                     ts = fobj.sfunc(mdf_m)
                     if type(ts).__name__ == 'Series':
                         if ts.name in mdf_m.columns:
                             self.logger.warning(
                                 'TimeSeries name %s is already in the columns for inst = %s'
                                 % (ts.name, inst))
                         mdf_m[ts.name] = ts
                     elif type(ts).__name__ == 'DataFrame':
                         for col_name in ts.columns:
                             if col_name in mdf_m.columns:
                                 self.logger.warning(
                                     'TimeSeries name %s is already in the columns for inst = %s'
                                     % (col_name, inst))
                             mdf_m[col_name] = ts[col_name]
                 self.min_data[inst][m] = data_handler.DynamicRecArray(
                     dataframe=mdf_m)
Exemple #7
0
def plot_indicators(df, ind_fields, ind_levels):
    ccolors = ['blue', 'red', 'yellow', 'black', 'green']
    ra = dh.DynamicRecArray(dataframe = df)
    xdf = ra.data
    indx = np.array(range(len(df)))
    plt.ion()
    fig = plt.figure(facecolor='white')
    ax0 = plt.subplot2grid((6, 4), (1, 0), rowspan=4, colspan=4)
    finance.candlestick2_ohlc(ax0, xdf['open'], xdf['high'], xdf['low'], xdf['close'], \
                              width=0.6, colorup='g', colordown='r')
    c = 0
    for field in ind_fields[0]:
        ax0.plot(indx, xdf[field], 'g^', label=field)
        c = (c + 1) % len(ccolors)
    ax0.grid(True, color='b')
    ax0.xaxis.set_major_locator(mticker.MaxNLocator(10))
    ax0.yaxis.label.set_color("b")
    ax0.spines['bottom'].set_color("#5998ff")
    ax0.spines['top'].set_color("#5998ff")
    ax0.spines['left'].set_color("#5998ff")
    ax0.spines['right'].set_color("#5998ff")
    ax0.tick_params(axis='y', colors='b')
    plt.gca().yaxis.set_major_locator(mticker.MaxNLocator(prune='upper'))
    ax0.tick_params(axis='x', colors='b')
    plt.ylabel('Price Chart')

    ax0v = ax0.twinx()
    ax0v.fill_between(indx, 0, xdf['volume'], facecolor='#00ffe8', alpha=.4)
    ax0v.axes.yaxis.set_ticklabels([])
    ax0v.grid(False)
    ax0v.set_ylim(0, xdf['volume'].max())
    ax0v.spines['bottom'].set_color("#5998ff")
    ax0v.spines['top'].set_color("#5998ff")
    ax0v.spines['left'].set_color("#5998ff")
    ax0v.spines['right'].set_color("#5998ff")
    ax0v.tick_params(axis='x', colors='b')
    ax0v.tick_params(axis='y', colors='b')

    ax1 = plt.subplot2grid((6, 4), (0, 0), sharex=ax0, rowspan=1, colspan=4)
    indCol = '#c1f9f7'
    posCol = '#386d13'
    negCol = '#8f2020'
    for field in ind_fields[1]:
        ax1.plot(indx, xdf[field], indCol, linewidth=1)
    ax1.axhline(ind_levels[1][1], color=negCol)
    ax1.axhline(ind_levels[1][0], color=posCol)
    ax1.fill_between(indx, xdf[ind_fields[1][0]], ind_levels[1][0], \
                     where=(xdf[ind_fields[1][0]] >= ind_levels[1][0]), facecolor=negCol, edgecolor=negCol, alpha=0.5)
    ax1.fill_between(indx, xdf[ind_fields[1][0]], ind_levels[1][1], \
                     where=(xdf[ind_fields[1][0]] <= ind_levels[1][1]), facecolor=posCol, edgecolor=posCol, alpha=0.5)
    ax1.set_yticks([ind_levels[1][1], ind_levels[1][0]])
    ax1.yaxis.label.set_color("b")
    ax1.spines['bottom'].set_color("#5998ff")
    ax1.spines['top'].set_color("#5998ff")
    ax1.spines['left'].set_color("#5998ff")
    ax1.spines['right'].set_color("#5998ff")
    ax1.tick_params(axis='y', colors='b')
    ax1.tick_params(axis='x', colors='b')
    plt.ylabel(ind_fields[1][0])
    ax1.set_title('%s' % ind_fields[1][0])
    ax2 = plt.subplot2grid((6, 4), (5, 0), sharex=ax0, rowspan=1, colspan=4)
    for field in ind_fields[2]:
        ax2.plot(indx, xdf[field], color = ccolors[c], lw=0.6)
        c = (c + 1) % len(ccolors)
    ax2.spines['bottom'].set_color("#5998ff")
    ax2.spines['top'].set_color("#5998ff")
    ax2.spines['left'].set_color("#5998ff")
    ax2.spines['right'].set_color("#5998ff")
    ax2.tick_params(axis='y', colors='b')
    ax2.tick_params(axis='x', colors='b')

    for ax in ax0, ax0v, ax1, ax2:
        for label in ax.get_xticklabels():
            label.set_visible(False)
    ax1.yaxis.set_major_locator(MyLocator(5, prune='both'))
    ax2.yaxis.set_major_locator(MyLocator(5, prune='both'))
    plt.show()