Роботом на последних секунда с использованием индикаторов возникают некоторые нюансы!
2019.05.31 17:34:06.139 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:34:11.178 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:34:16.763 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:34:22.176 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:34:27.230 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:34:32.316 Разрешаем открывать позицию за 30 секунд ON_OFF = True
2019.05.31 17:37:22.934 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:37:28.347 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:37:34.446 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:37:39.485 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:37:44.898 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:37:52.199 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:37:57.238 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:02.355 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:07.378 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:12.510 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:17.596 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:23.259 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:28.235 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:33.742 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:39.046 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:44.335 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:49.389 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:38:56.379 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:02.884 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:08.219 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:13.352 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:18.375 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:23.585 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:29.700 Разрешаем открывать позицию за 30 секунд ON_OFF = False
2019.05.31 17:39:37.984 Разрешаем открывать позицию за 30 секунд ON_OFF = True
По логу видно, что робот запускает функцию function OnUpdate() примерно каждые 5 секунд
Дальше происходит следующее если робот управляет построением линии индикатора
- 2.jpg (104.85 КБ) 23742 просмотра
То есть если индикатор рисует линию по запросу как в этом индикаторе (код упростил до минимума)
Код: Выделить всё
function Initialize()
{
// Обязательные параметры:
IndicatorName = "Search_level_Robot"; // Задайте название индикатора и сохраните с данным именем
PriceStudy = true; // Рисовать в области цены (true – да, false – нет)
AddInput("Input", Inputs.Candle); // Input - входной ряд (Inputs.Price) или свечи (Inputs.Candle)
AddSeries("Last1", DrawAs.Line, Color.Red);// Задаем вид линии индикатора с именем ряда Last
AddLevel(0, Color.Red, LineStyles.Dot, 2, "Last");
//Данные получаемые с робота
AddParameter("GetPriceStep_ind", 0); // Минимальный шаг цены получаемый с робота (число знаков после запятой)
AddParameter("Period", 200); // Период построения уровней
AddParameter("Enable_Recalculation", 1); // Разрешение на обработку данных
AddParameter("max_stop", 20); // Период построения уровней (длинна истории)
AddParameter("gap", 4); // Период построения уровней (длинна истории)
//Данные передаваемые в робот
AddSeries("Direction"); // Направление открываемой позиции (0 - нет направления, 1- лонг, 2- шорт)
AddGlobalVariable("ListDouble", Types.DoubleList);
AddGlobalVariable("path", Types.String, @"c:\\dell\\Search_level_Robot.txt");
}
function Evaluate()
{
/*
код индикатора
*/
if (Direction>0 && (Convert.ToBoolean(Enable_Recalculation)==true))
{ //Открываем позицию вконце формирования свечи с индексом[0] (за 30 секунд до закрытия свечи)
Levels[0].Level = ListDouble[0];
}
}
Код: Выделить всё
/**
Тестируем патерны по А.М. Грчика, описанные в индикаторе Search_level.
Пытаемся открыть позицию на последних 30 секундах формирования свечи
( UseClosedBar = false;)
Algorithm = Отбой от уровня;
**/
function Initialize()
{
StrategyName = "Paterny_v1";
UseClosedBar=false; //разрешение на открывание позиции внутри бара
AddParameter("GetPriceStep_ind", 0, "Минимальный шаг цены (число знаков после запятой)" , 1); // Минимальный шаг цены получаемый с робота (число знаков после запятой)
AddParameter("Period", 200, "Период построения уровней",1); // Период построения уровней
AddParameter("Enable_Recalculation", 1, "Разрешение на пересчёт индикатора", 1);
AddParameter("max_stop", 20, "Максимальный стоп", 1);
AddParameter("gap", 4, "Величина проскальзования", 1);
AddParameter("Direction", 0, "Направление открываемой позиции", 1); // Направление открываемой позиции (0 - нет направления, 1- лонг, 2- шорт)
AddInput("Input1", Inputs.Candle, 5, true, "SRM9=ФОРТС");
LongLimit = 1;
ShortLimit = -1;
AddGlobalVariable("ON_OFF", Types.Boolean, false); //Разрешаем открывать позицию за 30 секунд до закрытия свечи (примерно 30секунд)
AddGlobalVariable("ON_OFF_Recalculation", Types.Boolean, true); //Расчёт исходных значений инструмента
AddGlobalVariable("path", Types.String, @"c:\\dell\\RobotSearch_level.txt");
AddChartIndicator("MY.Search_level_Robot", new Dictionary <string, string>{{"GetPriceStep_ind", "GetPriceStep_ind"},{"Period", "Period"},{"Enable_Recalculation", "Enable_Recalculation"},{"max_stop", "max_stop"},{"gap", "gap"}});
}
function OnUpdate()
{
//Расчёт исходных значений инструмента (Однократный)
if (ON_OFF_Recalculation==true)
{ //Рассчитываем колличество знаков после запятой в шаге цены
int GetPriceStep_ind=0;
while (GetPriceStep() * Math.Pow(10, 1 + GetPriceStep_ind) % 10 != 0) { GetPriceStep_ind++; }
//Рассчитываем величину стопа и проскальзывания
max_stop=Math.Round((Input.High[0]*0.2/100),(GetPriceStep_ind));
gap=Math.Round((max_stop*0.2),(GetPriceStep_ind));
ON_OFF_Recalculation=false;
}
TimeSpan Delta = new TimeSpan(0, 04, 30);
TimeSpan Interval = BarTime()+Delta;
TimeSpan Time_0;
Time_0=DateTime.Now.TimeOfDay;
if (Time_0>=Interval)
{
ON_OFF=true;
Enable_Recalculation=1;
LogData ("Разрешаем открывать позицию за 30 секунд ON_OFF = " + Convert.ToString(ON_OFF),Name);
}
else
{
ON_OFF=false;
Enable_Recalculation=0;
LogData ("Разрешаем открывать позицию за 30 секунд ON_OFF = " + Convert.ToString(ON_OFF),Name);
}
using (System.IO.StreamWriter sw = System.IO.File.CreateText(path))
{
sw.WriteLine("Расчёт исходных значений инструмента (Однократный)" );
sw.WriteLine("Шаг цены = " + Convert.ToString(GetPriceStep()));
sw.WriteLine("Колличество знаков после запятой = " + Convert.ToString(GetPriceStep_ind));
sw.WriteLine("Величина стопа = " + Convert.ToString(max_stop));
sw.WriteLine("Величина проскальзования = " + Convert.ToString(gap));
sw.WriteLine("время BarTime = " + BarTime().ToString());
sw.WriteLine("системное время = " + Time_0.ToString());
sw.WriteLine("BarTime()+Delta + 4.30 = " + Interval.ToString());
sw.WriteLine("ON_OFF = " + ON_OFF.ToString());
sw.Close(); sw.Dispose();
}
if(ON_OFF==true) //Разрешаем открывать позицию за 30 секунд до закрытия свечи (примерно 30секунд)
{
double price=(MY.Search_level_Robot(Input1, GetPriceStep_ind, Period, Enable_Recalculation, max_stop, gap).GetValue("Last1", 0));
LogData ("Разрешаем открывать позицию за 30 секунд - " + Convert.ToString(MY.Search_level_Robot(Input1, 2, Period).GetValue("Dictionary")),Name);
LogData ("Цена уровня = " + Convert.ToString(price),Name);
/// ПРАВИЛО 1
if (MY.Search_level_Robot(Input1, GetPriceStep_ind, Period, Enable_Recalculation, max_stop, gap).GetValue("Direction", 0) ==1)
{
EnterLongLimit(price+gap,1);
BreakingStop(max_stop, (max_stop*4), SignalPriceType.Price);
LogData ("заявка в лонг + стоп " ,Name);
//BreakingStop(0.1, 0.4, SignalPriceType.DeltaInPercentFromAveragePrice);
}
/// ПРАВИЛО 2
if (MY.Search_level_Robot(Input1, GetPriceStep_ind, Period, Enable_Recalculation, max_stop, gap).GetValue("Direction", 0) ==2)
{
EnterShortLimit(price-gap);
BreakingStop(max_stop, (max_stop*4), SignalPriceType.Price);
//BreakingStop(0.1, 0.4, SignalPriceType.DeltaInPercentFromAveragePrice);
LogData ("заявка в шорт + стоп " ,Name);
}
}
}
Робот выключается так как неможет обратиться к коду
Код: Выделить всё
double price=(MY.Search_level_Robot(Input1, GetPriceStep_ind, Period, Enable_Recalculation, max_stop, gap).GetValue("Last1", 0));
LogData ("Разрешаем открывать позицию за 30 секунд - " + Convert.ToString(MY.Search_level_Robot(Input1, 2, Period).GetValue("Dictionary")),Name);
Лог приведён выше.
Значит надо контролировать время разрешение на построение линии индикатором, а нетолько открытия позиции роботом.
Хотелось бы, что бы "oxi" более детально рассказал про взаимодействие робота и индикатора (на каком такте (цикле) робот получает данные с индикатора и отправляет данные. Интерисует динамика (данные в переменной робота поменялись), как поведет себя индикатор. Когда вернутся новые данные?
Так же в роботе переменные меняешь, запускаешь робота когда они обновятся. (Пробоваль менять переменные менялись как то медленно).