Playing around with an old trend sample and trying out different indicators but I still do not understand what role the null status has, or even if it is doing anything. The code does seem to produce results but not sure if the null rules contribute. Your thoughts?
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TrendRobot2 : Robot
{
[Parameter("Instance", DefaultValue = "TrendRobot2", Group = "Instance Name")]
public string Instance { get; set; }
[Parameter("MA Type")]
public MovingAverageType MAType { get; set; }
[Parameter("MA Type2")]
public MovingAverageType MAType2 { get; set; }
[Parameter("VolumeBuy1", DefaultValue = 1, MinValue = 0.01, MaxValue = 100, Step = 0.5, Group = "Risk Management")]
public double VolumeBuy1 { get; set; }
[Parameter("VolumeSell1", DefaultValue = 1, MinValue = 0.01, MaxValue = 100, Step = 0.5, Group = "Risk Management")]
public double VolumeSell1 { get; set; }
[Parameter()]
public DataSeries SourceSeries { get; set; }
[Parameter("Slow Periods", DefaultValue = 10)]
public int SlowPeriods { get; set; }
[Parameter("Fast Periods", DefaultValue = 5)]
public int FastPeriods { get; set; }
[Parameter("RSIPeriods", Group = "RSI", DefaultValue = 5, MinValue =1, MaxValue = 200)]
public int RSIbuyPeriods { get; set; }
[Parameter("RSIOverBought", Group = "RSI", DefaultValue = 70, MinValue = 1, MaxValue = 200)]
public int RSIOverBought { get; set; }
[Parameter("RSIOverSold", Group = "RSI", DefaultValue = 30, MinValue = 1, MaxValue = 200)]
public int RSIOverSold { get; set; }
[Parameter("MACDPeriod", Group = "MACD", DefaultValue = 9)]
public int MACDPeriod { get; set; }
[Parameter("MACDLong Cycle", Group = "MACD", DefaultValue = 26)]
public int MACDLongCycle { get; set; }
[Parameter("MACDShort Cycle", Group = "MACD", DefaultValue = 12)]
public int MACDShortCycle { get; set; }
[Parameter("Stop Loss", DefaultValue = 10, MinValue = 0, Step = 0.001, Group = "Risk Management")]
public double StopLoss { get; set; }
[Parameter("Take Profit", DefaultValue = 10, MinValue = 0, Step = 0.001, Group = "Risk Management")]
public double TakeProfit { get; set; }
[Parameter("Stop Loss2", DefaultValue = 10, MinValue = 0, Step = 0.001, Group = "Risk Management")]
public double StopLoss2 { get; set; }
[Parameter("Take Profit2", DefaultValue = 10, MinValue = 0, Step = 0.001, Group = "Risk Management")]
public double TakeProfit2 { get; set; }
[Parameter("Martingale Buy", DefaultValue = false, Group = "Martingale")]
public bool UseMB { get; set; }
[Parameter("Martingale Sell", DefaultValue = false, Group = "Martingale")]
public bool UseMS { get; set; }
[Parameter("DonchianChannel", Group = "DonchianChannel", DefaultValue = 10)]
public int DONPeriods { get; set; }
[Parameter("Linear Periods1", Group = "Linear", DefaultValue = 3)]
public int Periods1 { get; set; }
[Parameter("Linear Periods2", Group = "Linear", DefaultValue = 10)]
public int Periods2 { get; set; }
private MovingAverage slowMa;
private MovingAverage fastMa;
private DonchianChannel _Dc;
private MacdCrossOver _macd;
private LinearRegressionForecast _lrf1;
private LinearRegressionForecast _lrf2;
private RelativeStrengthIndex rsi;
private const string label = "Trend Robot 2";
protected override void OnStart()
{
fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
_Dc = Indicators.DonchianChannel(Bars,DONPeriods);
_lrf1 = Indicators.LinearRegressionForecast(SourceSeries, Periods1);
_lrf2 = Indicators.LinearRegressionForecast(SourceSeries, Periods2);
_macd = Indicators.MacdCrossOver(MACDLongCycle, MACDShortCycle, MACDPeriod);
rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, RSIbuyPeriods);
}
protected override void OnTick()
{
var longPosition = Positions.Find(Instance, SymbolName, TradeType.Buy);
var shortPosition = Positions.Find(Instance, SymbolName, TradeType.Sell);
var DCTop = _Dc.Top.Last(0);
var DCMiddle = _Dc.Middle.Last(0);
var DCBottom = _Dc.Bottom.Last(0);
var LRForecast1 = _lrf1.Result.Last(0);
var LRForecast2 = _lrf2.Result.Last(0);
var PreviousLRForecast = _lrf1.Result.Last(2);
var MACD = _macd.MACD.Last(0);
var MACDH = _macd.Histogram.Last(0);
var MACDH2 = _macd.Histogram.Last(2);
var MACDS = _macd.Signal.Last(0);
var currentSlowMa = slowMa.Result.Last(0);
var currentFastMa = fastMa.Result.Last(0);
var previousSlowMa = slowMa.Result.Last(1);
var previousFastMa = fastMa.Result.Last(1);
if (LRForecast1 > LRForecast2 && previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa && MACD > MACDS && longPosition == null)
{
if (shortPosition != null)
if (UseMB)
{
if (shortPosition.NetProfit < 0)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, (int)shortPosition.VolumeInUnits + GetVolumeBuy1(), Instance, StopLoss, TakeProfit);
}
ClosePosition(shortPosition);
}
else
ClosePosition(shortPosition);
ExecuteMarketOrder(TradeType.Buy, SymbolName, GetVolumeBuy1(), Instance, StopLoss, TakeProfit);
}
else if (LRForecast1 < LRForecast2 && previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa && MACD < MACDS && shortPosition == null)
{
if (longPosition != null)
if (UseMS)
{
if (longPosition.NetProfit < 0)
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, (int)longPosition.VolumeInUnits + GetVolumeSell1(), Instance, StopLoss2, TakeProfit2);
}
ClosePosition(longPosition);
}
else
ClosePosition(longPosition);
ExecuteMarketOrder(TradeType.Sell, SymbolName, GetVolumeSell1(), Instance, StopLoss2, TakeProfit2);
}
}
// Calculating Volume
private double GetVolumeBuy1()
{
var maxAmountRisked1 = (Account.Balance * (VolumeBuy1 / (100000 * Symbol.PipValue)));
return Symbol.NormalizeVolumeInUnits(maxAmountRisked1, RoundingMode.Down);
}
private double GetVolumeSell1()
{
var maxAmountRisked2 = (Account.Balance * (VolumeSell1 / (100000 * Symbol.PipValue)));
return Symbol.NormalizeVolumeInUnits(maxAmountRisked2, RoundingMode.Down);
}
}
}