Hi all, I would love to share an algorithm with you guys here! This algorithm, Forex Monday CCI Trend, trades the currency pair EUR/USD on Mondays based on the trend of the CCI (Commodity Channel Index) indicator. It aims to take 100-200 base points of profit for each trade, along with trailing stop-loss. In the Initialize() method, I set up all parameters we need and the CCI indicator provided by QC:
def Initialize(self):
self.SetStartDate(2018, 1, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
# add currency pair EUR/USD
self.symbol = self.AddForex("EURUSD", Resolution.Hour, Market.FXCM).Symbol
# parameters
self.CCIPeriod = 30 # CCI period
self.CCIupperBound = 100 # CCI upper bound line
self.CCIlowerBound = -100 # CCI lower bound line
self.stopLossLevel = -0.05 # stop loss percentage
self.stopProfitLevel = 0.01 # stop profit percentage
# Commodity Channel Index (https://en.wikipedia.org/wiki/Commodity_channel_index)
self.cci = self.CCI(self.symbol, self.CCIPeriod, MovingAverageType.Simple, Resolution.Daily)
The CCI indicator is described very clearly here. In the algorithm, if the CCI indicator crosses the CCIupperBound line from the bottom upwards on the current hourly candle, a buy order with predefined stop loss level and stop profit level is opened; if the CCI indicator crosses the CCIlowerBound line downwards, a sell order with predefined stop loss level and stop profit level is opened. When the forex order is opened, we will not consider opening another until the order is closed.
The idea of this algorithm is that we trade on Mondays depending on the price movements on Fridays, so we will only calculate the CCI indicator and open order on Mondays. I use the following way in OnData() method to achieve this:
### On Monday
if self.Time.weekday() == 0 and not self.Portfolio.Invested:
# get current value of CCI
CCI = self.cci.Current.Value
# enter long position if CCI is over UpperBound
if CCI > self.CCIupperBound:
self.SetHoldings(self.symbol.Value, 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}")
# enter short position if CCI is under LowerBound
if CCI < self.CCIlowerBound:
self.SetHoldings(self.symbol.Value, -1)
# 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}")
Then, when holding an order, this algorithm detects every opportunity to stop loss/profit whenever a new Bar comes in. Here the stopProfitLevel and stopLossLevel are set arbitrarily, so feel free to adjust them to get better performance.
### Stop loss/profit
if self.Portfolio.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(self.symbol.Value)
self.Log(f"{self.Time} Long Position Stop Profit at {current_price}")
if condStopLoss:
self.Liquidate(self.symbol.Value)
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(self.symbol.Value)
self.Log(f"{self.Time} Short Position Stop Profit at {current_price}")
if condStopLoss:
self.Liquidate(self.symbol.Value)
self.Log(f"{self.Time} Short Position Stop Loss at {current_price}")
The backtest is attached below. We encourage you to explore the code, and create better algorithms based on it!
Michael Manus
hm is it just me or are the overall statistics gone in the backtest? Daniel Chen
thanks for the example i will check that out
Jared Broad
Sorry, Michael, you're right... will try to fix it ASAP.
https://github.com/QuantConnect/Lean/issues/3330The 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.
Mitch Hankins
Thanks DanielChan
These examples are much appreciated :)
(especially with the lack of examples in regards to Forex)
Kenneth Wong
Thanks for sharing Daniel, very informative.
Daniel Chen
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!