Overall Statistics
Total Trades
4951
Average Win
0.21%
Average Loss
-0.77%
Compounding Annual Return
-2.589%
Drawdown
36.000%
Expectancy
-0.013
Net Profit
-25.201%
Sharpe Ratio
-0.313
Probabilistic Sharpe Ratio
0.000%
Loss Rate
22%
Win Rate
78%
Profit-Loss Ratio
0.27
Alpha
-0.018
Beta
-0.012
Annual Standard Deviation
0.061
Annual Variance
0.004
Information Ratio
-0.856
Tracking Error
0.168
Treynor Ratio
1.561
Total Fees
$0.00
import numpy as np
import pandas as pd

from collections import *


# Reproduce RSI Delta strategy: https://medium.com/swlh/the-rsi-delta-indicator-enhancing-momentum-trading-c1d7ca03a8f8
# AUDCAD
# Resolution.Hour
# 2010-2020
# Delta RSI(5, 3)
# ATR(50)
# 40
# stopProfitPrice = price * (1 + (1 *atr))
# stopLossPrice = price * (1 - (4 * atr))

class ForexAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2010, 1, 1)
        self.SetCash(100000)
        
        # update prices every minute
        self.resolution = Resolution.Hour

        self.ticker = "AUDNZD"
        self.AddForex(self.ticker, self.resolution, Market.FXCM)

        self.daysInHistory = 10 

        self.atr = self.ATR(self.ticker, 50, self.resolution)
        self.rsi = self.RSI(self.ticker, MovingAverageType.Exponential, 5, self.resolution)

        self.history = deque(maxlen=self.daysInHistory)
        
    def OnData(self, data):
        if data.ContainsKey(self.ticker):
            self.history.append(self.rsi.Current.Value)
            
            price = data[self.ticker].Price

            if self.Portfolio.Invested:
                exit = False
                if self.long == 1:
                    if self.stopProfitPrice <= price:
                        exit = True
                    if self.stopLossPrice >= price:
                        exit = True
                else:
                    if self.stopProfitPrice >= price:
                        exit = True
                    if self.stopLossPrice <= price:
                        exit = True

                if exit:
                    self.SetHoldings(self.ticker, 0)
            else:
                if len(self.history) >= self.daysInHistory:
                    # history is ready
                    enter = False
                    limit = 40
                    
                    rsiCurrent = pd.DataFrame(np.array(self.history))
                    rsiDelta = rsiCurrent - rsiCurrent.shift(3)
                    rsiDelta = rsiDelta.values
    
                    if rsiDelta[-1] > limit and rsiDelta[-2] < limit and rsiDelta[-3] < limit:
                        enter = True
                        self.long = -1
                    elif rsiDelta[-1] < -limit and rsiDelta[-2] > -limit and rsiDelta[-3] > -limit:
                        enter = True
                        self.long = 1
    
                    if enter:
                        self.stopProfitPrice = price * (1 + self.long * (1 * self.atr.Current.Value))                    
                        self.stopLossPrice = price * (1 - self.long * (4 * self.atr.Current.Value))
                        self.SetHoldings(self.ticker, self.long)

    def OnEndOfAlgorithm(self):
        self.Liquidate()