コード例 #1
0
    def stop(self):
        # 防止除以0
        if len(self.pnlWins) > 0 and len(self.pnlLosses) > 0:

            avgWins = average(self.pnlWins)  # 计算平均盈利
            avgLosses = abs(average(self.pnlLosses))  # 计算平均亏损(取绝对值)
            winLossRatio = avgWins / avgLosses  # 盈亏比

            if winLossRatio == 0:
                kellyPercent = None
            else:
                numberOfWins = len(self.pnlWins)  # 获胜次数
                numberOfLosses = len(self.pnlLosses)  # 亏损次数
                numberOfTrades = numberOfWins + numberOfLosses  # 总交易次数
                winProb = numberOfWins / numberOfTrades  # 计算胜率
                inverse_winProb = 1 - winProb

                # 计算凯利比率
                # 即每次交易投入资金占总资金的最优比率
                kellyPercent = winProb - (inverse_winProb / winLossRatio)
        else:
            kellyPercent = None  # 信息不足

        self.rets.kellyRatio = kellyPercent  # 例如 0.215
        self.rets.kellyPercent = kellyPercent * 100  # 例如 21.5
コード例 #2
0
    def stop(self):
        # There must be at least one winning trade and one losing trade to
        # Calculate Kelly percent. Else get a division by zero error.
        if len(self.pnlWins) > 0 and len(self.pnlLosses) > 0:

            # Calculate average wins and losses
            avgWins = average(self.pnlWins)
            avgLosses = abs(average(self.pnlLosses))  # Remove the -ve sign
            winLossRatio = avgWins / avgLosses

            # Check winLoss ratio not 0 else division by zero later because
            # otherwise a rare bug can occur if all winners have value of 0.
            # (Since BT convention is to class trades with profit >=0 as a
            # winner)
            if winLossRatio == 0:
                kellyPercent = None  # Because average of winners were 0.

            else:
                # Calculate probability of winning from our data.
                # Number of wins divide by number of trades.
                numberOfWins = len(self.pnlWins)
                numberOfLosses = len(self.pnlLosses)
                numberOfTrades = numberOfWins + numberOfLosses
                winProb = numberOfWins / numberOfTrades
                inverse_winProb = 1 - winProb

                # Now calculate Kelly percentage
                # i.e. optimal percent of account to risk on each trade.
                kellyPercent = winProb - (inverse_winProb / winLossRatio)

        else:
            kellyPercent = None  # Not enough information to calculate.

        self.rets.kellyRatio = kellyPercent  # e.g. 0.215
        self.rets.kellyPercent = kellyPercent * 100  # e.g. 21.5
コード例 #3
0
ファイル: sharpe.py プロジェクト: dafyddd/backtrader
    def stop(self):
        super(SharpeRatio, self).stop()
        if self.p.legacyannual:
            retfree = [self.p.riskfreerate] * len(self.anret.rets)
            retavg = average(list(map(operator.sub, self.anret.rets, retfree)))
            retdev = standarddev(self.anret.rets)

            self.ratio = retavg / retdev
        else:
            rate = self.p.riskfreerate
            factor = None
            if self.p.timeframe in self.RATEFACTORS:
                # rate provided on an annual basis ... downgrade it
                factor = self.RATEFACTORS[self.p.timeframe]
            elif self.p.timeframe == TimeFrame.Days:
                factor = self.p.daysfactor

            if factor is not None:
                rate = math.pow(1.0 + rate, 1.0 / factor) - 1.0

            returns = list(itervalues(self.timereturn.get_analysis()))
            retfree = itertools.repeat(rate)

            ret_free = map(operator.sub, returns, retfree)
            ret_free_avg = average(list(ret_free))
            retdev = standarddev(returns)

            if retdev != 0:
                self.ratio = ret_free_avg / retdev if self.p.convertrate else (factor ** .5) * ret_free_avg / retdev
            else:
                self.ratio = None
            self.rets['sharperatio'] = self.ratio
