50 day moving average must remain above 200 day moving average in order for candidate to be selected.

This commit is contained in:
2025-02-20 10:34:59 -05:00
parent aebd58be25
commit 1f7aec2391

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using MarketData.MarketDataModel;
using MarketData.DataAccess;
using MarketData.Utils;
@@ -386,7 +385,7 @@ namespace MarketData.Generator.CMTrend
}
// DMA50 check : The 50 day moving average must remain above the 200 day moving average
Prices prices50=GBPriceCache.GetInstance().GetPrices(symbol,analysisDate,MovingAverageGenerator.DayCount50+10);
if(null==prices50||prices50.Count<MovingAverageGenerator.DayCount50)
if(null==prices50 || prices50.Count < MovingAverageGenerator.DayCount50)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Cannot evaluate DMA50 for candidate {0} due to insufficient pricng data",symbol));
return;
@@ -399,11 +398,20 @@ namespace MarketData.Generator.CMTrend
prices50=new Prices(prices50.Take(MovingAverageGenerator.DayCount50).ToList());
DMAPrices dma50Prices=MovingAverageGenerator.GenerateMovingAverage(prices50,prices50.Count);
double dma50Close=dma50Prices[0].AVGPrice;
if(currentPrice.Close<dma50Close)
// CHECK THAT THE CURRENT PRICE IS ABOVE THE 50 DAY MOVING AVERAGE
if(currentPrice.Close <= dma50Close)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMA50 Violation for candidate {0}. The closing price is less than the 50 day moving average {1} < {2} on {3}",symbol,Utility.FormatCurrency(currentPrice.Close),Utility.FormatCurrency(dma50Close),analysisDate.ToShortDateString()));
return;
}
// CHECK THAT THE 50 DAY MOVING AVERAGE IS ABOVE THE 200 DAY MOVING AVERAGE
if(dma50Close <= dma200Close)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMA50 Violation for candidate {0}. The 50 DMA must remain about 200 DMA. {1} < {2} on {3}",symbol,Utility.FormatCurrency(dma50Close),Utility.FormatCurrency(dma200Close),analysisDate.ToShortDateString()));
return;
}
// Price trend check. Ensure that prices are trending higher UsePriceTrendSlope UsePriceTrendSlopeDayCount
if(Parameters.UsePriceSlopeIndicator)
{
@@ -1104,11 +1112,20 @@ namespace MarketData.Generator.CMTrend
prices50=new Prices(prices50.Take(MovingAverageGenerator.DayCount50).ToList());
DMAPrices dma50Prices=MovingAverageGenerator.GenerateMovingAverage(prices50,prices50.Count);
double dma50Close=dma50Prices[0].AVGPrice;
if(currentPrice.Close<dma50Close)
// CHECK THAT THE CURRENT PRICE IS ABOVE THE 50 DAY MOVING AVERAGE
if(currentPrice.Close <= dma50Close)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMA50 Violation for candidate {0}. The closing price is less than the 50 day moving average {1} < {2} on {3}",mmCandidate.Symbol,Utility.FormatCurrency(currentPrice.Close),Utility.FormatCurrency(dma50Close),tradeDate.ToShortDateString()));
continue;
}
// CHECK THAT THE 50 DAY MOVING AVERAGE IS ABOVE THE 200 DAY MOVING AVERAGE
if(dma50Close <= dma200Close)
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("DMA50 Violation for candidate {0}. The 50 DMA must remain about 200 DMA. {1} < {2} on {3}",mmCandidate.Symbol,Utility.FormatCurrency(dma50Close),Utility.FormatCurrency(dma200Close),tradeDate.ToShortDateString()));
continue;
}
// Trend check ensure that prices are trending higher
if(Parameters.UsePriceSlopeIndicator)
{
@@ -1403,28 +1420,19 @@ namespace MarketData.Generator.CMTrend
double volatility=double.NaN;
if(Parameters.UseProfitMaximization)
{
// double unadjustedStop=double.NaN;
// double adjustedStop=double.NaN;
CodeRunner codeRunner=new CodeRunner();
SymbolTable symbolTable=codeRunner.SymbolTable;
symbolTable.AddObjects(new Object[]{position}.ToList());
codeRunner.Execute(Parameters.UseProfitMaximizationExpression);
double multiplier=codeRunner.GetValue<double>("MULTIPLIER");
// volatility=VolatilityGenerator.CalculateVolatility(position.Symbol,tradeDate,Parameters.StopLimitScalingVolatilityDays);
// unadjustedStop=currentPrice.Low-volatility;
volatility=VolatilityGenerator.CalculateVolatility(position.Symbol,tradeDate,Parameters.StopLimitScalingVolatilityDays,multiplier);
// adjustedStop=currentPrice.Low-volatility;
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Using profit maximization strategy for {0} which has RMultiple={1}. Multiplier:{2}",position.Symbol,position.RMultiple,Utility.FormatNumber(multiplier,3)));
}
else
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Using standard ATR multiplier for {0} which has RMultiple={1}.",position.Symbol,position.RMultiple));
volatility=VolatilityGenerator.CalculateVolatility(position.Symbol,tradeDate,Parameters.StopLimitScalingVolatilityDays);
}
// double stopLimit=stopLimitNonScaled;
if(double.IsNaN(volatility))
{
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Unable to calculate StopLimit for AverageTrueRange for {0} on {1}. Using non-scaled stop limit.",position.Symbol,tradeDate.ToShortDateString()));