Fix Backtest runs VS production run. Align dates.
This commit is contained in:
@@ -328,17 +328,26 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
StartDate=StartDate-timeSpan;
|
StartDate=StartDate-timeSpan;
|
||||||
TradeDate=dateGenerator.GetCurrentMonthEnd(StartDate);
|
TradeDate=dateGenerator.GetCurrentMonthEnd(StartDate);
|
||||||
}
|
}
|
||||||
if(null!=PathSessionFileName)sessionParams=RestoreSession();
|
if(null!=PathSessionFileName)
|
||||||
|
{
|
||||||
|
sessionParams=RestoreSession();
|
||||||
|
DateTime currentMonthEndDate = dateGenerator.GetCurrentMonthEnd(TradeDate);
|
||||||
|
if(TradeDate!=currentMonthEndDate)
|
||||||
|
{
|
||||||
|
TradeDate=currentMonthEndDate;
|
||||||
|
AnalysisDate=TradeDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(null!=sessionParams)
|
if(null!=sessionParams)
|
||||||
{
|
{
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Using session file {0}, Last updated {1}",paramPathSessionFileName,sessionParams.LastUpdated));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Using session file {0}, Last updated {1}, Current Trade Date: {2}",paramPathSessionFileName,sessionParams.LastUpdated.ToShortDateString(),TradeDate.ToShortDateString()));
|
||||||
}
|
}
|
||||||
Configuration.DisplayConfiguration();
|
Configuration.DisplayConfiguration();
|
||||||
DisplayBalance();
|
DisplayBalance();
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(TradeDate>AnalysisDate)break;
|
if(TradeDate > AnalysisDate)break;
|
||||||
int slotIndex=(int)(((double)Cycle)%((double)(HoldingPeriod)));
|
int slotIndex=(int)(((double)Cycle)%((double)(HoldingPeriod)));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TRADE DATE {0} , ANALYSIS DATE {1}",Utility.DateTimeToStringMMHDDHYYYY(TradeDate),Utility.DateTimeToStringMMHDDHYYYY(AnalysisDate)));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("TRADE DATE {0} , ANALYSIS DATE {1}",Utility.DateTimeToStringMMHDDHYYYY(TradeDate),Utility.DateTimeToStringMMHDDHYYYY(AnalysisDate)));
|
||||||
if(!ActivePositions.ContainsKey(slotIndex))
|
if(!ActivePositions.ContainsKey(slotIndex))
|
||||||
@@ -349,24 +358,34 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
{
|
{
|
||||||
SellAndBuySlotPositions(slotIndex);
|
SellAndBuySlotPositions(slotIndex);
|
||||||
}
|
}
|
||||||
// Check if we are configured to use any of the daily strategies
|
ManageHedgedPositions(TradeDate);
|
||||||
|
DateTime nextBusinessDay = dateGenerator.FindNextBusinessDay(TradeDate);
|
||||||
|
DateTime nextMonthEndDate = dateGenerator.GetNextMonthEnd(TradeDate);
|
||||||
|
|
||||||
|
// if the TradeDate and AnalysisDate are equal then set the trade date to the next business day and exit the cycle
|
||||||
|
if(TradeDate.Equals(AnalysisDate))
|
||||||
|
{
|
||||||
|
TradeDate = nextBusinessDay;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will enter the daily cycle which we need for backtesting
|
||||||
if(Configuration.UseStopLimits || Configuration.UseHedging)
|
if(Configuration.UseStopLimits || Configuration.UseHedging)
|
||||||
{
|
{
|
||||||
DateTime nextMonthEndDate = dateGenerator.GetNextMonthEnd(TradeDate);
|
if(nextMonthEndDate >= AnalysisDate)
|
||||||
if(nextMonthEndDate > TradeDate && nextMonthEndDate<=AnalysisDate)
|
|
||||||
{
|
{
|
||||||
if(null!=PathSessionFileName)SaveSession();
|
nextMonthEndDate=dateGenerator.FindNextBusinessDay(AnalysisDate);
|
||||||
UpdateDaily(dateGenerator.FindNextBusinessDay(TradeDate),nextMonthEndDate,paramPathSessionFileName);
|
|
||||||
}
|
}
|
||||||
|
TradeDate = nextBusinessDay;
|
||||||
|
SaveSession();
|
||||||
|
UpdateDaily(nextBusinessDay,nextMonthEndDate,AnalysisDate,paramPathSessionFileName); // This will save the session file
|
||||||
|
sessionParams = RestoreSession();
|
||||||
}
|
}
|
||||||
Cycle++;
|
Cycle++;
|
||||||
TradeDate = dateGenerator.GetNextMonthEnd(TradeDate);
|
|
||||||
if (TradeDate>AnalysisDate)break;
|
|
||||||
} // WHILE TRUE
|
} // WHILE TRUE
|
||||||
|
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,$"RUN COMPLETE FOR ANALYSIS DATE {AnalysisDate.ToShortDateString()}.");
|
MDTrace.WriteLine(LogLevel.DEBUG,$"RUN COMPLETE FOR ANALYSIS DATE {AnalysisDate.ToShortDateString()}.");
|
||||||
if(null!=PathSessionFileName)SaveSession();
|
if(null!=PathSessionFileName)SaveSession();
|
||||||
if(null==sessionParams)sessionParams=RestoreSession();
|
|
||||||
DisplayStatistics(sessionParams);
|
|
||||||
for(int slotIndex=0;slotIndex<HoldingPeriod;slotIndex++)
|
for(int slotIndex=0;slotIndex<HoldingPeriod;slotIndex++)
|
||||||
{
|
{
|
||||||
if(!ActivePositions.ContainsKey(slotIndex)||0==ActivePositions[slotIndex].Count())continue;
|
if(!ActivePositions.ContainsKey(slotIndex)||0==ActivePositions[slotIndex].Count())continue;
|
||||||
@@ -378,13 +397,10 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
CashBalance+=slotPositions.MarketValue;
|
CashBalance+=slotPositions.MarketValue;
|
||||||
ActivePositions[slotIndex].Clear();
|
ActivePositions[slotIndex].Clear();
|
||||||
}
|
}
|
||||||
|
DisplayStatistics(sessionParams);
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,"************** A L L P O S I T I O N S *************");
|
MDTrace.WriteLine(LogLevel.DEBUG,"************** A L L P O S I T I O N S *************");
|
||||||
AllPositions=new MGSHPositions((from MGSHPosition position in AllPositions orderby position.PurchaseDate ascending select position).ToList());
|
AllPositions=new MGSHPositions((from MGSHPosition position in AllPositions orderby position.PurchaseDate ascending select position).ToList());
|
||||||
AllPositions.Display();
|
AllPositions.Display();
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG, "************** T O P G A I N E R S *************");
|
|
||||||
AllPositions.DisplayTopFive();
|
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG, "************** T O P L O S E R S *************");
|
|
||||||
AllPositions.DisplayBottomFive();
|
|
||||||
DisplayBalance();
|
DisplayBalance();
|
||||||
backTestResult.Success=true;
|
backTestResult.Success=true;
|
||||||
backTestResult.CashBalance=CashBalance;
|
backTestResult.CashBalance=CashBalance;
|
||||||
@@ -397,8 +413,9 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
public void BuySlotPositions(int slotIndex)
|
public void BuySlotPositions(int slotIndex)
|
||||||
{
|
{
|
||||||
MGSHPositions positions = null;
|
MGSHPositions positions = null;
|
||||||
positions=BuyPositions(TradeDate,AnalysisDate,CashBalance/((double)HoldingPeriod-(double)ActivePositions.Count),SymbolsHeld(TradeDate));
|
positions=BuyPositions(slotIndex, TradeDate, AnalysisDate, CashBalance/((double)HoldingPeriod-(double)ActivePositions.Count), SymbolsHeld(TradeDate));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG, "******************** B U Y ********************");
|
MDTrace.WriteLine(LogLevel.DEBUG, "******************** B U Y ********************");
|
||||||
|
MDTrace.WriteLine(LogLevel.DEBUG, $"SLOT:{slotIndex}");
|
||||||
if(CashBalance-positions.Exposure<0.00)
|
if(CashBalance-positions.Exposure<0.00)
|
||||||
{
|
{
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
|
||||||
@@ -429,7 +446,7 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
int positionsToFill = MaxPositions-slotPositions.Count;
|
int positionsToFill = MaxPositions-slotPositions.Count;
|
||||||
double cashAllocation = (CashBalance / ((HoldingPeriod * MaxPositions) - ActivePositions.GetCount()))*positionsToFill; // split the cash between the total positions we can own less the number of positions we have
|
double cashAllocation = (CashBalance / ((HoldingPeriod * MaxPositions) - ActivePositions.GetCount()))*positionsToFill; // split the cash between the total positions we can own less the number of positions we have
|
||||||
MGSHPositions positions = null;
|
MGSHPositions positions = null;
|
||||||
positions=BuyPositions(TradeDate,AnalysisDate,cashAllocation,SymbolsHeld(TradeDate), positionsToFill);
|
positions=BuyPositions(slotIndex, TradeDate,AnalysisDate,cashAllocation,SymbolsHeld(TradeDate), positionsToFill);
|
||||||
if(CashBalance-positions.Exposure<=0.00)
|
if(CashBalance-positions.Exposure<=0.00)
|
||||||
{
|
{
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("********** Insufficient funds to make additional purchases.**************"));
|
||||||
@@ -455,36 +472,47 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
// ********************************************************************************************************************************************************
|
// ********************************************************************************************************************************************************
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Entry point for daily runs. Make sure for daily runs that startDate=endDate=Trading Date after market close
|
/// Entry point for daily runs. Make sure for daily runs that startDate=endDate=Trading Date after market close
|
||||||
|
/// The system does not process endDate. (i.e.) startDate < endDate
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="startDate">{ORIGINAL START DATE}</param>
|
/// <param name="startDate">{ORIGINAL START DATE}</param>
|
||||||
/// <param name="endDate">{TODAY}</param>
|
/// <param name="endDate">{TODAY}</param>
|
||||||
/// <param name="paramPathSessionFileName">The session file name</param>
|
/// <param name="paramPathSessionFileName">The session file name</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public MGSHBacktestResult UpdateDaily(DateTime startDate,DateTime endDate,String pathSessionFileName)
|
public MGSHBacktestResult UpdateDaily(DateTime startDate, DateTime endDate, DateTime analysisDate, String pathSessionFileName)
|
||||||
{
|
{
|
||||||
DateGenerator dateGenerator = new DateGenerator();
|
DateGenerator dateGenerator = new DateGenerator();
|
||||||
PathSessionFileName = pathSessionFileName;
|
PathSessionFileName = pathSessionFileName;
|
||||||
|
|
||||||
RestoreSession();
|
RestoreSession();
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("************** U P D A T E D A I L Y {0} < {1}",startDate.ToShortDateString(),endDate.ToShortDateString()));
|
AnalysisDate=analysisDate;
|
||||||
|
|
||||||
|
if(startDate != TradeDate)
|
||||||
|
{
|
||||||
|
MDTrace.WriteLine(LogLevel.DEBUG,$"Unexpectd StartDate. Start Date:{startDate.ToShortDateString()} Trade Date:{TradeDate.ToShortDateString()}");
|
||||||
|
return new MGSHBacktestResult(false, CashBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("************** U P D A T E D A I L Y **************"));
|
||||||
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Trade Date:{TradeDate.ToShortDateString()} Analysis Date:{AnalysisDate.ToShortDateString()}"));
|
||||||
|
|
||||||
while(startDate < endDate)
|
while(startDate < endDate)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
TradeDate=startDate;
|
||||||
if(Configuration.UseStopLimits)
|
if(Configuration.UseStopLimits)
|
||||||
{
|
{
|
||||||
changed = UpdateStopLimitsForActivePositions(startDate);
|
UpdateStopLimitsForActivePositions(startDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Configuration.UseHedging)
|
if(Configuration.UseHedging)
|
||||||
{
|
{
|
||||||
changed = ManageHedgedPositions(startDate) ? true : changed;
|
ManageHedgedPositions(startDate);
|
||||||
}
|
}
|
||||||
// if(changed)DisplayBalance();
|
|
||||||
DisplayBalance();
|
DisplayBalance();
|
||||||
startDate = dateGenerator.FindNextBusinessDay(startDate);
|
startDate = dateGenerator.FindNextBusinessDay(startDate);
|
||||||
|
TradeDate = startDate;
|
||||||
}
|
}
|
||||||
if(null!=PathSessionFileName)SaveSession();
|
SaveSession();
|
||||||
return new MGSHBacktestResult(true, CashBalance);
|
return new MGSHBacktestResult(true, CashBalance);
|
||||||
}
|
}
|
||||||
// *******************************************************************************************************************************************************
|
// *******************************************************************************************************************************************************
|
||||||
@@ -567,7 +595,7 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
|
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Initial stop limit for {0} on {1} with PurchsePrice:{2} is {3}, Shares:{4} Risk:{5}%",
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Initial stop limit for {0} on {1} with PurchsePrice:{2} is {3}, Shares:{4} Risk:{5}%",
|
||||||
shortPosition.Symbol,
|
shortPosition.Symbol,
|
||||||
shortPosition.PurchaseDate,
|
shortPosition.PurchaseDate.ToShortDateString(),
|
||||||
Utility.FormatCurrency(shortPosition.PurchasePrice,2),
|
Utility.FormatCurrency(shortPosition.PurchasePrice,2),
|
||||||
Utility.FormatCurrency(shortPosition.InitialStopLimit,2),
|
Utility.FormatCurrency(shortPosition.InitialStopLimit,2),
|
||||||
Utility.FormatNumber(shortPosition.Shares,2),
|
Utility.FormatNumber(shortPosition.Shares,2),
|
||||||
@@ -662,7 +690,7 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
position.LastStopAdjustment = Utility.Epoch;
|
position.LastStopAdjustment = Utility.Epoch;
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Initial stop limit for {0} on {1} with PurchsePrice:{2} is {3}, Shares:{4} Risk:{5}%",
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("Initial stop limit for {0} on {1} with PurchsePrice:{2} is {3}, Shares:{4} Risk:{5}%",
|
||||||
position.Symbol,
|
position.Symbol,
|
||||||
position.PurchaseDate,
|
position.PurchaseDate.ToShortDateString(),
|
||||||
Utility.FormatCurrency(position.PurchasePrice,2),
|
Utility.FormatCurrency(position.PurchasePrice,2),
|
||||||
Utility.FormatCurrency(position.InitialStopLimit,2),
|
Utility.FormatCurrency(position.InitialStopLimit,2),
|
||||||
Utility.FormatNumber(position.Shares,2),
|
Utility.FormatNumber(position.Shares,2),
|
||||||
@@ -731,7 +759,6 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
ActivePositions.Remove(position);
|
ActivePositions.Remove(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("*************************************************************************************************",analysisDate.ToShortDateString()));
|
|
||||||
if(closedPositions.Count>0)return true;
|
if(closedPositions.Count>0)return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -946,12 +973,12 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
// ************************************************************************************************************************************************************
|
// ************************************************************************************************************************************************************
|
||||||
// *********************************************************** B U Y S L O T P O S I T I O N S ************************************************************
|
// *********************************************************** B U Y S L O T P O S I T I O N S ************************************************************
|
||||||
// ************************************************************************************************************************************************************
|
// ************************************************************************************************************************************************************
|
||||||
private MGSHPositions BuyPositions(DateTime tradeDate, DateTime analysisDate, double cash, List<String> symbolsHeld, double maxPositions=double.NaN)
|
private MGSHPositions BuyPositions(int slotIndex, DateTime tradeDate, DateTime analysisDate, double cash, List<String> symbolsHeld, double maxPositions=double.NaN)
|
||||||
{
|
{
|
||||||
MGSHPositions positions = new MGSHPositions();
|
MGSHPositions positions = new MGSHPositions();
|
||||||
if(double.IsNaN(maxPositions))maxPositions=MaxPositions;
|
if(double.IsNaN(maxPositions))maxPositions=MaxPositions;
|
||||||
if(0==maxPositions)return positions;
|
if(0==maxPositions)return positions;
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"BUY POSITIONS: TRADE DATE:{TradeDate.ToShortDateString()} CASH:{Utility.FormatCurrency(cash)} POSITIONS TO FILL:{maxPositions}"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"BUY POSITIONS: SLOT:{slotIndex} TRADE DATE:{TradeDate.ToShortDateString()} CASH:{Utility.FormatCurrency(cash)} POSITIONS TO FILL:{maxPositions}"));
|
||||||
int positionCount = 0;
|
int positionCount = 0;
|
||||||
if (Configuration.BenchmarkMode) return BuyBenchmarkPositions(tradeDate, cash);
|
if (Configuration.BenchmarkMode) return BuyBenchmarkPositions(tradeDate, cash);
|
||||||
MGSHMomentumCandidates momentumCandidates = MGSHMomentumGenerator.GenerateMomentum(tradeDate, symbolsHeld, Configuration);
|
MGSHMomentumCandidates momentumCandidates = MGSHMomentumGenerator.GenerateMomentum(tradeDate, symbolsHeld, Configuration);
|
||||||
@@ -1059,10 +1086,10 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Total Trades:{modelStatistics.TotalTrades}"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Total Trades:{modelStatistics.TotalTrades}"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Winning Trades:{modelStatistics.WinningTrades}"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Winning Trades:{modelStatistics.WinningTrades}"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Losing Trades:{modelStatistics.LosingTrades}"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Losing Trades:{modelStatistics.LosingTrades}"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Average Winning Trade Percent Gain:{modelStatistics.AverageWinningTradePercentGain}%"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Average Winning Trade Percent Gain:{Utility.FormatNumber(modelStatistics.AverageWinningTradePercentGain,2)}%"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Average Losing Trade Percent Loss:{modelStatistics.AverageLosingTradePercentLoss}%"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Average Losing Trade Percent Loss:{Utility.FormatNumber(modelStatistics.AverageLosingTradePercentLoss,2)}%"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Winning Trades Percent:{modelStatistics.WinningTradesPercent}%"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Winning Trades Percent:{Utility.FormatNumber(modelStatistics.WinningTradesPercent,2)}%"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Losing Trades Percent:{modelStatistics.LosingTradesPercent}%"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Losing Trades Percent:{Utility.FormatNumber(modelStatistics.LosingTradesPercent,2)}%"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Expectancy:{Utility.FormatNumber(modelStatistics.Expectancy,2)}"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format($"Expectancy:{Utility.FormatNumber(modelStatistics.Expectancy,2)}"));
|
||||||
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("**************************************************************"));
|
MDTrace.WriteLine(LogLevel.DEBUG,String.Format("**************************************************************"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,8 +140,7 @@ namespace MarketData.Generator.MGSHMomentum
|
|||||||
// Fallback candidate settings
|
// Fallback candidate settings
|
||||||
UseFallbackCandidate=true; // True is the default
|
UseFallbackCandidate=true; // True is the default
|
||||||
FallbackCandidate="SHV"; // "SHV" ICE U.S. Treasury Short Bond Index, "AGG" Barclays U.S. Aggregate Bond Index - AGG can have a slighty better return but is more volatile
|
FallbackCandidate="SHV"; // "SHV" ICE U.S. Treasury Short Bond Index, "AGG" Barclays U.S. Aggregate Bond Index - AGG can have a slighty better return but is more volatile
|
||||||
FallbackCandidateBestOf="SHV,AGG,ACWX"; // if set then the fallback candidate is selected as the best 252 day return in this comma seperated list (i.e.) "SHV,ACWX,AGG"
|
FallbackCandidateBestOf="SHV,NEAR,BIL,GSY,AGG,ACWX,GSY,SCHF,IXUS,DBEF,IEFA,TLT"; // if set then the fallback candidate is selected as the best 252 day return in this comma seperated list (i.e.) "SHV,ACWX,AGG,SHV,NEAR,BIL,GSY,AGG,ACWX,GSY,SCHF,IXUS,DBEF,IEFA
|
||||||
// SHV,NEAR,BIL,GSY,AGG,ACWX,GSY,SCHF,IXUS,DBEF,IEFA
|
|
||||||
// Set the QualityIndicator type to the ScoreIndicator by default.
|
// Set the QualityIndicator type to the ScoreIndicator by default.
|
||||||
QualityIndicatorType=MGSHQualityIndicator.ToString(MGSHQualityIndicator.QualityType.ScoreIndicator);
|
QualityIndicatorType=MGSHQualityIndicator.ToString(MGSHQualityIndicator.QualityType.ScoreIndicator);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user