コード例 #4
0
ファイル: sharpe.py プロジェクト: rlcjj/backtrader
    def stop(self):
        if self.p.legacyannual:
            retfree = [self.p.riskfreerate] * len(self.anret.rets)
            retavg = average(list(map(operator.sub, self.anret.rets, retfree)))
            retdev = standarddev(self.anret.rets)

            self.ratio = retavg / retdev
        else:
            rate = self.p.riskfreerate
            if self.p.convertrate:
                factor = None
                if self.p.timeframe in self.RATEFACTORS:
                    # rate provided on an annual basis ... downgrade it
                    factor = self.RATEFACTORS[self.p.timeframe]
                elif self.p.timeframe == TimeFrame.Days:
                    factor = self.p.daysfactor

                if factor is not None:
                    rate = math.pow(1.0 + rate, 1.0 / factor) - 1.0

            returns = list(itervalues(self.timereturn.get_analysis()))
            retfree = itertools.repeat(rate)

            ret_free = map(operator.sub, returns, retfree)
            ret_free_avg = average(list(ret_free))
            retdev = standarddev(returns)

            self.ratio = ret_free_avg / retdev
コード例 #5
0
    def stop(self):
        super(SharpeRatio, self).stop()
        if self.p.legacyannual:
            rate = self.p.riskfreerate
            retavg = average([r - rate for r in self.anret.rets])
            retdev = standarddev(self.anret.rets)

            self.ratio = retavg / retdev
        else:
            # Get the returns from the subanalyzer
            returns = list(itervalues(self.timereturn.get_analysis()))

            rate = self.p.riskfreerate  #

            factor = None

            # Hack to identify old code
            if self.p.timeframe == TimeFrame.Days and \
               self.p.daysfactor is not None:

                factor = self.p.daysfactor

            else:
                if self.p.factor is not None:
                    factor = self.p.factor  # user specified factor
                elif self.p.timeframe in self.RATEFACTORS:
                    # Get the conversion factor from the default table
                    factor = self.RATEFACTORS[self.p.timeframe]

            if factor is not None:
                # A factor was found

                if self.p.convertrate:
                    # Standard: downgrade annual returns to timeframe factor
                    rate = pow(1.0 + rate, 1.0 / factor) - 1.0
                else:
                    # Else upgrade returns to yearly returns
                    returns = [pow(1.0 + x, factor) - 1.0 for x in returns]

            # Get the excess returns - arithmetic mean - original sharpe
            ret_free = [r - rate for r in returns]
            ret_free_avg = average(ret_free)
            retdev = standarddev(ret_free,
                                 avgx=ret_free_avg,
                                 bessel=self.p.stddev_sample)

            try:
                ratio = ret_free_avg / retdev

                if factor is not None and \
                   self.p.convertrate and self.p.annualize:

                    ratio = math.sqrt(factor) * ratio
            except (ValueError, TypeError, ZeroDivisionError):
                ratio = None

            self.ratio = ratio

        self.rets['sharperatio'] = self.ratio
コード例 #6
0
ファイル: sharpe.py プロジェクト: remroc/backtrader
    def stop(self):
        super(SharpeRatio, self).stop()
        if self.p.legacyannual:
            rate = self.p.riskfreerate
            retavg = average([r - rate for r in self.anret.rets])
            retdev = standarddev(self.anret.rets)

            self.ratio = retavg / retdev
        else:
            # Get the returns from the subanalyzer
            returns = list(itervalues(self.timereturn.get_analysis()))

            rate = self.p.riskfreerate  #

            factor = None

            # Hack to identify old code
            if self.p.timeframe == TimeFrame.Days and \
               self.p.daysfactor is not None:

                factor = self.p.daysfactor

            else:
                if self.p.factor is not None:
                    factor = self.p.factor  # user specified factor
                elif self.p.timeframe in self.RATEFACTORS:
                    # Get the conversion factor from the default table
                    factor = self.RATEFACTORS[self.p.timeframe]

            if factor is not None:
                # A factor was found

                if self.p.convertrate:
                    # Standard: downgrade annual returns to timeframe factor
                    rate = pow(1.0 + rate, 1.0 / factor) - 1.0
                else:
                    # Else upgrade returns to yearly returns
                    returns = [pow(1.0 + x, factor) - 1.0 for x in returns]

            # Get the excess returns - arithmetic mean - original sharpe
            ret_free = [r - rate for r in returns]
            ret_free_avg = average(ret_free)
            retdev = standarddev(ret_free, avgx=ret_free_avg,
                                 bessel=self.p.stddev_sample)

            try:
                ratio = ret_free_avg / retdev

                if factor is not None and \
                   self.p.convertrate and self.p.annualize:

                    ratio = math.sqrt(factor) * ratio
            except (ValueError, TypeError):
                ratio = None

            self.ratio = ratio

        self.rets['sharperatio'] = self.ratio
