In C# .NET. This block of if/else if works fine, but its getting cumbersome to maintain and read. I want a more optimized writing style.
if (Globals.SRSI < 10 && Globals.SRSI != 0 && Globals.ATR14 != 0) //Low Stochastic Entry Long Strategy
{
dStochRSIPriceLong = markPrice - (0.1 * Globals.ATR14);
ECStrategy = "Stochastic Long";
}
else if (Globals.RSI < 20 && Globals.RSI != 0 && Globals.ATR14 != 0) //RSI Rebound Long Strategy
{
dRSIPriceLong = markPrice - (0.2 * Globals.ATR14);
ECStrategy = "Rebound Long";
}
else if (Globals.MACDLINEPrevious < Globals.MACDSigLINEPrevious && Globals.MACDLINE > Globals.MACDSigLINE) //MACD Crossover Long Strategy
{
dMACDCrossoverLong = markPrice - (0.2 * Globals.ATR14);
ECStrategy = "Crossover Long";
}
else if (Math.Abs(markPrice - Globals.SMA25) > 300 && Globals.PreviousCandleLo > Globals.SMA25 && markPrice > Globals.SMA25 && Globals.SMA25 > Globals.SMA50 && Globals.SMA50 > Globals.SMA100) //Runaway Long Strategy
{
dLoCandleLong = Globals.PreviousCandleLo;
ECStrategy = "Runaway Long";
}
else if (markPrice > Globals.SMA25 && Globals.SMA25 > Globals.SMA50 && Globals.SMA50 > Globals.SMA100) //Knife Long Strategy
{
dMA2PriceLong = Globals.SMA25;
ECStrategy = "Knife Long";
}
else if (markPrice > Globals.SMA50 && Globals.SMA50 > Globals.SMA100) //Moving Average Momentum Long Strategy
{
dMAPriceLong = Globals.SMA50;
ECStrategy = "Momentum Long";
}
else if (markPrice > Globals.SMA100) //MA100 Breakout Long Strategy
{
dPullbacksPriceLong = Globals.SMA100;
ECStrategy = "Breakout Long";
}
dPositionEntryPriceLong = SearchArray(markPrice, new List<double> { dStochRSIPriceLong, dRSIPriceLong, dMACDCrossoverLong, dLoCandleLong, dMA2PriceLong, dMAPriceLong, dPullbacksPriceLong });
Obviously there will still be if/else but I am hoping to not having this repetition. I tried to use a list with index but got lost in the complication of it all because I don't know how I can list a condition and action and then look it up.
You can use a list of conditions and corresponding actions to make this block of if/else statements more structured, condensed, and easier to maintain. This can be achieved by creating a list of tuples or a custom class to hold the condition and action and then iterating through this list. Here's one way to do it using a custom class:
public class Strategy
{
public Func<bool> Condition { get; set; }
public Action Action { get; set; }
}
public void DetermineStrategy(double markPrice)
{
double dStochRSIPriceLong = 0, dRSIPriceLong = 0, dMACDCrossoverLong = 0;
double dLoCandleLong = 0, dMA2PriceLong = 0, dMAPriceLong = 0, dPullbacksPriceLong = 0;
string ECStrategy = string.Empty;
var strategies = new List<Strategy>
{
new Strategy
{
Condition = () => Globals.SRSI < 10 && Globals.SRSI != 0 && Globals.ATR14 != 0,
Action = () => { dStochRSIPriceLong = markPrice - (0.1 * Globals.ATR14); ECStrategy = "Stochastic Long"; }
},
new Strategy
{
Condition = () => Globals.RSI < 20 && Globals.RSI != 0 && Globals.ATR14 != 0,
Action = () => { dRSIPriceLong = markPrice - (0.2 * Globals.ATR14); ECStrategy = "Rebound Long"; }
},
new Strategy
{
Condition = () => Globals.MACDLINEPrevious < Globals.MACDSigLINEPrevious && Globals.MACDLINE > Globals.MACDSigLINE,
Action = () => { dMACDCrossoverLong = markPrice - (0.2 * Globals.ATR14); ECStrategy = "Crossover Long"; }
},
new Strategy
{
Condition = () => Math.Abs(markPrice - Globals.SMA25) > 300 && Globals.PreviousCandleLo > Globals.SMA25 && markPrice > Globals.SMA25 && Globals.SMA25 > Globals.SMA50 && Globals.SMA50 > Globals.SMA100,
Action = () => { dLoCandleLong = Globals.PreviousCandleLo; ECStrategy = "Runaway Long"; }
},
new Strategy
{
Condition = () => markPrice > Globals.SMA25 && Globals.SMA25 > Globals.SMA50 && Globals.SMA50 > Globals.SMA100,
Action = () => { dMA2PriceLong = Globals.SMA25; ECStrategy = "Knife Long"; }
},
new Strategy
{
Condition = () => markPrice > Globals.SMA50 && Globals.SMA50 > Globals.SMA100,
Action = () => { dMAPriceLong = Globals.SMA50; ECStrategy = "Momentum Long"; }
},
new Strategy
{
Condition = () => markPrice > Globals.SMA100,
Action = () => { dPullbacksPriceLong = Globals.SMA100; ECStrategy = "Breakout Long"; }
}
};
foreach (var strategy in strategies)
{
if (strategy.Condition())
{
strategy.Action();
break;
}
}
dPositionEntryPriceLong = SearchArray(markPrice, new List<double> { dStochRSIPriceLong, dRSIPriceLong, dMACDCrossoverLong, dLoCandleLong, dMA2PriceLong, dMAPriceLong, dPullbacksPriceLong });
}
This approach makes it easier to maintain and read the conditions and actions. You can add, remove, or modify strategies without changing the structure of the DetermineStrategy method.