Главная Quikprofit twiiter Quikprofit Rss

Торговый робот. Шаг за шагом. Шаг 5.

Май 10, 2010 | 2 комментариев

Шаг 5. Начинаем торговать
В сегодняшнем уроке мы будем учить нашего робота отправлять заявки на покупку и продажу.

Как и в других уроках нашего цикла «Торговый робот. Шаг за шагом», мы вновь возвращаемся к первому уроку с тем, чтобы освежить память. На сей раз вопрос такой: какой тип заявок согласно техническому заданию требуется для открытия/закрытия позиции.

Не для кого не секрет классификация заявок: рыночные, лимитированные и стоп-заявки. Подробно об этом написано как в руководстве Quik, так и в любом другом учебнике по трейдингу.

Итак, смотрим техническое задание в первом уроке.

Тип заявки для входа в позицию. Для входа в позицию будем использовать заявку по текущей рыночной цене (рыночная заявка).

Тип заявки для выхода из позиции. Для выхода из позиции будем использовать рыночную заявку.

Следующим шагом было бы логично обратиться к справке Quik (Раздел 8. Алгоритмический язык QPILE). Так и сделаем. Для работы с заявками QPile предлагает одну встроенную функцию SEND_TRANSACTION. Использование данной функции сильно усложняет работу по созданию торгового робота. Для упрощения будем использовать разработанную нашими программистами функцию для отправки заявок fNewSimpleOrder

Применяя функцию fNewSimpleOrder процесс подачи заявки значительно упрощается. Давайте в этом убедимся. Но для начала следует прикрепить внешнюю функцию fNewSimpleOrder.qpl как это сделано в Шаг 3

Синтаксис функции достаточно прост.

fNewSimpleOrder(Account, ClientСode, Seccode, Price, Operation, Quantity)

  • Account - Счет Депо. Указывается в любой заявке в поле «Торговый счет».
  • ClientCode - Код клиента. Это ваш номер (код) у брокера. Указывается в любой заявке в поле «Код Клиента».
  • Seccode - Код бумаги. Найти можно в таблице «Поиск по инструменту», столбец «Код инструмента».
  • Price – цена выставляемой заявки. Для отправки рыночной заявки требуется указать нулевую цену.
  • Operation – направление сделки. Указывается латинскими буквами B (Buy/Покупка) или S (Sell/Продажа).
  • Quantity – количество лотов (контрактов).

Такие параметры как счет депо (Account)  и код клиента (ClientCode) в данной статье вымышленные. За случайное совпадение ответственности не несем. Все остальные параметры вытекают из технического задания описанного выше.

В блоке (подробно в Шаг 4)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
If ToolQuantity ==0
	If  (ЕМА_1 > ЕМА_2) and (АС_С > 0) and (АС_С > АС_С_1)
		Заявка на покупку
	End if
	If  (ЕМА_1 < ЕМА_2) and (АС_С < 0) and (АС_С < АС_С_1)
		Заявка на продажу
	End if
Else
	If  (ToolQuantity>0) and (АС_С < 0)
		Заявка на продажу
	End if
	If  (ToolQuantity<0) and (АС_С > 0)
		Заявка на покупку
	End if
End if

Текстовые строки заменяем на заявки.

Заявка на покупку:

1
quote_res = fNewSimpleOrder("Y62-000098B01", "56786", "SBER03", 0, "B", 1)

Заявка на продажу:

1
quote_res = fNewSimpleOrder("Y62-000098B01", "56786", "SBER03", 0, "S", 1)

Данные две строчки выставляют рыночные заявки на покупку/продажу акций АО Сбербанк в количестве 1 лот.

У данной функции есть еще одно несомненно привлекательное качество — она позволяет узнать результат обработки заявки, а в случае принятия и номер заявки. Предлагаю этим воспользоваться. А как именно, сейчас поясню.

В прошлом уроке наш робот научился вести журнал своих действий (Шаг 4). Но в журнале указывалось лишь сведения о наступлении того или иного события (сигнал на открытие/закрытия позиции). Сейчас же мы имеем возможность помимо уже указанных сведений вносить в журнал как минимум «результат отправки заявки» и «номер зарегистрированной заявки в системе».

Как это сделать, спросите вы?

«Просто!» —  отвечу я.

Итак, по порядку.