コード例 #7
0
ファイル: sqn.py プロジェクト: johndpope/broker
    def stop(self):
        pnl_av = average(self.pnl)
        pnl_stddev = standarddev(self.pnl)

        trades_sqr = pow(len(self.pnl), 0.5)

        sqn = trades_sqr * pnl_av / pnl_stddev

        self.ret.sqn = sqn
        self.ret.trades = self.count
コード例 #8
0
    def stop(self):
        if self.count > 1:
            pnl_av = average(self.pnl)
            pnl_stddev = standarddev(self.pnl)
            sqn = math.sqrt(len(self.pnl)) * pnl_av / pnl_stddev
        else:
            sqn = 0

        self.rets.sqn = sqn
        self.rets.trades = self.count
コード例 #9
0
ファイル: sqn.py プロジェクト: slipdigital/backtrader
    def stop(self):
        pnl_av = average(self.pnl)
        pnl_stddev = standarddev(self.pnl)

        trades_sqr = math.sqrt(len(self.pnl))

        sqn = trades_sqr * pnl_av / pnl_stddev

        self.rets.sqn = sqn
        self.rets.trades = self.count
コード例 #10
0
ファイル: sqn.py プロジェクト: remroc/backtrader
    def stop(self):
        if self.count > 1:
            pnl_av = average(self.pnl)
            pnl_stddev = standarddev(self.pnl)
            sqn = math.sqrt(len(self.pnl)) * pnl_av / pnl_stddev
        else:
            sqn = 0

        self.rets.sqn = sqn
        self.rets.trades = self.count
コード例 #11
0
ファイル: sqn.py プロジェクト: nooperpudd/backtrader
    def stop(self):
        pnl_av = average(self.pnl)
        pnl_stddev = standarddev(self.pnl)

        trades_sqr = pow(len(self.pnl), 0.5)

        sqn = trades_sqr * pnl_av / pnl_stddev

        self.ret.sqn = sqn
        self.ret.trades = self.count
コード例 #12
0
ファイル: sqn.py プロジェクト: aaron8tang/backtrader
    def stop(self):
        if self.count > 1:
            pnl_av = average(self.pnl)
            pnl_stddev = standarddev(self.pnl)
            try:
                sqn = math.sqrt(len(self.pnl)) * pnl_av / pnl_stddev
            except ZeroDivisionError:
                sqn = None
        else:
            sqn = 0

        self.rets.sqn = sqn
        self.rets.trades = self.count
コード例 #13
0
    def stop(self):
        if self.count > 1:
            pnl_av = average(self.pnl)
            pnl_stddev = standarddev(self.pnl)
            try:
                sqn = math.sqrt(len(self.pnl)) * pnl_av / pnl_stddev
            except ZeroDivisionError:
                sqn = None
        else:
            sqn = 0

        self.rets.sqn = sqn
        self.rets.trades = self.count
コード例 #14
0
    def stop(self):
        trets = self._tr.get_analysis()  # dict key = date, value = ret
        pos = nul = neg = 0
        trets = list(itervalues(trets))
        for tret in trets:
            if tret > 0.0:
                pos += 1
            elif tret < 0.0:
                neg += 1
            else:
                if self.p.zeroispos:
                    pos += tret == 0.0
                else:
                    nul += tret == 0.0

        self.rets['average'] = avg = average(trets)
        self.rets['stddev'] = standarddev(trets, avg)

        self.rets['positive'] = pos
        self.rets['negative'] = neg
        self.rets['nochange'] = nul

        self.rets['best'] = max(trets)
        self.rets['worst'] = min(trets)
コード例 #15
0
ファイル: periodstats.py プロジェクト: aaron8tang/backtrader
    def stop(self):
        trets = self._tr.get_analysis()  # dict key = date, value = ret
        pos = nul = neg = 0
        trets = list(itervalues(trets))
        for tret in trets:
            if tret > 0.0:
                pos += 1
            elif tret < 0.0:
                neg += 1
            else:
                if self.p.zeroispos:
                    pos += tret == 0.0
                else:
                    nul += tret == 0.0

        self.rets['average'] = avg = average(trets)
        self.rets['stddev'] = standarddev(trets, avg)

        self.rets['positive'] = pos
        self.rets['negative'] = neg
        self.rets['nochange'] = nul

        self.rets['best'] = max(trets)
        self.rets['worst'] = min(trets)
