| Overall Statistics |
|
Total Trades 6701 Average Win 0.42% Average Loss -0.28% Compounding Annual Return 25.973% Drawdown 33.400% Expectancy 0.148 Net Profit 278.557% Sharpe Ratio 1.199 Probabilistic Sharpe Ratio 61.331% Loss Rate 55% Win Rate 45% Profit-Loss Ratio 1.53 Alpha 0.121 Beta 0.548 Annual Standard Deviation 0.156 Annual Variance 0.024 Information Ratio 0.446 Tracking Error 0.149 Treynor Ratio 0.342 Total Fees $167953.96 Estimated Strategy Capacity $130000.00 Lowest Capacity Asset TLSA WZ7AA7WL40H1 |
'''
RAPHAEL TRADING STRATEGY
------------------------
This is a basic trend following trading strategy
created using the RSI, MACD, and Exponential MA
-
Created by Philson
https://github.com/AzureKn1ght
-
'''
class Raphael(QCAlgorithm):
def Initialize(self):
# Training Period: 2010-2016
# Test Period: 2016-Present
self.SetStartDate(2016, 1, 1) # Set Start Date
# self.SetEndDate(2016, 1, 1) # Set End Date
# Set Strategy Cash
self.SetCash(1000000)
# Assets to Trade (See Presentation Document)
self.assets = ["MSFT","FB","APPL","GOOGL","AMZN","CRM","JPM","PFE","TLSA","NFLX","IAU","ATVI","MNSO","MDB","CRWD","AMD","DDOG","SE","ZM","MDY","EEM","PYPL","UNH","NVDA","EBAY","MA","TWTR","SQ","CME"]
# STRATEGY PARAMETERS (use this to optimize)
RSI_Period = 13 # Daily RSI Look back period
self.RSI_Threshold = 50 # RSI bullish threshold level
MACD_Fast = 12 # Hourly MACD fast EMA
MACD_Slow = 26 # Hourly MACD slow EMA
MACD_Signal = 9 # Hourly MACD signal length
EMA_Length = 34 # Hourly trend baseline EMA
# TRADING PRAMETERS (portfolio allocation, R/R ratio)
self.Allocation = 0.1 # Percentage of captital to allocate
ATR_Period = 13 # Hourly ATR period for stoploss
self.SL_Multiple = 2 # Multiple of ATR for stoploss
self.TP_Multiple = 4 # Multiple of ATR for TP [1 : 2]
# Warmup period to ensure enough indicator data
self.SetWarmUp(RSI_Period+1)
# Asset Object (Store the data in Dictionaries)
self.rsi = {}
self.macd = {}
self.ema = {}
self.atr = {}
self.prev_macd = {}
self.prev_macd_signal = {}
self.entry_price = {}
self.take_profit = {}
self.stoploss = {}
# Initialize all the asset variables
for i in self.assets:
self.AddEquity(i, Resolution.Hour)
self.rsi[i] = self.RSI(i, RSI_Period, Resolution.Daily)
self.macd[i] = self.MACD(i, MACD_Fast, MACD_Slow, MACD_Signal, Resolution.Hour)
self.ema[i] = self.EMA(i, EMA_Length, Resolution.Hour)
self.atr[i] = self.ATR(i, ATR_Period, Resolution.Hour)
self.prev_macd[i] = None
self.prev_macd_signal[i] = None
self.entry_price[i] = None
self.take_profit[i] = None
self.stoploss[i] = None
self.Debug("RAPHAEL: STRATEGY STARTED")
# Function to act on every incoming data bar
def OnData(self, data):
# check if indicators ready
if self.IsWarmingUp: return
# check through all the assets
for asset in self.assets:
if data.ContainsKey(asset) and not data[asset] == None:
# Already invested, check for exit conditions
if self.Securities[asset].Invested:
self.CheckTPandSL(asset, data)
# Not invested, check whether we should enter
else:
self.CheckEntryCondition(asset, data)
# Update prev_macd and prev_macd_signal data
self.prev_macd[asset] = self.macd[asset].Current.Value
self.prev_macd_signal[asset] = self.macd[asset].Signal.Current.Value
# Function to check TP/SL and exit accordingly
def CheckTPandSL(self, asset, data):
if self.stoploss[asset] == None or self.take_profit[asset] == None: return
if data[asset].Close <= self.stoploss[asset]:
self.Liquidate(asset, "stop-loss")
self.entry_price[asset] = None
self.take_profit[asset] = None
self.stoploss[asset] = None
self.Debug(str(asset) + " stoploss hit: " + str(data[asset].Close))
elif data[asset].High >= self.take_profit[asset]:
self.Liquidate(asset, "take-profit")
self.entry_price[asset] = None
self.take_profit[asset] = None
self.stoploss[asset] = None
self.Debug(str(asset) + " profit taken: " + str(data[asset].Close))
# Function to check for entry conitions and buy
def CheckEntryCondition(self, asset, data):
if self.prev_macd[asset] == None or self.rsi[asset] == None: return
# Calculate TP and SL based on ATR
ATR = self.atr[asset].Current.Value
TP = data[asset].Close + ATR * self.TP_Multiple
SL = data[asset].Close - ATR * self.SL_Multiple
# Check for bullish daily RSI
RSI_Bullish = self.rsi[asset].Current.Value > self.RSI_Threshold
# Check for uptrend in Price
EMA = self.ema[asset].Current.Value
Uptrend = (data[asset].Open > EMA) and (data[asset].Close > EMA)
# Check for bullish MACD cross
MACD_Cross = (self.prev_macd[asset] < self.prev_macd_signal[asset]) \
and (self.macd[asset].Current.Value > self.macd[asset].Signal.Current.Value)
if RSI_Bullish and Uptrend and MACD_Cross and not self.Securities[asset].Invested:
self.Debug("--- Buy Signal Triggered ---")
self.SetHoldings(asset, self.Allocation)
self.entry_price[asset] = data[asset].Close
self.take_profit[asset] = TP
self.stoploss[asset] = SL
self.Debug("Bought: " + str(asset) + " at " + str(self.entry_price[asset]))
self.Debug("Take Profit: " + str(self.take_profit[asset]))
self.Debug("Stoploss: " + str(self.stoploss[asset]))