Сборник торговых роботов
(тема закреплена, новые публикации будут появляться ниже)
В целях структурирования информации, завожу тему, в которой в комментариях будут публиковаться пользовательские торговые роботы, функции публикуемые посетителями ресурса. Это будет полезно как новичку, так и программистам со стажем в поисках готовых функций. Для облегчения поиска, при публикации делайте небольшое описание робота или функции, затем выкладывайте код. Для правильного отображения кавычек копируйте текст из виндового блокнота. Законченные и проверенные функции и роботы, будут выкладываться в раздел «Скачать торгового робота» с обязательным указанием авторства. Просьба ко всем, кто уже публиковал свой код на этом сайте, опубликовать заново в этой рубрике. Спасибо за понимание!
вот кому интерсно, написал трал-робота для отслежвания бумаг в лонге
==========================================================
PORTFOLIO_EX TralBot;
DESCRIPTION Трал-робот;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST FIRMID;
PROGRAM
'Трал-робот отслеживает снижение цены от достигнутого максимума на указанный процент
'В случае снижения больше чем на указанный процент, выставляется заявка на продажу бумаги
'с указанном так же в процентах отступом
'
'ВНИМАНИЕ! Робот работает только с лонгами
'
'Для работы необходимо изменить название площадки, название инструмента, код клиента, фирмы, счета
USE_CASE_SENSITIVE_CONSTANTS
RANDOMIZE ()
'Определим начальные параметры
NEW_GLOBAL («MaxPriceDeltaProcent», 0.10)' Максимальное снижение в процентах от пика
NEW_GLOBAL («MaxPriceDiscountProcent», 0.05) 'Отступ в процентах от цены для выставления заявки на выход
NEW_GLOBAL («InstrumentID»,"SBER03") 'Код бумаги для мониторинга
NEW_GLOBAL («TagID»,"EQBR")
NEW_GLOBAL («LogDirectory»,"C:\WORKFILES\QPILE\")
NEW_GLOBAL («ClientID»,"ХХХХХХХХХХХХХХ")
NEW_GLOBAL («FirmID»,"ХХХХХХХХХХХХХХХ")
NEW_GLOBAL («AccountID»,"ХХХХХХХХХХХХХХ")
NEW_GLOBAL («CurrencyID»,"SUR")
'Переменные для отслеживания пика
NEW_GLOBAL («PeakPrice»,0)
NEW_GLOBAL («PathToLogFile»,aGetLogFileName ()&"«)
UserConnected=IS_CONNECTED ()
IF UserConnected=0 THEN
aLogMessage („Внимание! Клиент отключен от сервера!“)
RETURN
END IF
'Сначала определим есть ли открытая позиция
'Если позиция есть, будем смотреть как движется цена
'Если цена преодалела рубеж включения трала, начинаем постоянно отслеживать
'хай, если они упал ниже чем на дельту выхода из позиции, то выходим из позиции
DepoBalance=DEPO_CURRENT_BALANCE (ClientID, FirmID, InstrumentID, AccountID)+0
IF DepoBalance>0 THEN 'Пока только для растущего рынка
CurrentPrice=GET_VALUE (GET_PARAM_EX („EQBR“,InstrumentID,»last"),"param_value")+0
IF CurrentPrice=0 THEN
'Странная цена, прекращаем расчет
RETURN
END IF
IF CurrentPrice>PeakPrice THEN
PeakPrice=CurrentPrice
END IF
'Проверим не преодалели ли мы рубеж
PriceDelta=PeakPrice-CurrentPrice
PriceDeltaProcent=PriceDelta/CurrentPrice*100
MyTable=CREATE_MAP ()
MyTable=SET_VALUE (MyTable,"Info",aGetTime ()&"«)
MyTable=SET_VALUE (MyTable,»Instrument","«&InstrumentID)
MyTable=SET_VALUE (MyTable,»PeakPrice",PeakPrice+0)
MyTable=SET_VALUE (MyTable,"DepoBalance",Depobalance+0)
MyTable=SET_VALUE (MyTable,"CurrentPrice",CurrentPrice+0)
MyTable=SET_VALUE (MyTable,"PriceDelta",PriceDelta+0)
MyTable=SET_VALUE (MyTable,"PriceDeltaProcent",PriceDeltaProcent+0)
IF PriceDeltaProcent>=MaxPriceDeltaProcent THEN
'ВЫХОДИМ ИЗ РЫНКА!
MyTable=SET_VALUE (MyTable,"Info","«)
MyTable=SET_VALUE (MyTable,»Instrument","«&InstrumentID)
ADD_ITEM (1,MyTable)
Quantity=DepoBalance
ExitPrice=CurrentPrice*(1-MaxPriceDiscountProcent/100)
'Округлим цену для заявки
ExitPrice=FLOOR (ExitPrice*100)/100
aSendSellOrder (InstrumentID, ExitPrice, Quantity)
RETURN
END IF
ELSE
'бумаги нет, выходим
MyTable=CREATE_MAP ()
MyTable=SET_VALUE (MyTable,»Info",aGetTime ()&"«)
MyTable=SET_VALUE (MyTable,»Instrument","")
ADD_ITEM (1,MyTable)
RETURN
END IF
ADD_ITEM (1,MyTable)
FUNC aSendSellOrder (Instrument, Price, Quantity)
new_global («trans_params», "") ' заводим две глобальные переменные
new_global («trans_result», "")
trans_params = "«
UID=RAND ()
trans_params = set_value (trans_params, „TRANS_ID“, UID&»") ' тот самый ИН транзакции
trans_params = set_value (trans_params, «ACTION», «NEW_ORDER») ' тип заявки, в данном случае обычная
trans_params = set_value (trans_params, «CLASSCODE», TagID) ' код класса
trans_params = set_value (trans_params, «SECCODE», Instrument) ' инструмент
trans_params = set_value (trans_params, «ACCOUNT», AccountID) ' здесь прописываем свой аккаунт на фортс
trans_params = set_value (trans_params, «CLIENT_CODE», ClientID) ' здесь свой код клиента
trans_params = set_value (trans_params, «OPERATION», «S») ' направление
trans_params = set_value (trans_params, «PRICE», Price&"«) ' цена
trans_params = set_value (trans_params, „QUANTITY“, Quantity&»") ' кол-во лотов
trans_params = set_value (trans_params, «Comment», «Hello, QUIK!»)
trans_params = set_value (trans_params, «Curr_Code», CurrencyID)
trans_result = SEND_TRANSACTION (30, trans_params) ' отправляем заявку в систему
RESULT=get_value (trans_result, «DESCRIPTION»)
aLogMessage (result) ' выводим в окно сообщений результат отправки
END FUNC
FUNC aGetLogFileName ()
DateTime=GET_DATETIME ()
FullPath=LogDirectory&"_MyLog-"&Get_Value (DateTime, «Year»)&Get_Value (DateTime, «Month»)&Get_Value (DateTime, «Day»)&".txt"
RESULT = FullPath
END FUNC
'Функция записи сообщений в окно сообщений и лог-файл
FUNC aLogMessage (MessageText)
Message (MessageText, 1)
WRITELN (PathToLogFile, aGetTime ()&": "&MessageText)
END FUNC
FUNC aGetTime ()
DateTime=GET_DATETIME ()
RESULT=SUBSTR (Get_Value (DateTime, «DateTime»), 0, 19)
END FUNC
END_PROGRAM
PARAMETER Info;
PARAMETER_TITLE Информация;
PARAMETER_DESCRIPTION Информация;
PARAMETER_TYPE STRING (255);
END
PARAMETER Instrument;
PARAMETER_TITLE Бумага;
PARAMETER_DESCRIPTION Бумага;
PARAMETER_TYPE STRING (255);
END
PARAMETER PeakPrice;
PARAMETER_TITLE Пик;
PARAMETER_DESCRIPTION Пиковая цена;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER CurrentPrice;
PARAMETER_TITLE Цена;
PARAMETER_DESCRIPTION Текущая цена;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER PriceDelta;
PARAMETER_TITLE Дельта от пика;
PARAMETER_DESCRIPTION Дельта от пика;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER PriceDeltaProcent;
PARAMETER_TITLE Процент от пика;
PARAMETER_DESCRIPTION Процент от пика;
PARAMETER_TYPE NUMERIC (10,2);
END
PARAMETER DepoBalance;
PARAMETER_TITLE Количество;
PARAMETER_DESCRIPTION Количество бумаг;
PARAMETER_TYPE NUMERIC (10,2);
END
Робот выложен в разделе «Скачать торгового робота» с правильными кавычками.
Робот проверен на лонгах, но сейчас я пишу более продвинутого робота в который будет добавлено
' 1. Загрузка из файла параметров управления роботом (бумага, проценты, вкл/выкл)
' 2. Вывод в таблицу по одной строке на каждую управляемую бумагу, а так же сумма заработанной прибыли (осталось только решить проблему с полученмем средневзвешанной цены покупки бумаги... ни как не получается ее выудить)
' 3. Реализовать включение трала после достижения какого-либо уровня
' 4. Работа с шортами
Выложить конечно можно и текущий, но только как демо-образец с пометкой «не для использования в работе»
простенький робот по мовингам (ставит на графике где покупать, где продавать без отправки транзакций) Нужно еще дорабатывать.
Можете не опубликовывать.
PORTFOLIO_EX MOVAV;
DESCRIPTION MOVAV;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST FIRM_ID;
PROGRAM
func format_date (mDateTime)
result=0
tYear = 0+get_value (mDateTime, «YEAR»)
tMonth = 0+get_value (mDateTime, «MONTH»)
tDay = 0+get_value (mDateTime, «DAY»)
if (tMonth < 10)
tMonth = «0» & tMonth
end if
if (tDay < 10)
tDay = «0» & tDay
end if
result = tYear & tMonth & tDay
end func
func format_last_candle_time (mDateTime, interval, hour_shift)
result=0
tHour=0+get_value (mDateTime, «HOUR») + hour_shift
tMin=floor ((0 + get_value (mDateTime, «MIN»)) / interval) * interval
if (tHour < 10)
tHour = «0» & tHour
end if
if (tMin fast)
output=set_value (output,"trend_line","Down" )
SET_ROW_COLOR_EX (outputline,"RGB (255,0,0)", «RGB (255,0,0)», «DEFAULT_COLOR», «DEFAULT_COLOR»)
end if
if (slowprevslow)
output=set_value (output,"trend_line","Sell" )
label_params=create_map ()
label_params=set_value (label_params,"TEXT", «Sell»)
label_params=set_value (label_params,"ALIGNMENT", «LEFT»)
label_params=set_value (label_params,"YVALUE", fast)
label_params=set_value (label_params,"DATE", candle_data)
label_params=set_value (label_params,"TIME", candle_time)
label_params=set_value (label_params,"R", 255)
label_params=set_value (label_params,"G", 0)
label_params=set_value (label_params,"B", 0)
label_params=set_value (label_params,"TRANSPARENCY", 10)
label_params=set_value (label_params,"FONT_FACE_NAME", «Tahoma»)
label_params=set_value (label_params,"FONT_HEIGHT", 12)
label_params=set_value (label_params,"HINT", «Продавай!!!»)
id=ADD_LABEL («mov», label_params)
end if
if (slow=fast) and (prevfast<prevslow)
output=set_value (output,"trend_line","Buy" )
label_params=create_map ()
label_params=set_value (label_params,"TEXT", «Buy»)
label_params=set_value (label_params,"ALIGNMENT", «LEFT»)
label_params=set_value (label_params,"YVALUE", fast)
label_params=set_value (label_params,"DATE", candle_data)
label_params=set_value (label_params,"TIME", candle_time)
label_params=set_value (label_params,"R", 255)
label_params=set_value (label_params,"G", 0)
label_params=set_value (label_params,"B", 0)
label_params=set_value (label_params,"TRANSPARENCY", 10)
label_params=set_value (label_params,"FONT_FACE_NAME", «Tahoma»)
label_params=set_value (label_params,"FONT_HEIGHT", 12)
label_params=set_value (label_params,"HINT", «Покупай!!!»)
id=ADD_LABEL («mov», label_params)
end if
ADD_ITEM (outputline,output)
outputline=outputline+1
END_PROGRAM
PARAMETER Date;
PARAMETER_TITLE Дата;
PARAMETER_DESCRIPTION Last msg;
PARAMETER_TYPE STRING (12);
END
PARAMETER slow;
PARAMETER_TITLE MOV10;
PARAMETER_DESCRIPTION Last msg;
PARAMETER_TYPE NUMERIC (10,5);
END
PARAMETER trend_line;
PARAMETER_TITLE Trend;
PARAMETER_DESCRIPTION Trend;
PARAMETER_TYPE STRING (1024);
END
PARAMETER fast;
PARAMETER_TITLE MOV2;
PARAMETER_DESCRIPTION Last msg;
PARAMETER_TYPE NUMERIC (10,5);
END
END_PORTFOLIO_EX
Func MovAv (Tag,Date,Time)
result=0
slice = Get_Candle_Ex (Tag, Date, Time)
LineCount = Get_Value (slice,"COUNT")
time = Get_Value (slice,"TIME")
lines = Get_Value (slice,"LINES")
FOR lineID FROM 0 TO LineCount-1
line = Get_Collection_Item (lines, lineID)
close = Get_Value (line,"CLOSE")
result=0+apply_scale (close,4)
end for
end Func
outputline=1
interval=5
hourshift=-3
I=500
output=CREATE_MAP ()
mDatetime=GET_DATETIME ()
candle_data=format_date (mDateTime)
candle_time=format_last_candle_time (mDateTime,interval,hourshift)
times=candle_time-500
slow=MovAv («mov10»,candle_data, candle_time)
fast=MovAv («mov»,candle_data, candle_time)
prevslow=MovAv («mov10»,candle_data, candle_time-I)
prevfast=MovAv («mov»,candle_data, candle_time-I)
output=SET_VALUE (output,"Date",candle_time)
output=SET_VALUE (output,"slow",slow)
output=SET_VALUE (output,"fast",fast)
if (slow> fast)
output=set_value (output,"trend_line","Down" )
SET_ROW_COLOR_EX (outputline,"RGB (255,0,0)", «RGB (255,0,0)», «DEFAULT_COLOR», «DEFAULT_COLOR»)
end if
if (slowprevslow)
output=set_value (output,"trend_line","Sell" )
label_params=create_map ()
label_params=set_value (label_params,"TEXT", «Sell»)
label_params=set_value (label_params,"ALIGNMENT", «LEFT»)
label_params=set_value (label_params,"YVALUE", fast)
label_params=set_value (label_params,"DATE", candle_data)
label_params=set_value (label_params,"TIME", candle_time)
label_params=set_value (label_params,"R", 255)
label_params=set_value (label_params,"G", 0)
label_params=set_value (label_params,"B", 0)
label_params=set_value (label_params,"TRANSPARENCY", 10)
label_params=set_value (label_params,"FONT_FACE_NAME", «Tahoma»)
label_params=set_value (label_params,"FONT_HEIGHT", 12)
label_params=set_value (label_params,"HINT", «Продавай!!!»)
id=ADD_LABEL («mov», label_params)
end if
if (slow=fast) and (prevfast<prevslow)
output=set_value (output,"trend_line","Buy" )
label_params=create_map ()
label_params=set_value (label_params,"TEXT", «Buy»)
label_params=set_value (label_params,"ALIGNMENT", «LEFT»)
label_params=set_value (label_params,"YVALUE", fast)
label_params=set_value (label_params,"DATE", candle_data)
label_params=set_value (label_params,"TIME", candle_time)
label_params=set_value (label_params,"R", 255)
label_params=set_value (label_params,"G", 0)
label_params=set_value (label_params,"B", 0)
label_params=set_value (label_params,"TRANSPARENCY", 10)
label_params=set_value (label_params,"FONT_FACE_NAME", «Tahoma»)
label_params=set_value (label_params,"FONT_HEIGHT", 12)
label_params=set_value (label_params,"HINT", «Покупай!!!»)
id=ADD_LABEL («mov», label_params)
end if
ADD_ITEM (outputline,output)
outputline=outputline+1
END_PROGRAM
PARAMETER Date;
PARAMETER_TITLE Дата;
PARAMETER_DESCRIPTION Last msg;
PARAMETER_TYPE STRING (12);
END
PARAMETER slow;
PARAMETER_TITLE MOV10;
PARAMETER_DESCRIPTION Last msg;
PARAMETER_TYPE NUMERIC (10,5);
END
PARAMETER trend_line;
PARAMETER_TITLE Trend;
PARAMETER_DESCRIPTION Trend;
PARAMETER_TYPE STRING (1024);
END
PARAMETER fast;
PARAMETER_TITLE MOV2;
PARAMETER_DESCRIPTION Last msg;
PARAMETER_TYPE NUMERIC (10,5);
END
END_PORTFOLIO_EX
Валерий!
Необходимо описать подробней что делают функции, и как это использовать.
Выложил в раздел скачать.
Хотел заметить по поводу средневзвешенной цены покупки! В квике ошибка и ее получиь пока невозможно(. Я спрашивал на форуме, вот ветка:
quik.ru/user/forum/qpile/34726/35304/
вот так(
Евгений Reply:
апреля 16, 2009 at 16:54
По какой формуле рассчитывается средневзвешенная цена покупки?
Сергей Reply:
апреля 16, 2009 at 18:05
Насколько я понимаю, как (q1*p1+q2*p2+...+qn*pn)/(q1+q2+...qn),
где q — количество бумаг по определенной цене p. Плюс необходимо корректировать на комиссию.
Если стратегия исключительно внутридневная, то данные можно брать из таблицы сделок, но насколько я убедился на собственном опыте, лучше qpile не перегружать, иначе начинаются глюки, особенно если расчет будет по скальперскому роботу с кучей сделок... Хотя может быть все будет работать хорошо)
Евгений Reply:
апреля 16, 2009 at 19:27
При выборке данных из таблицы всех сделок QUIK для Qpile не фильтрует данные, а высыпает все в кучу, которые потом нужно фильтровать. Это как раз подсаживает робота. проще дождаться когда разработчики исправят ошибку. Хотя поизвращаться тоже можно
Григорию. Спасибо за Трал-бота! Попробовал Трал-бота на SBERP03 — заработал с первого раза, а вот на FEES не хочет выставлять заявку хотя отклонения превышают указанные иногда в 2-3-4 раза. При этом лог-файл записываются строчки без указания даты-времени в колонке INFO. А QUIK выдает сообщение что инструмент запрещен для шорта. Бумага не заблокированна. И никак не могу понять почему не работает. И отловить тоже пока не получилось. Буду рад если поможете. Учусь.
Евгений Reply:
июня 11, 2009 at 13:51
Передам!
Спасибо. Но робот который был здесь далеко не совершенен. Поэтому его да же убрали с сайта. Возможно мы выпустим коммерческую версию, в которой будут разные возможности, в том числе уведомления по эл. почте и прочее.