FAQ
5 апреля 2010
В этой теме любой посетитель сайта в комментариях может задать любой вопрос о торговых роботах и получить квалифицированную помощь. Также тут обсуждаем новости из мира автоматизации торговых стратегий.
В этой теме любой посетитель сайта в комментариях может задать любой вопрос о торговых роботах и получить квалифицированную помощь. Также тут обсуждаем новости из мира автоматизации торговых стратегий.
В статье про тестирование робота на исторических данных Вы писали:
Итак, мы получили нужные нам данные, теперь приступим к модификации робота, например нашего «Торговый робот пробойный». Во первых нам нужно в самом начале, в первой части переменной PRICE присвоить значение из полученного нами файла с данными. Это делается с помощью функции READ_LINE:
Если НЕЛЬЗЯ
подскажите как? Если все таки можно где про это почитать? Огромное Спасибо за то что тратите время на нас!
Евгений Reply:
апреля 7, 2010 at 19:18
Привет.
В смысле «нельзя»?
Например, у нас есть файл с историческими данными такого формата:
time;last
...
time;last
Т.е. время и цена на момент времени, т.е. «тики». с помощью определенной функции узнаем количество строк в этом файле, делаем цикл от 1 до полученного числа. С помощью функции READ_LINE читаем в цикле каждую строку, и опять с помощью цикла разбираем полученную строку на символы. Делаем проверку если символ<>«;»то этот символ соединяем с предыдущим — это у нас будет «время». Как только встречается символ «;» то каждый последующий соединяем в отдельную переменную — это будет цена, до тех поб пока не получаем «пробел» вместо символа — это конец строки из файла. Приводим последнюю в цифровой вид (+0) и в итоге у нас две переменные: время и цена. Для «ПРобойного» этого конечно маловато, т.к. из этих цен нужно формировать бары. но ведь с того же финама можно скачать конкретный таймфрейм с полным OHLC и делать уже не две а пять переменных: время и OHLC.
Итак, получили в цикле эти переменные, а дальше, внутри того же цикла у нас торговый алгоритм, которому мы подсовываем данные цены, как будто мы получили их в реалтайме из графика. Но в самих торговых блоках, мы не отправляем транзакцию, а также пишем в файл (другой) строку например: 123433;покупка по;154345, где первое — то самое полученное время, второе операция, третье цена. Ну лоты можно также записать. В самом начале робота заводим глобальную переменную ТР, которой в блоках торговой логики будет присваиваться значение текущей позиции.
Вот как то так.
Привет,Евгений а по ТР можно по подробне,завели глобальную переменную ТР=0,обнуляем IF TP=0 AND STOPORDERCOUNT=0 ,а вот как присваивать значение текущей позиции не понятно.
Евгений Reply:
апреля 7, 2010 at 20:25
присваивать:
ТР=1
Все, присвоили значение равное единице. И если эта переменная определена как глобальная — значит с каждой итерацией она сохраняет последнее значение.
IF TP=0 AND STOPORDERCOUNT=0 — это не обнуление!! Это условие.
ТР=0 — вот обнуление.
Если далее развивать тему вышеописанного алгоритма по тесту на исторических данных — то если по условиям логики у нас должен быть лонг, мы ТР присваиваем единицу и сразу пишем в файл запись о покупке. если шорт то ТР=-1 и также запись. Потом в экселе. например, загружаем полученный файл и считаем результат. Или де сразу в роботе считаем результат и выводим его в таблицу.
теперь понятно, при реал тесте анологично
Здраствуйте.
Столкнулся с такой проблемой. При получении цены последней сделки:
PRICE=GET_VALUE (GET_PARAM_EX («SPBFUT»,INSTRUMENT,"LAST"),"PARAM_VALUE")+0
Программа всегда выдаёт 0. Хотя буквально неделю назад точно эта же программа выдавала правильное значение цены. Значения скользящих средних, фракталов и т.д. всё выдаёт правильно, а цену не могу получить. С чем это может быть связана? Всё уже вроде посмотрел((
Спасибо.
Евгений Reply:
апреля 12, 2010 at 20:01
Это может быть связано с неверным кодом бумаги, либо бумага отсутствует в списках доступных бумаг.
Привет, Евгений!
Не пойму, что могло случиться: функция READ_LINE не работает. Робот пишет unexpected ошибку.
Загрузил из справки QUIK пример:
WRITELN («new.log»,"Hello, world")
msg=READ_LINE («new.log», GET_FILE_LEN («new.log»), 0))
MESSAGE (msg,1)
— та же история.
Понимаю, что, наверно, не совсем по адресу, но может Вы уже столкивались с такой проблемой и можете подсказать решение.
Rem Reply:
апреля 16, 2010 at 20:25
Связался с техподдержками своего брокера, компании QUIK. В ответ на этот вопрос — тишина.
Методом тыка все-таки сумел найти какое изменение разработчики внесли в эту функцию, но не внесли его в справку QUIK:
Вот код из справки QUIK:
WRITELN («new.log»,"Hello, world")
msg = READ_LINE («new.log», GET_FILE_LEN («new.log»), error))
MESSAGE (msg,1)
Понятно, что вместо error записываем 0.
Теперь рабочий код, что называется, почувствуйте разницу:
WRITELN («new.log»,"Hello, world")
msg= READ_LINE («new.log», GET_FILE_LEN («new.log»), 0)
MESSAGE (msg,1)
Вот из-за этой закрывающей скобки — этого своего тихого «усовершенствования» в недавнем обновлении версии QUIK робот не работал несколько дней.
Евгений Reply:
апреля 18, 2010 at 17:39
Думаю что вместо нуля, надо в функцию прописать заранее объявленную переменную:
ERROR=0WRITELN ("new.log","Hello, world")msg=READ_LINE ("new.log", GET_FILE_LEN ("new.log"), ERROR))MESSAGE (msg,1)MESSAGE (ERROR,1) ' РЕЗУЛЬТАТ ВЫПОЛНЕНИЯ ФУНКЦИИ, ЕСЛИ НОЛЬ - УСПЕШНО.Здравствуйте, Евгений!
Необходимо в нужные моменты выключать робот. Сделать это можно убрав галочку из -> доступные портфели. Если нужно отключить не весь робот, а например, только функцию выставления заявки, то можно в коде задать соответствующее условие, параметры которого будут изменяться в текстовом файле (в текстовый файл вручную записываешь ВЫКЛ. и читаешь это с помощью READ_LINE).
Но это неудобно, неоперативно, некрасиво и неэлегантно ))
Вопрос следующий: можно ли в выпадающий список моей таблицы добавить какую-либо активную строчку (ведь во встроенных таблицах QUIK наименование таких строчек вариьируется). Если нет, то может, здесь нужен какой-то привод?
Евгений Reply:
апреля 21, 2010 at 19:38
ЭЭЭээээ... А правой кнопкой по таблице робота и «Приостановить работу» не устраивает?
Rem Reply:
апреля 21, 2010 at 20:03
Это крайний вариант, когда пожар бушует...
Но элегантным было бы отключить только одну из частей робота...
Если серьезно, то нужно привод какой-то придумывать, чтобы и количество лотов вводить и приостанавливать робота и много чего, не вмешиваясь в код робота и заново его не переустанавливая...
Если чего посоветуете, думаю всем будет полезно.
Евгений Reply:
апреля 22, 2010 at 20:41
Тогда думаю надо на AutoIT написать небольшую прогу, которая создает текстовый файл, в котором пишет построчно кол-во лотов, и вкл/выкл, ну и еще какие то параметры. а робот уже предложенным вами способом читает этот файл и соответствующим образом действует. Но проще сразу писать в файл руками
Здравствуйте, Евгений! помогите разобратся написл робота: вход по пробитию экстримума, выход по тэйкпрофиту,ограничения убытка по стопу,
не могу добится чтобы робот не отпровлял заявки на вход пока не исполнется тэйк или стоп,надо как в Black Hole пока неисполнется тэйк или стоп бот не производит расчет
Евгений Reply:
мая 23, 2010 at 19:24
Отправляйте заявки только тогда, когда нет активных заявок и/или стопов, в зависимости от стратегии! Посмотрите, в БХ именно так и сделано.
Срасибо за помощь,я правильно понял:
IF TP=0 AND ORDERCOUNT=0 AND STOPORDERCOUNT=0
Евгений Reply:
мая 24, 2010 at 18:46
Да.
Здравствуйте, Евгений!помогите с решением, при определения уровня пробоя я приравневаю уровень к CURRENT,пример по хаю
IF CURRENTHIGH>HIGH
HIGH=CURRENTHIGH
но придостижении тейка,если цена продолжает движение вверх,выстовляется новая заявка на покупку,если приронять так CURRENTHIGH=HIGH,то при откате назад новая заявка на покупку,а надо чтобы привыполнении тэйка или стопа уровень пробития определялся уже на следущем баре
Одно от другого не зависит. Этим условием вы получаете значение верхнего экстремума, от которого отталкивается вся программа. Если после достижения тейкпрофита вам не нужно входить в рынок в эту же сторону — сделайте условие что вход только при рождении новой свечи. это будет правильней.
вот здесь мой мозг и закипел,
IF TP=0 AND ORDERCOUNT=0 AND STOPORDERCOUNT=0 AND NUMBER=2
Евгений Reply:
мая 24, 2010 at 21:04
А причем тут номер бара? Вы же его задаете в начале программы, в переменных.
попытка угадать,не могу понять как сделать условие что вход только при рождении новой свечи.
Евгений Reply:
мая 24, 2010 at 21:17
Заведите две переменные под OHLC:
HIGH
HIGH_PREV
т.е. текущий хая и предыдущий. Если вновь получаемый хай не равен предыдущему и одновременно не равен нулю — то факт рождения новой свечи. Теже операции нужно провести и с остальными составляющими OHLC для гарантии. ну и соответственно каждую итерацию программы приравнивать:
HIGH_PREV=HIGH
после вышеописанного анализа.
Спасибо, сам не сделал бы очень долго.
alex_davyd Reply:
мая 25, 2010 at 0:03
сделал вот так:
'========= ПОЛУЧАЕМ ДАННЫЕ СВЕЧЕЙ
OHLC (1)
HIGH_PREV=HIGH
LOW_PREV=LOW
OHLC (NUMBER)
IF HIGH_PREVHIGH AND HIGH_PREVHIGH0
HIGH_PREV=HIGH
END IF
IF LOW_PREVLOW AND LOW_PREV0
LOW_PREV=LOW
END IF
не работает,CURRENT удалил
alex_davyd Reply:
мая 25, 2010 at 0:06
знак неравенство не отобразился
Евгений Reply:
мая 25, 2010 at 9:16
Я же написал как сделать! Не выдумывайте.
alex_davyd Reply:
мая 25, 2010 at 17:15
Евгений,я не выдумываю ,я просто не могу понять как это правильно описать, вот и сделал как CURREN в пробойном,вы профи в купале и написали как для уже продвинутого а я самоучка изучаю язык на ваших примерах и комментариях,и использую ваши готовые блоки,
завел переменные, обнулил,прировнял ,вот так я понял:
HIGH=0
HIGH_PREV=0
OHLC (NUMBER)
HIGH_PREV=HIGH
Евгений Reply:
мая 25, 2010 at 23:05
Ту дело не в купайле, тут дело в логике. Просто нужно выстроить логическую цепочку. Моя цель чтоб вы научили не только писать на купайле, но и алгоритмически думать.
HIGH=0
NEW_GLOBAL («HIGH_PREV»,0)
OHLC (NUMBER)
IF HIGH<>HIGH_PREV AND HIGH_PREV<>0
' НОВАЯ СВЕЧА
END IF
HIGH_PREV=HIGH
Привет, Евгений!
Что лучше: передвигать заявку, опасаясь превышения лимита по количеству заявок за сессию или продать (купить) по рынку в тот момент, когда bid (offer) достигает заданного уровня?
Евгений Reply:
июня 30, 2010 at 20:44
Привет!
Тут выбирать вам, лимит хорош тем, что ограничивает проскальзывание. Но в таком случае, если стратегия предусматривает большое кол-во заявок, можно превысить лимит кол-ва бесплатных, неисполненных заявок.
Но я сам, в своих роботах как правило отслеживаю бид/оффер, чтоб маркетом открыть\закрыть позицию. Минус — если этот момент попадет на сильное движение — будет проскальзывание.
Если вы планируете использовать арбитражную стратегию, то там, конечно, надо использовать лимиты на одном инструменте пары. Как вариант рассмотрите вариант увеличения периода расчета портфеля, например при 1 итерации в 10 сек кол-ва бесплатных заявок может хватить на 5-6 часов торгов.
Rem Reply:
июня 30, 2010 at 21:01
Спасибо за ответ.
Думаю, что маркет удобнее, тем более, что можно последить роботом не только за лучшими ценами в стакане (отдельный респект за трепанацию стакана).
Насчет арбитражных стратегий не понял: какая разница, если спрэд считать не по ценам закрытия, а также по бидам и офферам.
Евгений Reply:
июня 30, 2010 at 21:07
В арбитраже по первой бумаге в паре лучше входить лимитом. Это так. к слову
Добрый день!
Евгений, а у вас случайно нет скрипта на qpile для отображения котировок.
Например есть крафик ГАЗПРОМА и чтобы по нему выводить таблицу в виде
data time open close high low volume
Или я ошибаюсь может в Квике есть такая возможность?
Смысл такой хотелось бы эту табличку выводить по DDE в Эксель.
Евгений Reply:
июля 6, 2010 at 21:56
Привет.
Посмотрите тему — www.hirobot.ru/2010/04/ka...grafika-2-chast/
Спасибо за предыдущий ответ почти то что нужно!
А вот еще один вопрос а возможно ли сделать скрипт но чтобы он отрабатывался по команде внешей программы.
Ну например есть скрипт№1 в нем установлено RETURN= false
и имеется текстовый файл где находится значение переменной false или true.
Если в текстовеке false скрипт нечего не делает если true значит скрипт отработался.
Евгений Reply:
июля 7, 2010 at 10:28
Конечно можно! У QPILE есть функции записи и чтения из файла, а также обработки этих данных. Почитайте сайт, есть такая публикация www.hirobot.ru/2009/05/kak-sozdavat-log/ и www.hirobot.ru/2009/05/ka...x-dannyx-v-quik/ в них описано как пользоваться этими функциями.
Здравствуйте, Евгений я в своем роботе использую два вида стоп заявак одну стоп лимит,другую тейкпрофит с отступом и защитным спредом,немогу понять как сделать чтобы при активации тейкпрофита стоплимтная снималась,в принцепе условие не обязательное,у меня стопы удаляются при смене напровления и закрытие позиции,но для элегантности да и деньги чтоб не блокировались под лишнии стопы
Евгений Reply:
июля 20, 2010 at 18:33
Привет.
Как я понял у вас при открытой позиции две активных стопзаявки, одна «стоплосс» вторая «тейкпрофит». И при исполнении одной из них надо чтоб вторая снималась. Решение: при отсутствии открытых позиций и кол-ве активных стопов>0 — удаляйте все стопы.
Привет уменя сечас реалезованно имено это решение , я использываю именно квиковский текпрофит,TRANS_PARAMS = SET_VALUE (TRANS_PARAMS, «STOP_ORDER_KIND», «TAKE_PROFIT_STOP_ORDER»),хотелось чтоб после активации цены тейка , стоп лимит снимался,и остовался один тейк
Евгений Reply:
июля 20, 2010 at 19:12
Отслеживайте в таблице «стопзаявки» свойства этого «тейкпрофита» и при соответствующем изменении снимайте второй стоплимит.
Добрый день, Евгений!
Глобальная переменная при рестарте или запуске портфеля (например, с утра) принимает значение, заданное в начальных установках портфеля.
Можно ли сделать так, чтобы глобальная переменная хранилась без изменений несколько дней (при этом ПК на ночь выключается) и при запуске портфеля не изменялась?
Евгений Reply:
августа 4, 2010 at 12:16
Привет. В таком случае необходимо нудный вам параметр записывать в файл, и каждую итерацию считывать его содержание и присваивать последнее нужной вам переменной.
Rem Reply:
августа 4, 2010 at 12:57
В таком случае глобальная переменная вообще не нужна, т.к. ее функцию будет выполнять описанный Вами процесс. Именно такой процесс мне приходиться уже давольно давно использовать в своем роботе, но это очень громоздко (робот уже имеет 4451 строчки) и из-за этого он немного притормаживает, что сказывается на величину профита (из-за проскальзываний при работе со стаканом).
Евгений, а где вообще хранятся значения глобальных переменных: на моей машине или где-то на сервере?
Евгений Reply:
августа 5, 2010 at 17:25
Привет.
Значения глобальных переменных хранятся локально. Если вас не устраивает вариант с файлом (хотя на мой взгляд капля в море), не выключайте компьютер и не закрывайте QUIK, в таком случае глобальная переменная сохранит свое значение.
4 тысячи строк — это много...
День добрый!
Убился, не могу выцепить цену последней сделки по определенному инструменту. Логика такая:
N=GET_NUMBER_OF («TRADES»)
IF N>0
FOR I FROM 0 TO N
IF (GET_VALUE (GET_ITEM («TRADES», C), «SECCODE»)=INSTRUMENT) AND (GET_VALUE (GET_ITEM («TRADES», C), «TRDACCID»)=ACCOUNT)
PRICEEND=GET_VALUE (GET_ITEM («TRADES», C),"PRICE")+0 ' ПОЛУЧАЕМ ЦЕНУ КРАЙНЕЙ СДЕЛКИ
END IF
END FOR
END IF
Чую, где-то не прав и ничего тут нет сложного, но заклинило.
Помогите, плиз.
Сергей Reply:
сентября 1, 2010 at 12:10
Прошу прощения, вот так, конечно.
Но сути это не меняет
N=GET_NUMBER_OF («TRADES»)
IF N>0
FOR I FROM 0 TO N
IF (GET_VALUE (GET_ITEM («TRADES», I), «SECCODE»)=INSTRUMENT) AND (GET_VALUE (GET_ITEM («TRADES», I), «TRDACCID»)=ACCOUNT)
PRICEEND=GET_VALUE (GET_ITEM («TRADES», I),"PRICE")+0 ' ПОЛУЧАЕМ ЦЕНУ КРАЙНЕЙ СДЕЛКИ
END IF
END FOR
END IF
Сергей Reply:
сентября 2, 2010 at 12:27
Нашел проблему.
Называется для бестолковых — если что-то не работает, читай первоисточник, т.е. справку по алгоритмическому языку.
Короче — номер торгового счета в таблице сделок функция GET_ITEM возвращает параметром ACCOUNT.
Может пригодится кому.