Контроль исполнения заявок в AmiSharp.
- Сообщений: 8
- Спасибо получено: 0
Начал реализовывать робота в AmiSharp. Наверное лучшая платформа для роботостроения из тех что видел.
Хотел спросить у вас, не могли бы вы прислать любой кусок кода с контролем заявки на выполнение(в соседней ветке вы предложили отличный алгоритм, через создание пользовательской таблицы).
С Уважением
Андреев В. В.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Ваш вопрос довольно объемный. Прямо с ходу 100%-но работающий код маленького объема (и универсальный) привести затрудняюсь, но проиллюстрировать попробую.
Вот шаблон процедурки, которая открывает позицию и записывает данные о сделке.
Order_Number = Send_Transaction(Classcode,SecCode,"Buy",Price,Size);
if (Order_Number != "0") // Ошибка выставления ордера
{ Height = 1+StrToNum(mutant.GetHeight(Result_Table));
SetCellName(Result_Table,"Сигнал", Height,"Long");
SetCellName(Result_Table,"Время", Height,Now());
SetCellName(Result_Table,"Бумага", Height,SecCode);
SetCellName(Result_Table,"Операция", Height,"Buy");
SetCellName(Result_Table,"Ордер", Height,Order_Number);
SetCellName(Result_Table,"Статус", Height,"Выставлен");
}На следующей итерации (этот тик скорее всего будет порожден нашей заявкой) смотрим табличку и видим, что в последней ее строке есть незакрытая сделка - все прописано, кроме цены сделки. Значит, нужно посмотреть, выполнена ли заявка. Соответственно, вынимаем из таблицы номер ордера и лезем в таблицу сделок. Фильтруем ее по номеру нашего ордера - получаем временную таблицу, в которой имеются только сделки, порожденные нашим ордером. Проверяем, , что сделка закрыта полностью (весь объем прошел) и вычисляем среднюю цену ( пример ), после чего завершаем заполнение строки - записываем среднюю цену по заявке в таблицу нашего робота.
Если теперь эту таблицу записать на диск при помощи SaveTable , то получим готовый csv файл для анализа истории сделок в Excel.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 8
- Спасибо получено: 0
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 8
- Спасибо получено: 0
CurrentPosition = StrToNum(StaticVarGetText("POSITION"));
if (CurrentPosition == 0)
{ if (LastValue(Buy))
{ Make_Order(ClassCode,SecCode,"Buy",Size);
StaticVarSetText("POSITION","" + CurrentPosition);
}
if (LastValue(Short))
{ Make_Order(ClassCode,SecCode,"Short",Size);
StaticVarSetText("POSITION","" + CurrentPosition);
}
}
else
{ if (LastValue(Sell))
{ Make_Order(ClassCode,SecCode,"Sell",CurrentPosition);
StaticVarSetText("POSITION","0");
}
if (LastValue(Cover))
{ Make_Order(ClassCode,SecCode,"Cover",CurrentPosition);
StaticVarSetText("POSITION","0");
}
}
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
{ Make_Order(ClassCode,SecCode,"Short",Size);
StaticVarSetText("POSITION","" + CurrentPosition);
}
Наверное, здесь нужно сохранить отрицательное значение в глобальной переменной, чтобы иметь возможность отличать длинную позицию от короткой
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 8
- Спасибо получено: 0
CurrentPosition = StrToNum(StaticVarGetText("POSITION"));
if (CurrentPosition == 0)
{
if (LastValue(Buy))
{
Make_Order(ClassCode,SecCode,"Buy",Size);
StaticVarSetText("POSITION","" + CurrentPosition);
}
if (LastValue(Short))
{
Make_Order(ClassCode,SecCode,"Short",Size);
StaticVarSetText("POSITION","" + (-1*CurrentPosition));
}
}
else
{
if (LastValue(Sell) AND CurrentPosition > 0)
{
Make_Order(ClassCode,SecCode,"Sell",CurrentPosition);
StaticVarSetText("POSITION","0");
}
if (LastValue(Cover) AND CurrentPosition < 0)
{
Make_Order(ClassCode,SecCode,"Cover",-CurrentPosition);
StaticVarSetText("POSITION","0");
}
}
В Cover я делаю -CurrentPosition, чтобы объем был положителен, это правильно?
P S Надо ли каментить:
amisharp.QuikConnect(QUIK_Path);
Если его оставляешь то постоянно в трее выдается ошибка, что квик уже подключен.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
По поводу QuikConnect. Этот метод нужно вызывать только тогда, когда связи нет. Если Вы вызываете его в момент, когда связь имеется, амишарп выдает ошибку - зачем подключаться, если и так все хорошо?
Поэтому можно или
1. установить связь единожды и больше не проверять (запомнив факт установления связи в глобальной переменной)
2. Или проверять наличие связи на каждой итерации. Если нет - тогда и вызывать QuikConnect.
Проверка наличия связи - относительно долгая процедура. поэтому на каждом тике ее выполнять не стоит. Лучше с какой-то периодичностью - раз в минуту или раз в таймфрейм графика - все индивидуально.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
- Сообщений: 8
- Спасибо получено: 0
1. Вошел по Short
2. Вышел по Cover и тут же вошел вверх по Buy
3. Вышел по Sell и тут же вошел по Short
4. Не вышел по Cover(здесь было только закрытие, сигнала buy не было).
Вот смотрю и пытаюсь понять причину. И думаю - правильно ли я передаю отрицательное число в глобальную переменную.
P S Еще вопрос:
amisharp = CreateStaticObject("AmiSharp.Mutant"); - должен исполнятся на каждой интерации или только единожды, вначале?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Для контроля сделок реализовал следующий алгоритм. если отправленный объем заявки на равен текущему лимиту из таблицы лимитов по бумагам, то снять все заявки.
if(TransactionSize != Qty)
strToKill = SetTransParameter("", "ACTION", "KILL_ALL_ORDERS");
strToKill = SetTransParameter(strToKill, "TRANS_ID", amisharp.Generate_TransID());
strToKill = SetTransParameter(strToKill,"CLASSCODE", ClassCode);
strToKill = SetTransParameter(strToKill,"SECCODE", Seccode);
strToKill = SetTransParameter(strToKill,"ACCOUNT", Account);
if (ClientCode != "") strToKill = SetTransParameter(strToKill,"CLIENT_CODE", ClientCode);
amisharp.QuikSendSyncTransaction(strToKill);
На это в лог файле возврат функции следующий:
23.06.2015 18:00:22 QuikSendSyncTransaction("ACTION=KILL_ALL_ORDERS;TRANS_ID=2507;CLASSCODE=QJSIM;ACCOUNT=NL0011100043;CLIENT_CODE=90680;") = 0,0,Обработка внешних транзакций: Отправка транзакций данного типа не поддерживается.,1,
Не могли бы Вы разъяснить в чем я не прав?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Проблема в типе транзакции: KILL_ALL_ORDERS.
Этот тип транзакции подерживается только при импорте транзакций из .tri файла. Во всех остальных вариантах (qpile,lua,API) этот тип транзакции не поддерживается.
Смотрите в таблицу заявок, выбирайте активные и снимайте в цикле по одной.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Скажите пожалуйста, какое значение присваивается полю "Результат транзакции" ( первая позиция в возвращаемой строке результата) в случае успешного выполнения операции QuikSendSyncTransaction (...) .
Если, к примеру, это значение "1", то какому из следующих трех результатов выполнения операции это соответствует: "Транзакция отправлена серверу", "Транзакция получена на сервер Quik от клиента", "Транзакция выполнена":
Именно такие формулировки результата приведены в Руководстве пользователя Quik, раздел Импорт транзакций / Формат .tro - файла с результатами обработки транзакций
Спасибо..
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
При отсылке транзакции терминал анализирует ее содержимое на правильность, отправляет транзакцию серверу. Сервер проверяет лимиты и все остальное и формирует ответ терминалу. На основе этого ответа вы получите статус исполнения вашей транзакции. Если все эти моменты исполнены успешно, терминал сообщит функции код успеха и функция также вам выдаст успех. Иначе не успех.
То есть вы получаете результат первичной обработки транзакции. Для заявки он может быть как "отправлено на биржу", " Отправлено на биржу по рынку и куплено", "установлен стоп " и так далее.
Если были ошибки, вы получите нулевой код в ответе и диагностику типа 'не прошли лимиты" или "эта сессия сейчас не идет"
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Большое спасибо за оперативный ответ. С кодом ошибки все понятно.
Скажите, с учетом Вашего большого опыта написания торговых роботов, Вам всегда было достаточно знать только кода ошибки для написания процедур контроля "принятия" Заявки системой (Сервером), или встречались алгоритмы, когда Вам было необходимо знать дополнительно и конкретное значение "код успеха" , возвращаемое при обработке данной Заявки?
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе.
