Exemple #1
0
    def backTest(self):
        ''' Function that used to do back-testing based on the strategy you give
        Params: None
        
        Notes: this back-test function will move on minute bar and generate your 
        strategy detail dataframe by using the position vectors your strategy gives
        each minute
        '''

        format1 = h5py.File(self.data_format1_path, mode='r')
        format2 = h5py.File(self.data_format2_path, mode='r')
        assets = list(format1.keys())
        keys = list(format2.keys())

        for i in range(len(keys)):
            data_cur_min = format2[keys[i]][:]
            # 1. initialization
            if i == 0:
                total_balance = self.init_cash
                average_price_old = np.mean(data_cur_min[:, :4], axis=1)
                position_old = np.repeat(0., 4)
                position_new = np.repeat(0., 4)
                details = list()
                stop_signal = False

            # 2. calculate position & cash/crypto/total balance & transaction cost etc.
            position_change = position_new - position_old
            mask = np.abs(position_change) > .25 * data_cur_min[:, 4]
            position_change[mask] = (.25 * data_cur_min[:, 4] *
                                     np.sign(position_change))[mask]
            position_new = position_old + position_change
            average_price = np.mean(data_cur_min[:, :4], axis=1)
            transaction_cost = np.sum(
                np.abs(position_change) * average_price * self.commissionRatio)
            revenue = np.sum(
                position_old *
                (average_price - average_price_old)) - transaction_cost
            crypto_balance = np.sum(np.abs(position_new * average_price))
            total_balance = total_balance + revenue
            cash_balance = total_balance - crypto_balance
            detail = np.append(
                position_new,
                list(average_price) + [
                    cash_balance, crypto_balance, revenue, total_balance,
                    transaction_cost
                ])
            details.append(copy.deepcopy(detail))

            position_old = copy.deepcopy(position_new)
            average_price_old = copy.deepcopy(average_price)

            # 3. check special cases
            # if cash balance is less than lower limit, the program will stop all trading actions in the future
            if (cash_balance < self.cash_balance_lower_limit) and (stop_signal
                                                                   == False):
                stop_signal = True
                print("Current cash balance is lower than",
                      self.cash_balance_lower_limit)
                print("Your strategy is forced to stop")
                print(
                    "System will soon close all your positions (long and short) on crypto currencies"
                )

            if stop_signal:
                position_new = np.repeat(0., 4)
                if '09:30:00' in keys[i]:
                    print(keys[i][:10])
                continue

            # Update position and memory
            [position_new, self.memory
             ] = handle_bar(i, keys[i], data_cur_min, self.init_cash,
                            self.commissionRatio, cash_balance, crypto_balance,
                            total_balance, position_new, self.memory)

            # Update position and timer
            if '09:30:00' in keys[i]:
                print(keys[i][:10])

        detailCol = assets + [s + '_price' for s in assets] + [
            "cash_balance", "crypto_balance", "revenue", "total_balance",
            "transaction_cost"
        ]
        detailsDF = pd.DataFrame(details,
                                 index=pd.to_datetime(keys),
                                 columns=detailCol)

        format1.close()
        format2.close()
        return detailsDF
Exemple #2
0
 def backTest(self):
     ''' Function that used to do back-test based on the strategy you give
     
     Params: None
     
     Notes: this back-test function will move on minute bar and generate your 
     strategy detail dataframe by using the position matrix your strategy gives
     each minute
     
     Data: 
     1. Load futures information matrix and trading data during backtesting period
     2. You can load different .h5 file by changing the path down below to paths like
     self.train_data_path or self.test_data_path so that you can test and train your
     own strategy on different periods
     3. Try to make your strategy profitable and achieve stable return
     '''
     
     info = pd.read_csv(self.info_path, encoding='utf-8')
     btData = h5py.File(self.data_format2_path, mode='r')
     keys = list(btData.keys())
     
     # PnL initialization
     timer = 0
     pnl = self.init_cash
     details = list()
     detail = [np.repeat(0.,13), self.init_cash, 0., 0., self.init_cash, 0.]
     lastPosition = np.repeat(0, 13)
     
     for i in range(len(keys)-1):
         # Data of current minute and next minute
         data_cur_min = btData[keys[i]][:]
         exe_cur_min = np.mean(data_cur_min[:,:4], axis=1)
         exe_next_min = np.mean(btData[keys[i+1]][:,:4], axis=1)
         
         # Update position and parameter
         [curPosition, self.memory] = handle_bar(timer, data_cur_min, info, self.init_cash, self.commissionRatio, detail, self.memory)
         
         # Calculate margin required and commission charged
         marginRequired = np.matmul(np.abs(curPosition), (exe_next_min * info.unit_per_lot * info.margin_rate))
         transactionVolume = np.matmul(np.abs(curPosition-lastPosition), (exe_next_min * info.unit_per_lot))
         commission = transactionVolume * self.commissionRatio
         
         # Check and update pnl
         dataChange = exe_next_min - exe_cur_min
         revenue_min = np.matmul(lastPosition, dataChange * info.unit_per_lot)
         pnl = pnl + revenue_min - commission
         
         # Check if strategy losses too much
         assert pnl > self.margin_threshold, "Too much loss, strategy failed"
         
         # Check if margin requirement is satisfied
         assert marginRequired <= pnl, "You don't have enough margin"
         
         # Keep record
         detail = [curPosition, pnl-marginRequired, marginRequired, revenue_min, pnl, commission]
         details.append(copy.deepcopy(detail))
         
         # Update position and timer
         lastPosition = copy.deepcopy(curPosition)
         timer+=1
         if '09:30:00' in keys[i]:
             print(keys[i][:10])
         
     detailCol = ["postion","cash_balance", "margin_balance", "revenue", "total_balance", "transaction_cost"]
     detailsDF = pd.DataFrame(details,index=pd.to_datetime(keys[:-1]),columns=detailCol)
     
     btData.close()
     return detailsDF