| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.469 Tracking Error 0.346 Treynor Ratio 0 Total Fees $0.00 |
from datetime import datetime,timedelta
import numpy as np
class ReversalAlpha(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 30) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
tickers = ["EURUSD","USDCAD"]
# Rolling Windows to hold bar close data keyed by symbol
self.closingData = {}
for ticker in tickers:
symbol = self.AddForex(ticker, Resolution.Hour, Market.Oanda).Symbol
self.closingData[symbol] = RollingWindow[float](50)
# Warm up our rolling windows
self.SMA45 = SimpleMovingAverage(symbol, 45)
self.SetWarmUp(50)
def OnData(self, data):
for symbol, window in self.closingData.items():
if data.ContainsKey(symbol) and data[symbol] is not None:
window.Add(data[symbol].Close)
if self.IsWarmingUp or not all([window.IsReady for window in self.closingData.values()]):
return
for symbol, window in self.closingData.items():
supports, resistances = self.GetPriceLevels(window)
#self.Log(f"Symbol: {symbol.Value} , Supports: {supports} , Resistances: {resistances}")
self.Debug(self.SMA45.Current.Value)
if self.SMA45.Current.Value<0:
self.marketTicket=self.MarketOrder(symbol, -100000)
def GetPriceLevels(self, series, variation = 0.005, h = 3):
supports = []
resistances = []
maxima = []
minima = []
# finding maxima and minima by looking for hills/troughs locally
for i in range(h, series.Size-h):
if series[i] > series[i-h] and series[i] > series[i+h]:
maxima.append(series[i])
elif series[i] < series[i-h] and series[i] < series[i+h]:
minima.append(series[i])
# identifying maximas which are resistances
for m in maxima:
r = m * variation
# maxima which are near each other
commonLevel = [x for x in maxima if x > m - r and x < m + r]
# if 2 or more maxima are clustered near an area, it is a resistance
if len(commonLevel) > 1:
# we pick the highest maxima if the cluster as our resistance
level = max(commonLevel)
if level not in resistances:
resistances.append(level)
# identify minima which are supports
for l in minima:
r = l * variation
# minima which are near each other
commonLevel = [x for x in minima if x > l - r and x < l + r]
# if 2 or more minima are clustered near an area, it is a support
if len(commonLevel) > 1:
# We pick the lowest minima of the cluster as our support
level = min(commonLevel)
if level not in supports:
supports.append(level)
return supports, resistances