| Overall Statistics |
|
Total Trades 2282 Average Win 0.55% Average Loss -0.56% Compounding Annual Return -2.081% Drawdown 36.300% Expectancy -0.033 Net Profit -22.314% Sharpe Ratio -0.176 Probabilistic Sharpe Ratio 0.000% Loss Rate 52% Win Rate 48% Profit-Loss Ratio 1.00 Alpha -0.032 Beta 0.129 Annual Standard Deviation 0.079 Annual Variance 0.006 Information Ratio -0.943 Tracking Error 0.163 Treynor Ratio -0.107 Total Fees $0.00 Estimated Strategy Capacity $1900000.00 |
class DeterminedRedOrangeAnt(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2008, 12, 1) # Set Start Date
self.SetEndDate(2020, 12, 1)
self.SetCash(100000) # Set Strategy Cash
#EURUSD", "USDJPY", "GBPUSD", "AUDUSD" "USDCAD",
#"GBPJPY", "EURUSD", "AUDUSD", "EURJPY", "EURGBP"
self.Data = {}
for ticker in ["EURUSD","NZDUSD","USDJPY"]:
symbol = self.AddForex(ticker, Resolution.Hour, Market.FXCM).Symbol
self.Data[symbol] = SymbolData(self, symbol)
self.stopLossLevel = -0.05 # stop loss percentage
self.stopProfitLevel = 0.01# stop profit percentage
self.SetWarmUp(25, Resolution.Hour)
def OnData(self, data):
if self.IsWarmingUp:
return
for symbol, symbolData in self.Data.items():
if not (data.ContainsKey(symbol) and data[symbol] is not None and symbolData.IsReady):
continue
ADX = symbolData.adx.Current.Value
RSI = symbolData.rsi.Current.Value
current_price = data[symbol].Close
# Condition to begin if ADX value is greater than 25
if (not ADX > 25):
return
if self.Portfolio[symbol].Invested:
if self.isLong:
condStopProfit = (current_price - self.buyInPrice)/self.buyInPrice > self.stopProfitLevel
condStopLoss = (current_price - self.buyInPrice)/self.buyInPrice < self.stopLossLevel
if condStopProfit:
self.Liquidate(symbol)
self.Log(f"{self.Time} Long Position Stop Profit at {current_price}")
if condStopLoss:
self.Liquidate(symbol)
self.Log(f"{self.Time} Long Position Stop Loss at {current_price}")
else:
condStopProfit = (self.sellInPrice - current_price)/self.sellInPrice > self.stopProfitLevel
condStopLoss = (self.sellInPrice - current_price)/self.sellInPrice < self.stopLossLevel
if condStopProfit:
self.Liquidate(symbol)
self.Log(f"{self.Time} Short Position Stop Profit at {current_price}")
if condStopLoss:
self.Liquidate(symbol)
self.Log(f"{self.Time} Short Position Stop Loss at {current_price}")
if not self.Portfolio[symbol].Invested:
lbbclose = symbolData.closeWindow[20] # self.closeWindow[20]
lbsclose = symbolData.closeWindow[10] # self.closeWindow[10]
if RSI < 50 and current_price < lbbclose and current_price > lbsclose:
self.SetHoldings(symbol, 1)
# get buy-in price for trailing stop loss/profit
self.buyInPrice = current_price
# entered long position
self.isLong = True
self.Log(f"{self.Time} Entered Long Position at {current_price}")
if RSI > 50 and current_price > lbbclose and current_price < lbsclose:
self.SetHoldings(symbol, 0)
# get sell-in price for trailing stop loss/profit
self.sellInPrice = current_price
# entered short position
self.isLong = False
self.Log(f"{self.Time} Entered Short Position at {current_price}")
class SymbolData:
def __init__(self, algorithm, symbol):
self.adx = algorithm.ADX(symbol, 14, Resolution.Hour)
self.rsi = algorithm.RSI(symbol, 14, Resolution.Hour)
self.adxWindow = RollingWindow[IndicatorDataPoint](2) #setting the Rolling Window for the fast SMA indicator, takes two values
self.adx.Updated += self.AdxUpdated #Updating those two values
self.rsiWindow = RollingWindow[IndicatorDataPoint](2) #setting the Rolling Window for the slow SMA indicator, takes two values
self.rsi.Updated += self.RsiUpdated #Updating those two values
self.closeWindow = RollingWindow[float](21)
# Add consolidator to track rolling close prices
self.consolidator = QuoteBarConsolidator(1)
self.consolidator.DataConsolidated += self.CloseUpdated
algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
def AdxUpdated(self, sender, updated):
'''Event holder to update the fast SMA Rolling Window values'''
if self.adx.IsReady:
self.adxWindow.Add(updated)
def RsiUpdated(self, sender, updated):
'''Event holder to update the slow SMA Rolling Window values'''
if self.rsi.IsReady:
self.rsiWindow.Add(updated)
def CloseUpdated(self, sender, bar):
'''Event holder to update the close Rolling Window values'''
self.closeWindow.Add(bar.Close)
@property
def IsReady(self):
return self.adx.IsReady and self.rsi.IsReady and self.closeWindow.IsReady