Робот.

Модернизируем робота работающего через Quik API. Прикручиваем стопы.


Это попытка показать с комментариями как изменить представленного ранее робота чтобы он мог исполнять стопы.

Если хотите использовать эту схему, то надо обновить плагин AS_File. Старая версия плагина (до февраля 2012г) сохраняла в файл только целые цифры, а при сохранении цены входа требуется записывать и дробные значения.

Саму систему оставим, только добавим в неё стоп 1% по LKOH и 2% по SBER.

У нас есть простой механизм записи необходимых параметров в файл. Воспользуемся этой возможностью и для начала запишем в файл Quik_Robot цену входа в позицию. Можно записать и последнюю цену инструмента, по которому была совершена сделка и ту цену, по которой тестировали систему. Запишем системную цену, чтобы работа робота была максимально приближена к тестируемой системе. Эту цену в последствии будем использовать для расчета срабатывания стопа.
Разумеется, можно сразу рассчитать и записать цену стопа, но в том случае если размер стопа будет меняться, лучше записать именно цену входа и от неё вести расчеты. Надо заметить, что если делать трейлинг, то проще писать в файл именно цену стопа и при необходимости её переписывать.
И так, сначала в настройках символов зададим размеры стопов.

if(Name() == "LKOH") { // Символ как он называется в Ами SecCode = "LKOH"; Class = "EQBR"; Lots = 5; TickS = 0.1; // Минимальный шаг цены торгуемой бумаги Stop = 1; // стоп в % Otstup = 20; // Заявка будет выставлена хуже текущей цены на Otstup рублей } else if(Name() == "SBER") { // Символ как он называется в Ами SecCode = "SBER03"; Class = "EQBR"; Lots = 2; TickS = 0.01; // Минимальный шаг цены торгуемой бумаги Stop = 2; // стоп в % Otstup = 1; // Заявка будет выставлена хуже текущей цены на Otstup рублей }

затем изменим процедуру orders чтобы она записывала не только позицию, но и цену входа
procedure orders(bs, pr, Lot) { connection = 0; QC = AS_QUIK_CONNECT(Quik); if (QC == 1) { connection = 1; text = "Есть соединение с сервером"; Color = colorGreen; } else if (QC == -1) { text = "нет соединения с квиком"; Color = colorRed; } else if (QC == -2) { text = "нет соединения с сервером"; Color = colorRed; } else { text = "фигня какая то"; Color = colorRed; } if(connection == 1) { order = AS_QUIK_SEND_SYNC_NEWORDER( "123", // OrderID - Любые цифры Account, Client_Code, "L", // Тип заявки M-рыночная, L-лимитированная Class, SecCode, bs, pr, Lot); } if(StrToNum(order) > 100) { iz = "исполнена"; coloriz = colorGreen; str = str + " заяка исполнена" + " ответ сервера=" + order; if(pos > 0 AND bs == "S") // закрытие лонга { AS_WRITE_PARAM("Quik_Robot", Name(), "pos", 0); AS_WRITE_PARAM("Quik_Robot", Name(), "price", 0); } else if(pos == 0 AND bs == "S") // шорт { AS_WRITE_PARAM("Quik_Robot", Name(), "pos", -1*Lot); AS_WRITE_PARAM("Quik_Robot", Name(), "price", Close[BarCount - 2]); } else if(pos < 0 AND bs == "B") // закрытие шорта { AS_WRITE_PARAM("Quik_Robot", Name(), "pos", 0); AS_WRITE_PARAM("Quik_Robot", Name(), "price", 0); } else if(pos == 0 AND bs == "B") // лонг { AS_WRITE_PARAM("Quik_Robot", Name(), "pos", Lot); AS_WRITE_PARAM("Quik_Robot", Name(), "price", Close[BarCount - 2]); } str = str + " позиция на момент исполнения " + pos; } else { iz = "не исполнена"; coloriz = colorRed; str = str + " заяка НЕ исполнена" + " ответ сервера=" + order; } }

Теперь мы в любой момент можем узнать, по какой цене открыта позиция, конечно, если робот сейчас в рынке.
Вставим в систему проверку на срабатывание стопа и там же сразу запишем в лог что сработал стоп.
/// стопы /// if(pos > 0 AND L[BarCount-1] < AS_READ_PARAM("Quik_Robot", Name(), "price")*(1 - Stop/100)) { Sell1 = 1; str = str + " сработал стоп при лонге"; } else if(pos < 0 AND H[BarCount-1] > AS_READ_PARAM("Quik_Robot", Name(), "price")*(1 + Stop/100)) { Cover1 = 1; str = str + " сработал стоп при шорте"; }

Тут есть интересный момент. Можно использовать для определения стопа минимум и максимум цены соответственно позиции. В этом случае даже если цена достигнет стопа кратковременно в промежутке между сканированием рынка, то стоп сработает, а можно вместо H[BarCount-1] и L[BarCount-1] использовать последнюю цену Close[BarCount-1]. В этом случае стоп сработает только если в момент сканирования цена превысила уровень стопа. Первый вариант ближе к тестированному варианту, но в принципе имеет право на жизнь и второй.
Этот блок следует добавить после сдвижки сигналов, чтобы сигналы сгенерированные стопом не сдвигались, который просто для удобства тоже изменим.
Buy1 = Buy1[BarCount - 2]; Sell1 = Sell1[BarCount - 2]; Short1 = Short1[BarCount - 2]; Cover1 = Cover1[BarCount - 2];
Казалось бы все. Однако есть еще один момент который сразу не заметен. Что произойдет если стоп сработает на том же баре, на котором был вход в рынок? В файл Quik_Robot будет записана нулевая позиция, а сигнал на открытие на баре остался. Поэтому робот немедленно снова откроет позицию и сразу снова сработает стоп. Так будет продолжаться, пока не начнется следующий бар. Такое поведение надо исправить. Например сразу проверять бар на возможность срабатывания стопа и если он может сработать, то не генерировать сигнал.
Снова исправим блок сдвижки сигналов.
Buy1 = Buy1[BarCount - 2] AND L[BarCount - 1] > C[BarCount - 2]*(1 - Stop/100); Sell1 = Sell1[BarCount - 2]; Short1 = Short1[BarCount - 2] AND H[BarCount - 1] < C[BarCount - 2]*(1 + Stop/100); Cover1 = Cover1[BarCount - 2];


СКАЧАТЬ КОД


Вот и все. Робот со стопом готов.
Удачи.



Удачи.