Hey,
I already have list of Support levels of the Daily chart and of the 4hr timeframe, as well as resistance levels of daily and 4 hour timeframe. The challenge i have is, how do i identify the most relevant support and resitance level? (The ones closest to my current_price) so that i can use it as a condition to trade. depending on how close i am to it.
Here is my code block for the Daily support and resistance levels:
from datetime import datetime,timedelta
import numpy as np
class ReversalAlpha(QCAlgorithm):
def Initialize(self):
tickers = ["EURUSD","USDCAD"]
# Rolling Windows to hold bar close data keyed by symbol
self.closingData = {}
for ticker in tickers:
symbol = self.AddForex(ticker, Resolution.Daily, Market.Oanda).Symbol
self.closingData[symbol] = RollingWindow[float](50)
# Warm up our rolling windows
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(): #references the key-value pairs in the dictionary
supports_D, resistances_D = self.GetPriceLevels(window) # Daily Supports and Daily Resistances
self.Log(f"Symbol: {symbol.Value} , Supports: {supports_D} , Resistances: {resistances_D}")
def GetPriceLevels(self, series, variation = 0.005, h = 3):
supports_D = [] # List that will hold daily Supports points
resistances_D = [] # List that will hold daily Resistances points
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_D:
resistances_D.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_D:
supports_D.append(level)
return supports_D, resistances_D
# Your New Python File
as well as the code block for the 4hr support and resistance;
from datetime import datetime,timedelta
import numpy as np
class ReversalBeta(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 30) # Set Start Date
self.SetEndDate(2020, 12, 30)
self.SetCash(100000) # Set Strategy Cash
tickers = ["EURUSD","USDCAD"]
# Rolling Windows to hold bar close data keyed by symbol
self.closingData = {} # Dictionary to hold a rolling window with bar close data for each ticker symbol
for ticker in tickers:
symbol = self.AddForex(ticker, Resolution.Hour, Market.Oanda).Symbol
self.closingData[symbol] = SymbolData(self, symbol) #RollingWindow[float](50)
# Warm up our rolling windows
self.SetWarmUp(50)
def OnData(self, data):
if self.IsWarmingUp:
return
for symbol, symbolData in self.closingData.items(): #Returns self.closingData's dictionary key-value pairs
if not (data.ContainsKey(symbol) and data[symbol] is not None and symbolData.IsReady):
continue
for symbol, window in self.closingData.items(): #references the key-value pairs in the dictionary
supports_4H, resistances_4H = self.GetPriceLevels(window) #4 Hour Support and resistances
self.Log(f"Symbol: {symbol.Value} , Supports: {supports_4H} , Resistances: {resistances_4H}")
def GetPriceLevels(self, series, variation = 0.01, h = 3):
supports_4H = [] # List that will hold 4 hour Supports points
resistances_4H = [] # List that will hold 4 hour resistance points
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_4H:
resistances_4H.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_4H:
supports_4H.append(level)
return supports_4H, resistances_4H
#creating a class for consolidating data into 4hour time frames
class SymbolData:
def __init__(self, algorithm, symbol):
self.closeWindow = RollingWindow[float](50)
# Add consolidator to track rolling close prices
self.consolidator = TradeBarConsolidator(4)
self.consolidator.DataConsolidated += self.CloseUpdated
algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
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.closeWindow.IsReady
#the next support is the one with the smallest difference between current price
#since we have a list of support levels we need to merge the 4hr and the daily support level into one list
# and then rank them from them in decsending order
# we can further process the support data and resitance data gathered from above, by perhaps creating another function.
# where the final output will be directly below or above the current price.
Varad Kabade
Hi Samwel,
Refer to this related thread.
Best,
Varad Kabade
Samwel Kibet
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!