buy when it hit 20 day high; sell when it hit 20 day low. it has very few signal. somthing is wrong. can you please help
code:
from AlgorithmImports import *
# endregion
debugflag=True
deployflag=False
ticker="qqq"
resolution=Resolution.Hour
#resolution=Resolution.Daily
#resolution=Resolution.Minute
warmUPPeriod=200
cashlimit=100000
if deployflag:
cashlimit=1400
ticker_list=['spy']
#ticker_list=['gbtc','biti']
if debugflag:
cashvalue=100000
cashlimit=cashvalue
else:
cashvalue=cashlimit
#cashlimit=cashvalue/(len(ticker_list))
#cashlimit=cashvalue/2
subject='quantconnect'
body_buy="buy"
body_sell="sell"
RSI_overbought_threshold=70
RSI_oversold_threshold=30
Sto_overbought_threshold=80
Sto_oversold_threshold=20
ma_period=20
ma_fast_period=10
ma_slow_period=20
max_period=20
min_period=20
class MACDTrendAlgorithm(QCAlgorithm):
def Initialize(self):
#self.ticker="SPY"
if debugflag:
self.SetStartDate(2022, 1, 1)
#self.SetStartDate(2023, 1, 1)
#self.SetStartDate(2024, 1, 1)
#self.SetEndDate(2023, 1, 1)
#self.SetStartDate(2024, 1, 1)
self.SetEndDate(2024, 3, 1)
#self.SetEndDate(2018, 1, 1)
self.SetCash(cashlimit) # Find more symbols here: http://quantconnect.com/data
self.SetBrokerageModel(BrokerageName.TradierBrokerage, AccountType.Margin)
self.macd = dict()
self.max = dict()
self.min = dict()
self.preivousPrice=dict()
# create a 15 day exponential moving average
#self.fast = self.EMA(ticker, 5, interval)
# create a 30 day exponential moving average
#self.slow = self.EMA(ticker, 50, interval)
for ticker in ticker_list:
symbol = self.AddEquity(ticker, resolution).Symbol
value=symbol.Value
#self.bband[symbol] = self.BB(symbol, 20, 2, MovingAverageType.Simple, Resolution.Daily)
self.macd[symbol] =self.MACD(ticker, 12, 26, 9, MovingAverageType.Exponential)
self.max[symbol] = self.MAX(symbol, max_period,resolution )
self.min[symbol] = self.MIN(symbol, min_period,resolution)
self.preivousPrice[symbol]=-1
self.SetWarmUp(warmUPPeriod, resolution)
self.EnableAutomaticIndicatorWarmUp = True
# define our daily macd(12,26) with a 9 day signal
#self.__macd = self.MACD(ticker, 12, 26, 9, MovingAverageType.Exponential, Resolution.Hour)
#self.__macd = self.MACD(ticker, 12, 26, 9, MovingAverageType.Exponential)
self.__previous = datetime.min
#self.PlotIndicator("MACD", True, self.__macd, self.__macd.Signal)
#self.PlotIndicator(ticker, self.__macd.Fast, self.__macd.SlowStoch)
self.crossUp_MACDTOLERANCE =0
self.crossDown_MACDTOLERANCE= 0
#self.crossUp_MACDTOLERANCE = 0.002
#self.crossDown_MACDTOLERANCE= 0.002
stockPlot = Chart('Trade Plot')
from System.Drawing import Color
stockPlot.AddSeries(Series('Price', SeriesType.Line, '$', Color.Green))
stockPlot.AddSeries(Series('Buy', SeriesType.Scatter, '$', Color.Red, ScatterMarkerSymbol.Triangle))
stockPlot.AddSeries(Series('Sell', SeriesType.Scatter, '$', Color.Blue, ScatterMarkerSymbol.TriangleDown))
self.AddChart(stockPlot)
self.PlotIndicator("Trade Plot", self.max[symbol])
self.PlotIndicator("Trade Plot", self.min[symbol])
self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
#for x in ticker_list:
# self.crossDown_MACD[x]=False
# self.crossUp_MACD[x]=False
# self.crossPrice_MACD[x]=0
self.SetBenchmark("SPY")
def OnData(self, data):
#if not self.__macd.IsReady: return
if self.IsWarmingUp: return
#available_buying_power = self.Portfolio.GetBuyingPower(ticker, OrderDirection.Buy)
for symbol, macd in self.macd.items():
#if not (self.max[symbol].IsReady and self.min[symbol].IsReady): return
price = self.Securities[symbol].Price
self.Plot("Trade Plot", "Price", price)
holdings = self.Portfolio[symbol].Quantity
#price=data[symbol].Close
#nominator=macd.Fast.Current.Value if macd.Fast.Current.Value!=0 else 0.01
nominator=macd.Fast.Current.Value
#signalDeltaPercent = (macd.Current.Value - macd.Signal.Current.Value)/nominator
signalDeltaPercent = (macd.Current.Value - macd.Signal.Current.Value)
signalDeltaPrevious = macd.Previous.Value-macd.Signal.Previous.Value
available_buying_power = self.Portfolio.GetBuyingPower(symbol, OrderDirection.Buy)
#self.Portfolio.TotalPortfolioValue
#self.Portfolio.TotalFees
#cashlimit=available_buying_power
if holdings <= 0 and self.IsMarketOpen(symbol) and ( price >= self.max[symbol].Current.Value):
self.Log(f"Buying SPY | Holding: {holdings} | Delta%:{signalDeltaPercent} | UP_Tolerance{self.crossUp_MACDTOLERANCE}")
self.Log(f'cash limit: {cashlimit}, poto value {self.Portfolio.TotalPortfolioValue} buying power: {available_buying_power} fee: {self.Portfolio.TotalFees}')
shares= cashlimit/ price
self.Log(f'shares {shares}')
#self.SetHoldings(symbol, 1.0)
ticket=self.MarketOrder(symbol, shares)
self.Log(f'order status {ticket.Status}')
msg= "filled" if (ticket.Status == OrderStatus.Filled) else "notfilled"
self.Plot(symbol, "Buy", price)
self.Plot('Trade Plot', "Buy", price)
elif holdings > 0 and self.IsMarketOpen(symbol) and( price <= self.min[symbol].Current.Value):
self.Log(f"Selling SPY | Holding: {holdings} | Delta%:{signalDeltaPercent} | DOWN_Tolerance{self.crossDown_MACDTOLERANCE}")
#self.Liquidate(symbol)
#self.SetHoldings("SPY", -1.0)
security_holding = self.Portfolio[symbol]
shares= cashlimit/price
#self.MarketOrder(symbol, -shares)
self.Liquidate(symbol)
self.Plot(symbol, "Sell", price)
self.Plot('Trade Plot', "Sell", price)
#self.Notify.Email(email_address, subject, body_sell)
else:
pass
#self.Log(f"Nothing | Holding: {holdings} | Delta%:{signalDeltaPercent} | UP_Tolerance{self.crossUp_MACDTOLERANCE} | DOWN_Tolerance{self.crossDown_MACDTOLERANCE}")
self.preivousPrice[symbol]=price
#else:
# self.Error(f"Data Missing on: {self.Time}")
#if price < bband.LowerBand.Current.Value:
# self.MarketOrder(symbol, 1)
#for symbol, bband in self.bband.items():
# price = self.Securities[symbol].Price
# if price < bband.LowerBand.Current.Value:
# self.MarketOrder(symbol, 1)
#available_buying_power = self.Portfolio.GetBuyingPower(ticker, OrderDirection.Buy)
def OnBrokerageDisconnect(self) -> None:
self.Error("Brokerage connection lost")
def OnBrokerageReconnect(self) -> None:
self.Debug("Brokerage connection restored")
def OnBrokerageMessage(self, message_event: BrokerageMessageEvent) -> None:
self.Debug(f"Brokerage message received: {message_event.Message}")
Replyxf
I fix it by using price <= self.min[symbol].Previous.Value not sure why
Mia Alissi
It seems like 'Replyxf' is trying to address an issue with their trading algorithm by adjusting the condition under which a trade is executed. By using
price <= self.min[symbol].Previous.Value, they are likely trying to ensure that a trade is made only when the current price is less than or equal to the previous minimum price of the symbol in question. This condition could be part of a strategy to buy when the price is low, aiming to purchase assets at a favorable price point.The reason this adjustment might have fixed their issue could be related to the nature of financial markets, where prices are continuously fluctuating. By using the
<=operator, they allow for a bit more flexibility in their trading condition, which might help in scenarios where the price does not exactly match the previous minimum value but is close enough to be considered a good buying opportunity. This approach can help in avoiding missed opportunities due to the highly volatile and fast-moving nature of financial markets.Here's a simplified example of how this might be implemented in a QuantConnect algorithm:
In this example,
MinIndicatoris a hypothetical indicator that tracks the minimum price over a specified period. The key part is the conditionif not self.Portfolio.Invested and price <= self.min[symbol].Previous.Value:, which checks if the algorithm is not already invested in the symbol and if the current price is less than or equal to the previous minimum price before executing a buy order. This is a basic illustration, and actual implementation details may vary based on the specific requirements of the strategy and the available data.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.
Replyxf
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!