Validate Instrument Assignments
Here's a code snippet demonstrating how the ValidateInstrumentAssignments method can be implemented to validate mapped instruments for correctness:
[StrategyAttribute("{A298AC5B-0715-40F6-B9F0-3F780B550AEA}", "BoxSpread-X1", "Box Spread Strategy", "X1", StrategyBase.QXTStrategyOwner)]
class MainStrategy : StrategyBase
{
private IVObject _ivObjectCallLSP = new IVObject("CallLSP", "CallLowerStrikePrice", true, InstrumentType.Options, MarketDataType.All, OrderEventType.All);
private IVObject _ivObjectCallHSP = new IVObject("CallHSP", "CallHigherStrikePrice", true, InstrumentType.Options, MarketDataType.All, OrderEventType.All);
private IVObject _ivObjectPutLSP = new IVObject("PutLSP", "PutLowerStrikePrice", true, InstrumentType.Options, MarketDataType.All, OrderEventType.All);
private IVObject _ivObjectPutHSP = new IVObject("PutHSP", " PutHigherStrikePrice ", true, InstrumentType.Options, MarketDataType.All, OrderEventType.All);
private IVInfo _ivInfoCallLSP = null;
private IVInfo _ivInfoCallHSP = null;
private IVInfo _ivInfoPutLSP = null;
private IVInfo _ivInfoPutHSP = null;
public override bool ValidateInstrumentAssignments(KeyValuePair<IVObject, Instrument>[] ivObjetToInstrumentMap, out string errorString)
{
Options optionCallLSP = null;
Options optionCallHSP = null;
Options optionPutLSP = null;
Options optionPutHSP = null;
foreach (KeyValuePair<IVObject, Instrument> iterator in ivObjetToInstrumentMap)
{
if (iterator.Key == _ivObjectCallLSP)
optionCallLSP = (Options)iterator.Value;
else if (iterator.Key == _ivObjectCallHSP)
optionCallHSP = (Options)iterator.Value;
else if (iterator.Key == _ivObjectPutLSP)
optionPutLSP = (Options)iterator.Value;
else if (iterator.Key == _ivObjectPutHSP)
optionPutHSP = (Options)iterator.Value;
}
if (optionCallLSP == null)
{
errorString = "Instrument assignment not found for Option Call Low Strike.";
return false;
}
if (optionCallHSP == null)
{
errorString = "Instrument assignment not found for Option Call High Strike.";
return false;
}
if (optionPutLSP == null)
{
errorString = "Instrument assignment not found for Option Put Low Strike.";
return false;
}
if (optionPutHSP == null)
{
errorString = "Instrument assignment not found for Option Put High Strike.";
return false;
}
if (!(optionCallLSP.OptionType == OptionType.CE || optionCallLSP.OptionType == OptionType.CA))
{
errorString = "Assigned Instrument for IVObject[" + _ivObjectCallLSP.Name + "] must be CALL.";
return false;
}
if (!(optionCallHSP.OptionType == OptionType.CE || optionCallHSP.OptionType == OptionType.CA))
{
errorString = "Assigned Instrument for IVObject[" + _ivObjectCallHSP.Name + "] must be CALL.";
return false;
}
if (!(optionPutLSP.OptionType == OptionType.PE || optionPutLSP.OptionType == OptionType.PA))
{
errorString = "Assigned Instrument for IVObject[" + _ivObjectPutLSP.Name + "] must be PUT.";
return false;
}
if (!(optionPutHSP.OptionType == OptionType.PE || optionPutHSP.OptionType == OptionType.PA))
{
errorString = "Assigned Instrument for IVObject[" + _ivObjectPutHSP.Name + "] must be PUT.";
return false;
}
if (optionCallLSP.StrikePrice != optionPutLSP.StrikePrice)
{
errorString = "Option strike must be same for IVObject " + _ivObjectCallLSP.Name + " and " + _ivObjectPutLSP.Name + ".";
return false;
}
if (optionCallHSP.StrikePrice != optionPutHSP.StrikePrice)
{
errorString = "Option strike must be same for IVObject " + _ivObjectCallHSP.Name + " and " + _ivObjectPutHSP.Name + ".";
return false;
}
if (optionCallLSP.StrikePrice >= optionCallHSP.StrikePrice)
{
errorString = "Option strike for IVObject[" + _ivObjectCallLSP.Name + "] must be less then IVObject[" + _ivObjectPutHSP.Name + "].";
return false;
}
errorString = string.Empty;
return true;
}
}
public override bool ValidateInstrumentAssignment(IVObject ivObject, Instrument instrument, out string errorString)
{
if (_ivObjectOptionFirstLeg.Name == ivObject.Name)
{
if (instrument.InstrumentType != InstrumentType.Options)
{
errorString = "Instrument assignment not valid for Option First Leg. It must be Option Contract.";
return false;
}
}
else if (_ivObjectOptionFirstLeg.Name == ivObject.Name)
{
if (instrument.InstrumentType != InstrumentType.Options)
{
errorString = "Instrument assignment not valid for Option Second Leg. It must be Option Contract.";
return false;
}
}
errorString = string.Empty;
return true;
}
In this implementation: - The ValidateInstrumentAssignments method takes a list of static IVObjects and their corresponding mapped instruments as input parameters. - It iterates through each IVObject and its corresponding mapped instrument, performing validation logic based on the expected instrument type of the IVObject. - If any validation check fails, the method returns false and sets an appropriate error message in the errorString parameter. - If all validation checks pass, the method returns true, indicating that the IVObject mapping is correct.
Validate Strategy Parameter Override Method
The Strategy's input parameters, controlled by the Trader, reflect any changed values from the trading dashboard in real-time within the Strategy Instance's bound variables. However, there's a possibility that a changed value might not be valid or could pose a risk to Strategy execution if set incorrectly. To mitigate this, the ValidateStrategyParameter method offers the Strategy an opportunity to validate the proposed value before applying it to the Strategy code's bound variable. If the value is found to be inappropriate, the Strategy can reject the change request.
The Strategy input parameters defined from the Strategy are controlled by the Trader, and any changed value from the trading dashboard is reflected in the bound variable of the Strategy Instance in real-time.
There could be a chance that the changed value is not valid or could pose a risk to Strategy execution if wrongly set. The strategy has the opportunity to validate the value of the input parameter change before it is applied to the bound variable of the Strategy code. The Strategy developer can reject the change request if the value is not appropriately set.
The ValidateStrategyParameter method is invoked during a request to change the value of an input variable within the Strategy Instance. This gives the Strategy an opportunity to scrutinize the proposed input value and reject it if it's deemed invalid for application to the mapped variable.
Below is a code snippet demonstrating how to implement the ValidateStrategyParameter method to validate input variables UserBenchmark and OrderLotQuantity :
[StrategyParameterAttribute("UserBenchmark ", DefaultValue = 500, Description = "User Benchmark.", CategoryName = "General", DisplayName = "User Benchmark")]
private double Input_UserBenchmarke = 500;
protected override bool ValidateStrategyParameter(string parameterName, object paramterValue, out string errorString)
{
errorString = string.Empty;
bool retValue = false;
switch (parameterName)
{
case "UserBenchmark": // UserBenchmark is defined as Input parameter
{
retValue = paramterValue is double;
if (retValue == false || retValue <= 0)
errorString = parameterName + " value is invalid";
}
break;
case "OrderLotQuantity": // OrderLotQuantity is defined as Input parameter
{
retValue = paramterValue is double;
if (retValue == false || retValue < 0 || retValue > 50 || retValue %_ivInfo.LotSize != 0)
errorString = parameterName + " value is invalid";
}
break;
default:
retValue = base.ValidateStrategyParameter(parameterName, paramterValue, out errorString);
break;
}
return retValue;
}
For the UserBenchmark parameter, the method checks if the proposed value is a positive double. If the conditions are met, it returns true, indicating the value is valid for application to the Strategy input variable. Otherwise, it returns false.
For the OrderLotQuantity parameter, the method verifies if the proposed value is an integer and a multiple of the instrument's lot size. If both criteria are satisfied, it returns true. Otherwise, it returns false. The method includes a default case to handle other input parameters if necessary, accepting the proposed value by default.
Each input parameter change request should invoke this method to ascertain whether the proposed value is acceptable. If true is returned, the value is applied to the corresponding Strategy input variable; otherwise, it's rejected.
Validate Strategy Parameter Override Method
The ValidateStrategyParameter method is called every time a Strategy Input Parameter is successfully applied to mapped variables. Here, the Strategy developer has an opportunity to implement post-processing logic based on the changed variable state.
Consider a scenario where the Strategy defines an input parameter to accept user input for squaring off all trading positions, specified in a time format of "HH:MM:SS".
[StrategyParameterAttribute("SquareOffTime ", DefaultValue ="15:20:00", Description = "SquareOff time in HH:mm:ss format")]
private string Input_SquareOffTime = "15:20:00";
private DateTime _squareOffTime = DateTime.Now.AddHours(10);
protected override void OnStrategyParamterChanged()
{
base.OnStrategyParamterChanged();
DateTime today = DateTime.Today;
// Combine today's date with the timestamp
string combinedDateTimeString = today.ToString("yyyy-MM-dd") + " " + Input_SquareoffTime;
// Parse the combined string to a DateTime object
_squareOffDateTime = DateTime.ParseExact(combinedDateTimeString, "yyyy-MM-dd HH:mm:ss", null);
}