コード例 #16
0
ファイル: sharpe-forensic.py プロジェクト: Aulla/backtrader
    def stop(self):
        retfree = [self.p.riskfreerate] * len(self.anret.rets)
        retavg = average(list(map(operator.sub, self.anret.rets, retfree)))
        retdev = standarddev(self.anret.rets)

        self.ratio = retavg / retdev
コード例 #17
0
def Stock_Hsi_Diff_Sqn(equity, startdate, enddate=end, period=p):
    index="^HSI"

    df1=pd.DataFrame()      # df1 is equity
    df2=pd.DataFrame()      # df2 is index
    df3=pd.DataFrame()      # df3 is the joined dataframe
    df_result=pd.DataFrame(columns=['Date', 'sqn', 'Close'])
    
#    print("\r\n\r\n     ====  Loading stock", equity, " ====\r\n")
#    df1=GetYahooData(equity, startdate, ed=date(2018,3,15) )
    df1=GetYahooData(equity, startdate, enddate )
#    print(df1)
#    print("\r\n\r\n     ====  Loading index", index, " ====\r\n")
#    df2=GetYahooData(index, startdate, ed=date(2018,3,15))
    df2=GetYahooData(index, startdate, enddate)
    
    df1['pchg1']=(df1['Close']-df1['Close'].shift(1)) / df1['Close'] * 100  
    df2['pchg2']=(df2['Close']-df2['Close'].shift(1)) / df2['Close'] * 100  
    
   
    df1.columns=['Date', 'Open1','High1','Low1','Close1','Adj Close1','Volume1','pchg1']
    df2.columns=['Date', 'Open2','High2','Low2','Close2','Adj Close2','Volume2','pchg2']
    
    df1=df1.set_index('Date')
    df2=df2.set_index('Date')
    df3=pd.concat([df1, df2], axis=1, join='inner')
    
    df3['pertchange']=df3['pchg1'] - df3['pchg2']
    
#    df3['pertchange'].plot()
    
#    print(df3)

#    count = 0
#    print('len(df3):' , len(df3))
    for x in range(1, len(df3)-period):
        pnl = list()
        for i in df3['pertchange'][x:x+period]:
            pnl.append(i)
        
    #    print("pnl", pnl) 
        pnl_av = average(pnl)
        pnl_stddev = standarddev(pnl)
#        print("pnl_av: ", pnl_av, "pnl_stddev", pnl_stddev)
        
        try:
            sqn = math.sqrt(len(pnl)) * pnl_av / pnl_stddev
        except ZeroDivisionError:
            sqn = None
            print("ZeroDivisionError")
#        print(x, df3.index[x+99],': SQN: %.2f '% sqn, 'Closing: %.2f'% df3['Close1'][x+99])
        
        df_result=df_result.append({'Date':df3.index[x+period], 'sqn': sqn, 'Close':df3['Close1'][x+period] }, 
                                    ignore_index=True)
        
    df_result=df_result.set_index('Date')
    df_result.index = pd.to_datetime(df_result.index)
    
    print("Equity ", equity)
    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    ax1.set_title(equity, fontsize="large")
    ax1.plot(df_result['sqn'], 'silver', label = 'sqn (Equity - Index)')
    ax1.axhline(linewidth=1, color='k')
    ax1.set_ylabel('y1', color='silver')
#    for t1 in ax1.get_yticklabels():
#        t1.set_color('k')
    
    ax2 = ax1.twinx()
    ax2.plot(df_result['Close'], 'r-', label = equity)
    ax2.set_ylabel('y2', color='r')
#    for tl in ax2.get_yticklabels():
#        tl.set_color('r')
    ax1.legend(loc='upper center', bbox_to_anchor=(0.35, -0.2))
          
    ax2.legend(loc='upper center', bbox_to_anchor=(0.7, -0.2))
    fig.autofmt_xdate()
    
    plt.show()
#    df_result.plot()
    
    for x in range(1, len(df3)):
        pnl = list()
        for i in df3['pertchange'][1:]:
            pnl.append(i)
        pnl_av = average(pnl)
        pnl_stddev = standarddev(pnl) 
        try:
            sqn2 = math.sqrt(len(pnl)) * pnl_av / pnl_stddev
        except ZeroDivisionError:
            sqn2 = None
            print("ZeroDivisionError")
    print(equity, "has SQN nmber diff(stock-index)  %.2f"% sqn2)