Результат отправки заявки имеет 2 возможных значения:

  • «1» – выполнено успешно,
  • «0» – произошла ошибка.

Тогда предлагаю сделать блок с условием:

  • если операция выполнена успешно (т.е. заявка принята торговой системой), тогда в журнал заносится запись «Заявка на покупку(продажу) принята. Номер заявки 00000″
  • если произошла ошибка, тогда в журнал заносится запись «Произошла ошибка. Заявка не принята»

На языке QPile выглядеть блок будет следующим образом:

1
2
3
4
5
6
7
quote_result = get_value (quote_res, "RESULT")+0 'Извлекаем результат 0/1. Указываем, что переменная числовая'
quote_number = get_value (quote_res, "ORDER_NUMBER") 'Извлекаем номер заявки в торговой системе'
if quote_result = 1 'если заявка принята, то'
	fDebugLog("Заявка на покупку(продажу) принята. Номер заявки" & quote_number) 'Пишем в журнал'
else
	fDebugLog("Произошла ошибка. Заявка не принята") 'Пишем в журнал'
end if

Складываем все ячейки вместе и получаем код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
PORTFOLIO_EX EMAvsAC;
DESCRIPTION Робот ЕМА и АС;
CLIENTS_LIST ALL_CLIENTS;
FIRMS_LIST ALL_FIRMS;
INCLUDE fGetMA.qpl, fGetAC.qpl, fDebugLog.qpl, fNewSimpleOrder.qpl;
 
PROGRAM
'Наш первый Портфель на основе ЕМА и АС
'Версия 0.1
DELETE_ALL_ITEMS () 'Благодаря этой функции из таблицы будут удалены старые значения.
'Короткая ЕМА (ЕМА_1) для последней закрытой свечи
dataMA9 = fGetMA("SBEREMA9", 2,  15)
EMA_1 = get_value (dataMA9,"MA_MAIN")+0
'Длинная ЕМА (ЕМА_2) для последней закрытой свечи
dataMA25 = fGetMA("SBEREMA25", 2,  15)
EMA_2 = get_value (dataMA25,"MA_MAIN")+0
'Текущее значение AC (АС_С) в незакрытой свече
dataAC1 = fGetAC("SBERAC", 1,  15)
AC_C = get_value (dataAC1,"AC_MAIN")+0
'Значение АС в последней закрытой свечи (АС_С_1)
dataAC2 = fGetAC("SBERAC", 2,  15)
AC_C_1 = get_value (dataAC2,"AC_MAIN")+0
ToolQuantity = DEPO_CURRENT_BALANCE("007", "MC0567300", "SBER03", "G01-0005D07") +0
If ToolQuantity == 0
	If  (ЕМА_1 > ЕМА_2) and (АС_С > 0) and (АС_С > АС_С_1)
		fDebugLog("Портфель пустой. Выполнено условие для ЛОНГа. Ставим заявку на покупку")
		quote_res = fNewSimpleOrder("Y62-000098B01", "56786", "SBER03", 0, "B", 1)
		quote_result = get_value (quote_res, "RESULT")+0
		quote_number = get_value (quote_res, "ORDER_NUMBER")
		if quote_result = 1 
			fDebugLog("Заявка на покупку принята. Номер заявки" & quote_number)
		else
		fDebugLog("Произошла ошибка. Заявка не принята")
		end if
	End if
	If  (ЕМА_1 < ЕМА_2) and (АС_С < 0) and (АС_С < АС_С_1)
		fDebugLog("Портфель пустой. Выполнено условие для ШОРТа. Ставим заявку на продажу")
		quote_res = fNewSimpleOrder("Y62-000098B01", "56786", "SBER03", 0, "S", 1)
		quote_result = get_value (quote_res, "RESULT")+0
		quote_number = get_value (quote_res, "ORDER_NUMBER")
		if quote_result = 1 
			fDebugLog("Заявка на продажу принята. Номер заявки" & quote_number)
		else
		fDebugLog("Произошла ошибка. Заявка не принята")
		end if
	End if
