Особенности торговых роботов для ММВБ
Уважаемые друзья! Поздравляю Вас с наступающими праздниками! С днем великой ПОБЕДЫ!
Этой статьей я начинаю цикл публикаций, посвященных нюансам написания торговых роботов.
С самой первой публикации мы с Вами говорили о торговых роботах адаптированных для площадки ФОРТС. Настало время разобраться наконец в вопросах, различающих код торгового робота для разных площадок. Вся основная разница в трех моментах:
1. Получение данных по аккаунту;
2. Получение данных текущей позиции;
3. Код класса бумаги.
Теперь по порядку. На ФОРТС состояние счета и доступных средств мы получаем из таблицы «Ограничения по клиентским счетам», и выглядит это так:
MoneyCurrentBalance = GET_VALUE(GET_ITEM("FUTURES_CLIENT_LIMITS",1), "CBPLIMIT")
Этой функцией мы получаем значение поля CBPLIMIT (Лимит открытых позиций) в строке номер 1 таблицы ограничений. Но у некоторых брокеров сейчас в эту таблицу транслируется несколько строк, в которых указываются значения до клиринга, после, залоговые рубли и т.д. И в строке номер один может не оказаться нужных данных. Из этих строк нужный нам лимит открытых позиций можно отличить по единичке в поле «Коэффициент ликвидности» — это реальные деньги, там где ноль — не смотрим. И чтобы универсализировать процесс, сделаем так:
FOR I FROM 0 TO GET_NUMBER_OF("FUTURES_CLIENT_LIMITS") ' делаем цикл по таблице "Ограничения по счетам"
IF GET_VALUE (GET_ITEM ("FUTURES_CLIENT_LIMITS", I), "LIQUIDITY_COEFF")+0=1
LIMITOPEN=GET_VALUE (GET_ITEM ("FUTURES_CLIENT_LIMITS", I), "CBPLIMIT")+0
VARMARGIN=GET_VALUE (GET_ITEM ("FUTURES_CLIENT_LIMITS", I), "VARMARGIN")+0
ACCRUEDINT=GET_VALUE (GET_ITEM ("FUTURES_CLIENT_LIMITS", I), "ACCRUEDINT")+0
COMISSION=GET_VALUE (GET_ITEM ("FUTURES_CLIENT_LIMITS", I), "TS_COMISSION")+0
ACCOUNT=GET_VALUE(GET_ITEM("FUTURES_CLIENT_LIMITS",I), "TRDACCID")
I=GET_NUMBER_OF("FUTURES_CLIENT_LIMITS")
END IF
END FOR
Делаем цикл перебора строк в этой таблице, и при каждой новой строке смолтрим в поле «Коэффициент ликвидности». Как только находим там единичку — это наша искомая строка. В результате получаем значения лимита открытых позиций, вармаржи, накопленного дохода, комиссии и аккаунта. И не забываем закончить цикл, иначе правильные данные не получим (за исключением варианта, когда искомая строка будет последней).
Как торговому роботу получить данные на площадке ММВБ?
На площадке ММВБ значение доступных средств транслируется в таблицу «Лимиты по денежным средствам», но по мне удобнее брать значение из таблицы «Клиентский портфель»:
GET_VALUE(GET_CLIENT_MARGINAL_PORTFOLIO_INFO(FIRMAMICEX,ACCOUNTMICEX),"IN_ASSETS")
Здесь мы получаем значение доступных средств на начало торгов. Почему из этой таблицы — в ней есть все необходимое, но, как вы уже заметили, в представленной функции есть две переменные: FIRMAMICEX и ACCOUNTMICEX. Они отвечают, как можно догадаться, за идентификаторы «фирмы» и «клиента», естественно эти значения мы получаем автоматически ДО применения функции получения из таблицы «Клиентский портфель»:
ACCOUNTMICEX=GET_VALUE(GET_ITEM("MONEY_LIMITS",1), "CLIENT_CODE")
FIRMAMICEX=GET_VALUE(GET_ITEM("MONEY_LIMITS",1), "FIRMID")
Ситуация аналогична первому примеру для ФОРТС в плане номера строки, из которой мы получаем. Но в QUIK на ММВБ как правило строка в этой таблице одна (если у вас один счет).
Итак, с аккаунтами и средствами разобрались.
Как торговому роботу узнать состояние текущей позиции по определенной бумаге?
На ФОРТС мы делали так:
INSTRUMENT="RIM0"
TP=0 ' объявляем переменную, обнуляем ее, чтоб при каждой итерации торгового робота переменная была объективна
FOR I FROM 0 TO GET_NUMBER_OF("FUTURES_CLIENT_HOLDINGS") ' цикл по таблице "Позиции по клиентским счетам"
IF GET_VALUE (GET_ITEM ("FUTURES_CLIENT_HOLDINGS", I), "SECCODE")=INSTRUMENT ' просматриваем каждую строку в поиске определенного инструмента
TP=GET_VALUE(GET_ITEM("FUTURES_CLIENT_HOLDINGS",I), "TOTAL_NET")+0 ' берем значение поля "текущая чистая позиция"
END IF
END FOR
Все тот же перебор строк, который очень часто применяется в QUIK в силу табличной ориентации последнего. В этому случае мы просматриваем таблицу «Позиции по клиентским счетам» и ищем соответствующий инструмент. Если по жтому инструменту еще не было ни одной сделки и его нет в таблице — этот код его там не найдет, на этот случай у нас есть обнуленная переменная. которая нам скажет что текущая чистая позиция по выбранной бумаге равна нулю. Все верно!
Вариант ММВБ:
TP=0
FOR I FROM 0 TO GET_NUMBER_OF("DEPO_LIMITS") ' делаем цикл по таблице "Лимиты по бумагам"
IF GET_VALUE(GET_ITEM("DEPO_LIMITS",I), "SECCODE")=INSTRUMENT ' ищем строку с выбранным кодом бумаги
TP=GET_VALUE(GET_ITEM("DEPO_LIMITS",I), "CURRENT_BALANCE")+0 ' получаем значение поля "Текущий остаток по бумагам"
END IF
END FOR
В принципе все тоже самое что и на ФОРТС, только таблица и поле другое. Но принцип тот же.
Как торговый робот определяет код класса?
Если на ФОРТС с кодом класса все понятно — для фьючерсов он всегда «SPBFUT» для опционов «SPBOPT», то на ММВБ классов много. и используя один и тот же робот для нескольких бумаг, чтоб каждый раз не прописывать в ручную код класса (который кстати находим в таблице текпараметров) есть простая функция получения кода класса по коду бумаги:
INSTRUMENT="SBER03"
CLASSCODE=GET_VALUE(GET_SECURITY_INFO("",INSTRUMENT),"CLASS_CODE")
Теперь Вы уже можете самостоятельно ориентировать торговых роботов под ту или иную площадку. Наименования полей и таблиц берите из руководства пользователя QUIK.
Спрашивайте!
Приветствую Евгений, к сожалению вы не упомянули как подсчитать активные заявки на ММВБ
Kobalt Reply:
мая 4, 2010 at 13:47
Я так понял что нет в qpile поля отражающего кол-во активных заявок на ммвб. Для подсчета колва активных заявок на форуме qpile мне предложили использовать этот код
n=get_number_of («ORDERS»)
sch=0
for i from 1 to n
sec_oper = «S»
trade=get_item («ORDERS»,i)
dd=substr (get_value (trade, «OPERATION»),0,1)
ee=get_value (trade, «STATUS»)
'условием проверяем, что заявка с интересующим нас кодом по 'выбранному направлению(покупка/продажа) — активна
if dd=sec_oper and ee= «ACTIVE»
sch=sch+1
end if
end for
ORDERCOUNTSELL=sch
1.Корректно ли использовать его в данном случае?
2. При прогоне кода
TP=0
FOR I FROM 0 TO GET_NUMBER_OF («DEPO_LIMITS») ' делаем цикл по таблице «Лимиты по бумагам»
IF GET_VALUE (GET_ITEM («DEPO_LIMITS»,I), «SECCODE»)=INSTRUMENT ' ищем строку с выбранным кодом бумаги
TP=GET_VALUE (GET_ITEM («DEPO_LIMITS»,I), «CURRENT_BALANCE»)+0 ' получаем значение поля «Текущий остаток по бумагам»
END IF
END FOR
в отладчике в TP попадает значение 31 это вообще что?
Евгений Reply:
мая 5, 2010 at 19:46
1. Это как раз о чем я говорю. Посмотрите на моем сайте, где то был мой вариант этого блока.
2. 31 — судя по всему это текущая позиция по отфильтрованной бумаге. Есть еще один вариант получения текпоза на ММВБ:
[code='css']
TPMICEX=DEPO_CURRENT_BALANCE (ACCOUNTMICEX, FIRMAMICEX, INSTRUMENT, ACCOUNTDEPO)+0
[/code]
По переменным понятно которая за что отвечает.
Евгений Reply:
мая 5, 2010 at 19:42
Точно также как и на ФОРТС, делаем цикл по таблице заявок, фильтрует по статусу «Активная». На ФОРТС есть еще один вариант, это из таблицы «позиции».
Где-то на страницах сайта поднимался вопрос о методе определения цены приобретения бумаг (она же балансная стоимость) для выбранной открытой позиции на ММВБ, но где именно, найти уже не получается. И кажется решение этого вопроса предложено не было (хотя могу и ошибаться). Просмотрев описание таблиц по квику так же не нашел откуда его можно взять. Думаю вопрос будет актуальным для многих, если кто знает ответ — пожалуйста подскажите.
@Prof
Порылся, нашел пример решения в файле portfolio.qpl:
www.quik.ru/depot/qpile.zip
Портфель расчитывает прибыли убытки по позициям клиента.
Осталось разобраться как и сделать себе что-то подобное.
@Prof
Посмотрел portfolio.qpl: значения цены и объема по открываемым сделкам сохраняются в файл с последующим извлечением данных и рассчетом балансной.
Не впечатляет...
Подскажите, можно ли, и если да, то как получить данные из Таблицы лимитов по бумагам (тбл. Купить/Продать или какой другой) непосредственно из квика? Он же эти значения где-то хранит, значит к ним можно обратиться. Еще раз перерыл документацию — ответа не нашел. Видимо плохо смотрю.
P.S. Не хочется устраивать танец с бубном вокруг файла: хочется что-то легкое и изящное, в 2-3 строчки
Евгений Reply:
июня 23, 2010 at 18:39
когда у вас будет открыта позиция на ММВБ посмотрите в таблице лимитов по бумагам, там есть поле в котором отображается стоимость покупки бумаг.
Prof Reply:
июня 24, 2010 at 13:01
Вот именно от туда я хочу брать данные программно. Но не могу найти информацию о том, как это сделать.
Евгений Reply:
июня 24, 2010 at 23:24
Отписал в почту.
igor1968 Reply:
июня 24, 2010 at 15:38
Там показывает общий остаток и среднюю цену бумаги в портфеле. А мне необходимо сделать так таблицу, чтобы все приобретения были видны именной по той цене, по которой были куплены, а при продаже исчезали из данной таблицы.
У меня простой вопрос! Как сформировать таблицу купленных, но еще не проданных лотов. Т.е. купленный лот должен автоматически попасть в эту таблицу, а проданный также автоматом из нее исчезнуть.
При частичной продаже, в таблице остается лот с остатком ЦБ.
Аналогично, таблица заявок: выставленная заявка висит в таблице, а удовлетворенная — исчезает. Буду признателен за мысль, может даже где-то уже и код есть, я бы поразбирался...
Евгений Reply:
июня 24, 2010 at 23:30
Таблица купленных — т.е. список бумаг, с текущей позицией отличной от «нуля» — это легко. если текпоз=0 то просто в программируемую таблицу не вносится/удаляется если был в ней.
Тоже самое с таблицей заявок. если активна — есть в программируемой таблице. не активная нет/удалена.
и то и другое можно сделать взяв соответствующие куски кода на сайте. Вам нужны блоки подсчета текпоза, и блок подсчета активных заявок. На основе этих данных формируете свою таблицу.
igor1968 Reply:
июня 25, 2010 at 11:29
Спасибо за ответ. Я на сайте новичок, еще плохо ориентируюсь. Может «ткнете носиком» на соответствующий код (если не сложно) или хотя бы в какой теме эта ситуация разбиралась.
Евгений Reply:
июня 25, 2010 at 17:59
www.hirobot.ru/2009/06/to...a-quik-defender/
В этой теме выложен код робота «Дефендер». У него есть все необходимое чтоб построить два робота для вашей задачи. Вам нужны блоки подсчета текущей позиции для первого робота, и блок подсчета и перебора активных заявок для второго робота. Если с постройкой этих роботов возникнет проблема — обращайтесь в личку.
Доброго времени суток.
Евгений, подскажите, можно ли в квике программно получить информацию о том, какой сегодня день недели? Хочу автоматически закрывать сопровождаемые сделки не каждым вечером, а только по пятницам.
Евгений Reply:
июня 26, 2010 at 20:56
ПРивет.
Есть функция получения дня недели:
VALUE=GET_VALUE (GET_DATETIME (),"DAYOFWEEK"))
на выходе — порядковый номер дня недели (воскресенье – 0, понедельник — 1, вторник – 2, среда – 3, четверг – 4, пятница -5, суббота – 6)
Подробнее смотрите в разделе 8.23.2 руководства пользователя.
Евгений Reply:
июня 26, 2010 at 20:58
В догонку: есть специальный раздел для вопросов общего характера: www.hirobot.ru/voprosyotvety/
Там информацию будет проще искать посетителям.