コード例 #18
0
    def stop(self):
        retfree = [self.p.riskfreerate] * len(self.anret.rets)
        retavg = average(list(map(operator.sub, self.anret.rets, retfree)))
        retdev = standarddev(self.anret.rets)

        self.ratio = retavg / retdev
コード例 #19
0
        df1['pchg1'] = (df1['Close'] -
                        df1['Close'].shift(1)) / df1['Close'] * 100
        df1.columns = [
            'Date', 'Open1', 'High1', 'Low1', 'Close1', 'Adj Close1',
            'Volume1', 'pchg1'
        ]
        df1 = df1.set_index('Date')

        df3 = pd.concat([df1, df2], axis=1, join='inner')
        df3['pertchange'] = df3['pchg1'] - df3['pchg2']

        for x in range(1, len(df3)):
            pnl = list()
            for i in df3['pertchange'][1:]:
                pnl.append(i)
            pnl_av = average(pnl)
            pnl_stddev = standarddev(pnl)
            try:
                sqn2 = math.sqrt(len(pnl)) * pnl_av / pnl_stddev
            except ZeroDivisionError:
                sqn2 = None
                print("ZeroDivisionError")
        print(equity, "has SQN nmber %.2f" % sqn2)
        d[equity] = sqn2
    except:
        pass

# finnally, we print the sorted result:

for w in sorted(d, key=d.get, reverse=False):
    print(w, "%.2f" % d[w])
コード例 #20
0
ファイル: stock_sqn.py プロジェクト: ngamc/Python
def sqn(equity, num=default_num, list_table=False, graph=True):
    #
    # Define equity and start date of equity data
    #    equity="^HSI"
    startdate = date(2017, 1, 1)

    df = pd.DataFrame()
    df_result = pd.DataFrame(columns=['Date', 'sqn', 'Close'])

    df = GetYahooData(equity, startdate)  # download from yahoo directly
    #    df=GetYahooDataFromFile(equity, startdate )             # read local files
    if not isinstance(df, pd.DataFrame):
        return None
    df = df[pd.notnull(df['Close'])]
    df = df.reset_index(drop=True)

    df['pertchange'] = (df['Close'] - df['Close'].shift(1)) / df['Close'] * 100

    last_sqn = 0
    #    count = 0
    if list_table:
        print('No of trading days:', len(df))
    for x in range(1, len(df) - num - 1):
        pnl = list()
        for i in df['pertchange'][x:x + num]:
            pnl.append(i)

    #    print("pnl", pnl)
        pnl_av = average(pnl)
        pnl_stddev = standarddev(pnl)
        #        print("pnl_av: ", pnl_av, "pnl_stddev", pnl_stddev)

        try:
            sqn = math.sqrt(len(pnl)) * pnl_av / pnl_stddev
            if list_table:
                print(x, df['Date'][x + num], ': SQN: %.2f ' % sqn,
                      'Closing: %.2f' % df['Close'][x + num])
            df_result = df_result.append(
                {
                    'Date': df['Date'][x + num],
                    'sqn': sqn,
                    'Close': df['Close'][x + num]
                },
                ignore_index=True)
        except ZeroDivisionError:
            sqn = None
            print("ZeroDivisionError")
            if list_table:
                print(x, df['Date'][x + num],
                      ': SQN: Nan  Closing: %.2f' % df['Close'][x + num])

        if x == (len(df) - num -
                 2):  # if this is the last number, we record the sqn number
            last_sqn = df_result['sqn'].iloc[-1]

    if graph:
        fig = plt.figure()
        #        df_result['Date'] = pd.to_datetime(df_result['Date'])
        df_result.set_index('Date', inplace=True)
        ax1 = fig.add_subplot(111)
        ax1.plot(df_result['sqn'], label="SQN(99)")
        ax1.set_ylabel('y1')

        ax2 = ax1.twinx()
        ax2.plot(df_result['Close'], 'r-', label=equity)
        ax2.set_ylabel('y2', color='r')
        for tl in ax2.get_yticklabels():
            tl.set_color('r')
        ax1.legend(loc='upper center', bbox_to_anchor=(0.35, -0.05))
        ax2.legend(loc='upper center', bbox_to_anchor=(0.7, -0.05))
        ax1.set_title(equity)
        plt.show()

    return ("%.2f" % last_sqn)