Else
	If (ToolQuantity>0) and (АС_С < 0)
		fDebugLog("Открыта позиция ЛОНГ. Выполнено условие для закрытия позиции. Ставим заявку на продажу")
		quote_res = fNewSimpleOrder("Y62-000098B01", "56786", "SBER03", 0, "S", 1)
		quote_result = get_value (quote_res, "RESULT")+0
		quote_number = get_value (quote_res, "ORDER_NUMBER")
		if quote_result = 1 
			fDebugLog("Заявка на продажу принята. Номер заявки" & quote_number)
		else
		fDebugLog("Произошла ошибка. Заявка не принята")
		end if
	End if
	If (ToolQuantity<0) and (АС_С > 0)
		fDebugLog("Открыта позиция ШОРТ. Выполнено условие для закрытия позиции. Ставим заявку на покупку")
		quote_res = fNewSimpleOrder("Y62-000098B01", "56786", "SBER03", 0, "B", 1)
		quote_result = get_value (quote_res, "RESULT")+0
		quote_number = get_value (quote_res, "ORDER_NUMBER")
		if quote_result = 1 
			fDebugLog("Заявка на покупку принята. Номер заявки" & quote_number)
		else
		fDebugLog("Произошла ошибка. Заявка не принята")
		end if
End if
End if
 
Massiv = CREATE_MAP() 'Создали массив с названием Massiv
Last_price = GET_VALUE(GET_PARAM_EX("EQBR","SBER03","last"),"param_value") 'Достаем из таблицы текущих параметров цену последней сделки по инструменту
Massiv = SET_VALUE(Massiv,"SecCode","СБЕРБАНК") 'Записали в массив наименование инструмента
Massiv = SET_VALUE(Massiv,"LastPrice", Last_price) 'Записали в массив цену последней сделки по инструменту
Massiv = SET_VALUE(Massiv,"EMA_1", EMA_1)
Massiv = SET_VALUE(Massiv,"EMA_2", EMA_2)
Massiv = SET_VALUE(Massiv,"AC_C", AC_C)
Massiv = SET_VALUE(Massiv,"AC_C_1", AC_C_1)
ADD_ITEM(0, Massiv)
END_PROGRAM
 
PARAMETER SecCode;
PARAMETER_TITLE Инструмент;
PARAMETER_DESCRIPTION Наименование инструмента;
PARAMETER_TYPE String(10);
END
PARAMETER LastPrice;
PARAMETER_TITLE Цена;
PARAMETER_DESCRIPTION Цена последней сделки по инструменту;
PARAMETER_TYPE Numeric(10,2);
END
PARAMETER EMA_1;
PARAMETER_TITLE ЕМА_1;
PARAMETER_DESCRIPTION MovingAverage с параметрами Exponential, 9;
PARAMETER_TYPE Numeric(10,6);
END
PARAMETER EMA_2;
PARAMETER_TITLE ЕМА_2;
PARAMETER_DESCRIPTION MovingAverage с параметрами Exponential, 25;
PARAMETER_TYPE Numeric(10,6);
END
PARAMETER AC_C;
PARAMETER_TITLE АС незакрытой свечи;
PARAMETER_DESCRIPTION АС незакрытой свечи;
PARAMETER_TYPE Numeric(10,6);
END
PARAMETER AC_C_1;
PARAMETER_TITLE АС закрытой свечи;
PARAMETER_DESCRIPTION АС закрытой свечи;
PARAMETER_TYPE Numeric(10,6);
END
 
END_PORTFOLIO_EX
Понравилось? Следите за обновлениями по RSS! Также можете следить за обновлениями в Twitter.
* * * ½   4 проголосовавших

Комментарии

2 ответов to “Торговый робот. Шаг за шагом. Шаг 5.”

  1. Константин
    Июнь 29th, 2010 @ 10:58

    Здравствуйте.Скажите пожалуйста где взять файл fDebugLog.qpl

  2. Ю.Р.
    Июль 8th, 2010 @ 21:34

    Файл fDebugLog.qpl входит в состав архива с текстом кода EMAvsAC_Lesson5. Ссылка на скачивание представлена выше.
    Также можно ознакомиться с работой данной функции и отдельно скачать файл на странице статьи «Что он там делает? Следим за работой робота» http://quikprofit.ru/chto-on-tam-delaet-sledim-za-rabotojj-robota/

Оставить комментарий





Поля помеченные (*) обязательны к заполнению

Страница 1 из 11
  • Меню

  • Облако тегов

  • Рубрики

  • Для пользователя