[b]Часть 4. Универсализация создания, тестирования и исполнения стратегий[/b]
Первое что мне бросилось в глаза в версии от Kazai Mazai, которую я продолжил допиливать - отсутствие универсальности в исполнении/тестировании одной и той же стратегии.
Так если запустить стратегию RobotStrategy на тестирование, то следующий участок кода стратегии:
[code=csharp]
... lock (this)
{
if (_bidOrder == null && _askOrder == null)
{
// проверяем на сигнал на вход
var spread = (ask - bid) / Security.MinStepSize;
if (spread >= ((RobotStrategyProperties)Params).Spread)
...
[/code]
вызовет ошибку "Не удалось привести тип объекта "System.Collections.Generic.List1[Robot.Strategies.HustleEveryDayStrategyTestingProperties]" к типу "System.Collections.Generic.List1[Robot.Strategies.HustleEveryDayStrategyProperties]".
Для решения этой проблемы введем в класс BaseShellStrategyProperties два параметра "Класс стратегии" и "Режим запуска":
[CODE=csharp]
public enum enMode
{
Execution,
Testing
}
private string _classname = "Класс стратегии";
[DisplayName(@"Класс")]
[Description(@"Класс стратегии")]
[Category(@"Основные")]
[PropertyOrder(1)]
public string ClassName
{
get { return _classname; }
set
{
_classname = value;
OnPropertyChanged("ClassName");
}
}
private enMode _mode = enMode.Testing;
[Category(@"Основные")]
[DisplayName(@"Режим запуска")]
[Description(@"Режим запуска стратегии")]
[PropertyOrder(2)]
public enMode Mode
{
get { return _mode; }
set
{
_mode = value;
OnPropertyChanged("Mode");
}
}
[/CODE]
Данные свойства необходимо определять во всех процедурах типа AddХХХХStrategy.
[CODE=csharp]
private void AddRobotStrategy()
{
var properties = new RobotStrategyProperties
{
ClassName = "Robot",
Mode = enMode.Execution
[/CODE]
4.1. Универсализация исполнения стратегий
Все параметры внутри стратегии обертываем процедурой if, которая проверяет режим запуска и проводит правильное приведение типов данных:
[CODE=csharp]
int StopVal = 1;
if (Params.Mode == enMode.Execution)
StopVal = ((RobotStrategyProperties)Params).Stop;
else
StopVal = ((RobotTestingProperties)Params).Stop;
[/CODE]
4.2. Универсализация тестирования стратегий
В основную процедуру запуска стратегий на тестирование StartTesingStrategy добавляем проверка класса стратегии при задании специфичных параметров:
[CODE=csharp]
if (parameters.ClassName == "Sma" || parameters.ClassName == "TLS")
{
switch (parameters.ClassName)
{
case "Sma":
((SmaStrategy)_strategy).series = _series;
break;
case "TLS":
((TLSStrategy)_strategy).series = _series;
break;
}
}
[/CODE]
4.3. Универсализация сохранения настроек стратегий
В основной процедуре сохранения настроек стратегии SaveStrategies проводим модификацию запроса Where
[CODE=csharp]
var robotstrategies = _documents.Keys.Where(str => str.Params.ClassName == "Robot" && str.Params.Mode == enMode.Execution).Select(str => (RobotStrategyProperties)str.Params).ToList();
SettingsEngine.Instance.SaveRobotStrategies(robotstrategies);
var hustlestrategies = _documents.Keys.Where(str => str.Params.ClassName == "Hustle" && str.Params.Mode == enMode.Execution).Select(str => (HustleStrategyProperties)str.Params).ToList();
SettingsEngine.Instance.SaveHustleStrProp(hustlestrategies);
[/CODE]
4.4. Устранение бага отображения стратегий на панели "Стратегии"
В поставляемой версии на панели "Стратегии" не отражаются тестовые стратегии. Для устранения этого бага проводим универсализацию хранения стратегий в переменной _documents.
а) везде в процедурах создания стратегий проводим сохранение стратегий в переменную _documents:
[CODE=csharp]
_documents.Add(strategy, doc);
[/CODE]
б) в свойстве SelectedStrategy дописываем условие выбора документа типа TestingDocument:
[CODE=csharp]
var doc = dockManager.ActiveContent;
if (doc is StrategyDocument)
{
var content = (StrategyDocument)doc;
result = content.Strategy;
}
else
{
var content = (TestingDocument)doc;
result = content.Strategy;
}
return result;
[/CODE]
Теперь все отображается корректно.
в) дополнительно можно вообще удалить процедуру SaveTestingStrategies, поместив соответствующие обработки в SaveStrategies:
[CODE=csharp]
var robotTstrategies = _documents.Keys.Where(str => str.Params.ClassName == "Robot" && str.Params.Mode == enMode.Testing).Select(str => (RobotStrategyTestingProperties)str.Params).ToList();
SettingsEngine.Instance.SaveRobotTestingStrategies(robotTstrategies);
var hustleTstrategies = _documents.Keys.Where(str => str.Params.ClassName == "Hustle" && str.Params.Mode == enMode.Testing).Select(str => (HustleStrategyTestingProperties)str.Params).ToList();
SettingsEngine.Instance.SaveHustleTestStrProp(hustleTstrategies);
[/CODE]
После всех этих универсализаций добавление новой стратегии действительно становится достаточно простым делом.