def GenBTReport(bt_file_path, file_name='strat_pnl_hist'): r = Reader() t = Trader() r.load_order_file(bt_file_path) for i in range(r.get_ordersize()): o = r.read_border(i) if o.price > 0 and abs(o.size) > 0: t.RegisterOneTrade(o.ticker, o.size if o.side == 1 else -o.size, o.price) t.PlotStratPnl(file_name) return t.GenDFReport(), t.GenStratReport()
class BackTestor: def __init__(self, order_path): self.r = Reader() self.t = Trader() self.LoadOrder(order_path) def LoadOrder(self, order_path): self.r.load_order_file(order_path) for i in range(self.r.get_ordersize()): o = self.r.read_border(i) if o.price > 0: self.t.RegisterOneTrade(o.contract, o.size if o.side == 1 else -o.size, o.price) def Plot(self): self.t.PlotStratPnl()
def TradeReport(date_prefix, trade_path, cancel_path, file_name=''): trader = Trader() command = 'cat ' + date_prefix + 'log/order.log | grep Filled > ' + trade_path + '; cat ' + date_prefix + 'log/order_night.log | grep Filled >> ' + trade_path command_result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) command = 'cat ' + date_prefix + 'log/order.log | grep Cancelled > ' + cancel_path + '; cat ' + date_prefix + 'log/order_night.log | grep Cancelled >> ' + cancel_path command_result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) time.sleep(3) trade_details = [] with open(trade_path) as f: ei = ExchangeInfo() for l in f: temp = [] ei.construct(l) temp.append( datetime.datetime.fromtimestamp(float( ei.time_str)).strftime("%Y-%m-%d %H:%M:%S")) temp.append(ei.ticker) temp.append("Buy" if ei.side == 0 else "Sell") temp.append(ei.trade_price) temp.append(ei.trade_size) trade_details.append(temp) trader.RegisterOneTrade( ei.ticker, int(ei.trade_size) if ei.side == 0 else -int(ei.trade_size), float(ei.trade_price)) #print('printint') df = trader.GenDFReport() trader.PlotStratPnl(file_name=file_name) #print(df) #trader.Summary() df.insert(len(df.columns), 'cancelled', 0) with open(cancel_path) as f: ei = ExchangeInfo() for l in f: ei.construct(l) if ei.ticker not in df.index: df.loc[ei.ticker] = 0 df.loc[ei.ticker, 'cancelled'] = df.loc[ei.ticker, 'cancelled'] + 1 return df, trader.GenStratReport(), pd.DataFrame( trade_details, columns=['time', 'ticker', 'Side', 'price', 'size'])
class BaseFactor: def __init__(self): self.f_value = [] self.tr = Trader() def run(self, start_date, end_date, ticker): self.m = self.LoadData(start_date, end_date, ticker) self.CalFactor() self.PlotFactor() self.TestPnl() self.PlotSignal() def PlotSignal(self): df_list = [i[1] for i in sorted(self.m.items(), key=lambda x: x[0])] if len(df_list) < 1: print('empty df') return df = df_list[0] start = time.time() for i in range(1, len(df_list)): df = pd.merge(df, df_list[i], how='outer') print('finished merge used %lfs' % (time.time() - start)) plt.plot(df['mid'], label='mid', alpha=0.3) buy_x = df[df['money'] < 0].index.tolist() buy = df[df['money'] < -0.1] plt.scatter(x=buy.index.tolist(), y=buy['mid'].tolist(), marker='.', s=[4] * len(buy), c='red', label='buy') sell = df[df['money'] > 0.1] plt.scatter(x=sell.index.tolist(), y=sell['mid'].tolist(), marker='.', s=[4] * len(sell), c='green', label='sell') plt.title('factor percentile signal') plt.legend() plt.grid() plt.show() def TestPnl(self): for k in self.m: df = self.m[k] up = df['factor'].quantile(0.999) down = df['factor'].quantile(0.001) df['money'] = np.where(df['factor'] > up, df['mid'], 0.0) df['money'] = np.where(df['factor'] < down, -df['mid'], df['money']) for i in df['money'].tolist(): if abs(i) > 1: self.tr.RegisterOneTrade('ni8888', 1 if i > 0 else -1, abs(i)) self.tr.Summary() self.tr.PlotStratRawPnl(show=True) self.tr.PlotStratPnl(show=True) def PlotFactor(self): plt.plot(self.f_value, label='factor value') plt.title('factor value curve') plt.legend() plt.grid() plt.show() def CalFactor(self): for k in sorted(self.m.keys()): df = self.m[k] df['factor'] = self.cal(df) self.f_value += df['factor'].tolist() @abstractmethod def cal(self, df): pass def LoadData(self, start_date, end_date, ticker): dl = dateRange(start_date, end_date) m = {} for date in dl: path = '/root/' + date + '/' + ticker + '.csv' if os.path.exists(path): m[date] = self.ReadData(date, ticker) else: print("%s not existed!" % (path)) return m def ReadData(self, date, ticker): path = '/root/' + date + '/' + ticker + '.csv' df = pd.read_csv(path, header=None) df.columns = shot.get_columns() df['mid'] = (df['asks[0]'] + df['bids[0]']) / 2 df['return1'] = df['mid'].diff(1).fillna(0.0) / df['mid'] return df