Привет, как в QUIK Lua сделать заявку Market-On-Open, чтобы получить покупку актива по цене открытия его основной сессии?
Сейчас подаю просто рыночную заявку на премаркете до начала основной американской сессии, есть проблема в том, что цена покупки сильно не совпадает с реальной ценой открытия в момент исполнения сделки на открытии сессии (иногда даже открывает по цене выше максимума дня, на что мне брокер отвечает, что «в данный момент на данный объем была такая цена»).

Всем привет. Может есть у кого нибудь скрипт уведомления при пересечении цены MA? Или может кто подскажет(поможет) как его написать?
есть программный код для выставления заявок под квик на lua по сигналу пересечения индикаторов?
Авто-репост. Читать в блоге >>>
Account = ""; -- счет клиента
ClientCode = ""; -- код клиента
FirmCode = ""; -- код фирмы
SecCode = ""; -- код инструмента
ClassCode = ""; -- класс инструмента
Tag = SecCode .. "_PRICE"; -- индикатор графика цены
EMA1 = SecCode .. "_EMA1"
EMA2 = SecCode .. "_EMA2"
Run = true; -- отвечает за работу скрипта
LastOpenBarIndex = 0;
FlagOrder = false; -- флаг наличия активной заявки
FlagStopOrder = false;
OrderNumber = 0; -- номер заявки
trans_id = os.time(); -- уникальный id транзакции
trans_number = 0; -- номер транзакции
trans_status = 0; -- статус транзакции
ClosePosition = true;
Count = 0;
Cycles = 60;
Rest = 1; -- остаток в заявке
Start = 65955; -- начало работы скрипта
Stop = 233000; -- конец работы скрипта
StopLossl = 350; -- размер стоп-лосса
StopLosss = 405; -- размер стоп-лосса
TakeProfit = 3.8/100
Step = 1; -- шаг цены
Slip = 0; -- проскальзывание цены
Unit = 10; -- количество лотов в заявке
-- Главная функция скрипта --
function main()
-- Основной цикл скрипта --
while Run do
if IsWindowClosed(t_id) then -- при закрытие окна торгового робота скрипт останавливается!!!
Run = false;
message("Stop trading robot!!!");
end;
if not_trade() then
file = io.open(getScriptPath() .. "/LastOpenBarIndex.txt", "r");
if file ~= nil then
LastOpenBarIndex = tonumber(file:read("*n"));
file:close();
end;
if LastOpenBarIndex == nil then LastOpenBarIndex = 0 end;
if FlagOrder then
done_order()
elseif FlagStopOrder then
stop_order()
elseif LastOpenBarIndex < getNumCandles(Tag) then
Predict = predict() -- получаем прогноз
Position = position() -- узнаем позицию по инструменту
if Predict > 0 and Position <= 0 then
if Position < 0 then
QtyBuy = math.abs(Position) + Unit;
elseif Position == 0 then
QtyBuy = Unit;
end;
buy(QtyBuy) -- покупаем
elseif Predict < 0 and Position >= 0 then
if Position > 0 then
QtySell = Position + Unit;
elseif Position == 0 then
QtySell = Unit;
end;
sell(QtySell) -- продаем
end;
LastOpenBarIndex = getNumCandles(Tag);
file = io.open(getScriptPath() .. "/LastOpenBarIndex.txt", "w");
if file ~= nil then
file:write(tostring(LastOpenBarIndex));
file:close();
end;
end;
-- вывод параметров скрипта в таблицу --
SetCell(t_id, 1, 1, tostring(getInfoParam("SERVERTIME")));
SetCell(t_id, 1, 2, SecCode);
SetCell(t_id, 1, 3, tostring(position()));
SetCell(t_id, 1, 4, tostring(round(tonumber(predict()), 10)));
SetCell(t_id, 1, 5, tostring(round(tonumber(getPortfolioInfo(FirmCode, ClientCode).total_limit_open_pos), 2)));
SetCell(t_id, 1, 6, tostring(round(tonumber(getPortfolioInfo(FirmCode, ClientCode).varmargin), 2)));
sleep(1000);
else
sleep(1000);
end;
end;
end;
function not_trade()
local Error = true;
if isConnected() == 1 then
local Time = 0;
SERVER_TIME = getInfoParam("SERVERTIME");
if string.len(SERVER_TIME) == 8 then
Time = tonumber(SERVER_TIME:sub (1,2) .. SERVER_TIME:sub (4,5) .. SERVER_TIME:sub (7,8));
else
Time = tonumber(SERVER_TIME:sub (1,1) .. SERVER_TIME:sub (3,4) .. SERVER_TIME:sub (6,7));
end;
if Time == nil then Time = 0 end;
if Time < Start then
Error = false;
SetCell(t_id, 1, 1, "ErrorTime");
for i = 2,6 do
SetCell(t_id, 1, i, "0");
end;
elseif Time > 135900 and Time < 140600 then
Error = false;
SetCell(t_id, 1, 1, "Clearing");
for i = 2,6 do
SetCell(t_id, 1, i, "0");
end;
elseif Time > 184400 and Time < 190600 then
Error = false;
SetCell(t_id, 1, 1, "Clearing");
for i = 2,6 do
SetCell(t_id, 1, i, "0");
end;
elseif Time > Stop then
Error = false;
SetCell(t_id, 1, 1, "ErrorTime");
for i = 2,6 do
SetCell(t_id, 1, i, "0");
end;
-- закрытие позиции и снятие стоп-заявки в конце торговой сессии --
--[[local Position = position();
if Position ~= 0 then
if ClosePosition then
if Position > 0 then
Slip = 0;
sell(Position);
elseif Position < 0 then
Slip = 0;
buy(math.abs(Position));
end;
FlagOrder = false;
ClosePosition = false;
end;
elseif Position == 0 then
stop_order()
ClosePosition = true;
end;]]
end;
else
Error = false;
SetCell(t_id, 1, 1, "ErrorConnection");
for i = 2,6 do
SetCell(t_id, 1, i, "0");
end;
end;
return Error;
end;
-- Функция покупки --
function buy(QtyBuy)
local PriceBuy = 0; -- цена по которой покупаем
while PriceBuy <= 0 do
PriceBuy = tonumber(getParamEx(ClassCode, SecCode, "offer").param_value) - Step * Slip -- получаем лучшую цену предложения
end;
message("Order to buy at the price: " .. PriceBuy .. ", qty: " .. QtyBuy);
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "NEW_ORDER",
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['OPERATION'] = "B",
['TYPE'] = "M",
['QUANTITY'] = tostring (math.floor(QtyBuy)),
['ACCOUNT'] = Account,
['PRICE'] = tostring(math.floor(PriceBuy)),
['CLIENT_CODE'] = ClientCode
}
trans_status = 0;
trans_number = 0;
sendTransaction(trans_params)
while trans_status ~= 3 do
sleep(20);
end;
OrderNumber = trans_number;
FlagOrder = true;
end;
-- Функция продажи --
function sell(QtySell)
local PriceSell = 0; -- цена по которой продаем
while PriceSell <= 0 do
PriceSell = tonumber(getParamEx(ClassCode, SecCode, "bid").param_value) - Step * Slip -- получаем лучшую цену спроса
end;
message("Order to sell at the price: " .. PriceSell .. ", in the quantity: " .. QtySell);
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "NEW_ORDER",
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['OPERATION'] = "S",
['TYPE'] = "M",
['QUANTITY'] = tostring (math.floor(QtySell)),
['ACCOUNT'] = Account,
['PRICE'] = tostring(math.floor(PriceSell)),
['CLIENT_CODE'] = ClientCode
}
trans_status = 0;
trans_number = 0;
sendTransaction(trans_params)
while trans_status ~= 3 do
sleep(20);
end;
OrderNumber = trans_number;
FlagOrder = true;
end;
-- Функция контроля исполнения активной заявки --
function done_order()
local QtyOrder = 0;
local PriceOrder = 0;
for i = 0, getNumberOf("orders") - 1 do
if getItem("orders", i).order_num == OrderNumber then
Rest = getItem("orders", i).balance;
while PriceOrder <= 0 do
PriceOrder = getItem("orders", i).price;
QtyOrder = getItem("orders", i).qty;
sleep(20);
end;
end;
end;
-- если заявка полностью исполнилась --
if Rest == 0 then
message(getInfoParam("SERVERTIME") .. " Order №" .. OrderNumber .. " fully executed, at the price without slipping: " .. PriceOrder .. " in quantity: " .. QtyOrder, 1)
FlagOrder = false;
FlagStopOrder = true;
Count = 0;
-- если заявка не исполнилась, снимаем отстаток --
elseif Count > Cycles then
kill_order(OrderNumber);
message(getInfoParam("SERVERTIME") .. " Order №" .. OrderNumber .. " canceled, rest: " .. Rest, 1)
Count = 0;
FlagOrder = false;
if position() ~= 0 then
FlagStopOrder = true;
end;
file = io.open(getScriptPath() .. "/LastOpenBarIndex.txt", "w");
file:write("");
file:close();
-- если заявка еще не исполнилась, но время на исполнение еще осталось --
elseif Rest > 0 then
Count = Count + 1;
end;
sleep(1000);
end;
-- Функция выставления stop_loss --
function stop_order()
local PriceStopOrder = 0;
local Position = position();
-- снимаем старую стоп-заявку --
for i = 0, getNumberOf("stop_orders") - 1 do
if bit.test(getItem("stop_orders", i).flags, 0) == true then
kill_stop_order(getItem("stop_orders", i).order_num);
end;
end;
-- определяем цену по которой заключена сделка --
if Position ~= 0 then
for i = 0, getNumberOf("trades") - 1 do
if getItem("trades", i).order_num == OrderNumber then
while PriceStopOrder <= 0 do
PriceStopOrder = getItem("trades", i).price;
sleep(20);
end;
end;
end;
end;
if PriceStopOrder > 0 and Position ~= 0 then
if Position > 0 then
StopPrice = PriceStopOrder - StopLossl;
PriceX = PriceStopOrder - Step * 200;
QtyStopOrder = Position;
Operation = "S";
elseif Position < 0 then
StopPrice = PriceStopOrder + Step * StopLosss;
PriceX = PriceStopOrder + Step * 200;
QtyStopOrder = math.abs(Position);
Operation = "B";
end;
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "NEW_STOP_ORDER",
['STOP_ORDER_KIND'] = "SIMPLE_STOP_ORDER",
['EXPIRY_DATE'] = "TODAY",
['STOPPRICE'] = tostring(math.floor(StopPrice)),
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['PRICE'] = tostring(math.floor(PriceX)),
['OPERATION'] = Operation,
['TYPE'] = "L",
['QUANTITY'] = tostring(math.floor(QtyStopOrder)),
['ACCOUNT'] = Account,
['CLIENT_CODE'] = ClientCode
}
trans_status = 0; -- сбрасываем прошлый статус транзакции
sendTransaction(trans_params); -- отправляем транзакцию
while trans_status ~= 3 do
sleep(20);
end;
if Position > 0 then
StopPrice = PriceStopOrder - StopLossl;
PriceX = PriceStopOrder - Step * 200;
QtyStopOrder = Position;
Operation = "S";
elseif Position < 0 then
StopPrice = PriceStopOrder + Step * StopLosss;
PriceX = PriceStopOrder + Step * 200;
QtyStopOrder = math.abs(Position);
Operation = "B";
end;
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "NEW_STOP_ORDER",
['STOP_ORDER_KIND'] = "SIMPLE_STOP_ORDER",
['EXPIRY_DATE'] = "TODAY",
['STOPPRICE'] = tostring(math.floor(StopPrice)),
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['PRICE'] = tostring(math.floor(PriceX)),
['OPERATION'] = Operation,
['TYPE'] = "L",
['QUANTITY'] = tostring(math.floor(QtyStopOrder)),
['ACCOUNT'] = Account,
['CLIENT_CODE'] = ClientCode
}
trans_status = 0; -- сбрасываем прошлый статус транзакции
sendTransaction(trans_params); -- отправляем транзакцию
while trans_status ~= 3 do
sleep(20);
end;
--[[]]
if Position > 0 then
StopPrice = PriceStopOrder *(TakeProfit+1) ;
PriceX = PriceStopOrder - Step * 200;
QtyStopOrder = Position;
Operation = "S";
elseif Position < 0 then
StopPrice = PriceStopOrder *(1-TakeProfit);
PriceX = PriceStopOrder + Step * 200;
QtyStopOrder = math.abs(Position);
Operation = "B";
end;
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "NEW_STOP_ORDER",
['STOP_ORDER_KIND'] = "SIMPLE_STOP_ORDER",
['EXPIRY_DATE'] = "TODAY",
['STOPPRICE'] = tostring(math.floor(StopPrice)),
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['PRICE'] = tostring(math.floor(PriceX)),
['OPERATION'] = Operation,
['TYPE'] = "L",
['QUANTITY'] = tostring(math.floor(QtyStopOrder)),
['ACCOUNT'] = Account,
['CLIENT_CODE'] = ClientCode
}
trans_status = 0; -- сбрасываем прошлый статус транзакции
sendTransaction(trans_params); -- отправляем транзакцию
while trans_status ~= 3 do
sleep(20);
end;
FlagStopOrder = false;
end;
end;
-- Функция снятия заявки --
function kill_order(Number)
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "KILL_ORDER",
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['ACCOUNT'] = Account,
['ORDER_KEY'] = tostring(Number)
}
sendTransaction(trans_params);
end;
-- Функция снятия стоп-заявки --
function kill_stop_order(Number)
trans_id = trans_id + 1;
local trans_params = {
['TRANS_ID'] = tostring(trans_id),
['ACTION'] = "KILL_STOP_ORDER",
['CLASSCODE'] = ClassCode,
['SECCODE'] = SecCode,
['ACCOUNT'] = Account,
['STOP_ORDER_KEY'] = tostring(Number)
}
sendTransaction(trans_params);
end;
-- Функция прогнозирования движения цены инструмента --
function predict()
local t, n, l = nil,nil,nil
while t == nil do
x1 = getNumCandles('Tag')
t, n, l = getCandlesByIndex('Tag', 0, 0, x1)
ma_1 = t[0].close
for i=1, x1-1 do
local C = t[i].close
local C1 = t[i-1].close
local C2 = t[i-2].close
local C3 = t[i-3].close
local C4 = t[i-4].close
local C5 = t[i-5].close
local C6 = t[i-6].close
local C7 = t[i-7].close
local C8 = t[i-8].close
local C9 = t[i-9].close
ma_2 = (C1+C2+C3+C4+C5+C6+C7+C8+C9+C)/10
ma_1 = ma_2
end
--
sleep(10)
end;
local ema2 = ma_1;
local ema1 = t[x1].close
local result
if ema1 > ema2 then
result = 1;
elseif ema1 < ema2 then
result = -1
end;
return result;
end;
-- Функция определния позиции по инструменту --
function position()
local res = 0;
for i = 0, getNumberOf("futures_client_holding") - 1 do
if getItem("futures_client_holding", i).sec_code == SecCode then
res = tonumber(getItem("futures_client_holding", i).totalnet);
end;
end;
return res;
end;
-- Функция обратного вызова запускается первой и создает таблицу торгового робота --
function OnInit()
message("Start trading robot!");
t_id = AllocTable(); -- создаем таблицу
AddColumn (t_id,1,"Time", true, QTABLE_TIME_TYPE, 15);
AddColumn (t_id,2,"Sec_Code", true, QTABLE_STRING_TYPE, 10);
AddColumn (t_id,3,"Position", true, QTABLE_STRING_TYPE, 10);
AddColumn (t_id,4,"Predict", true, QTABLE_STRING_TYPE, 15);
AddColumn (t_id,5,"Balance", true, QTABLE_STRING_TYPE, 10);
AddColumn (t_id,6,"Margin", true, QTABLE_STRING_TYPE, 10);
CreateWindow(t_id); -- создаем окно таблицы
SetWindowCaption(t_id, "Trading robot");
InsertRow(t_id, 1);
end;
-- Функция обратного вызова для получения результата отправки транзакции --
function OnTransReply(trans_reply)
if trans_reply.trans_id == trans_id then
trans_status = trans_reply.status;
trans_number = trans_reply.order_num;
end;
end;
-- Функция обратного вызова остановки скрипта --
function OnStop()
Run = false;
DestroyTable(t_id);
end;
-- Функция округления чисел --
function round(x, n)
n = math.pow(10, n or 0)
x = x * n
if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end;
return x / n
end;
Буду благодарен за помощь.Ура, наконец демо-версия готова!
Для тех, кто пропустил:
— https://smart-lab.ru/blog/697641.php немного картинок
— https://smart-lab.ru/blog/700079.php видео работы скрипта
Итак, еще раз, что такое SmartMap? Это срез стакана, который остается на графике в виде меток, что позволяет нам видеть когда и где были крупные скопления, как они отрабатывались ценой, и где они есть сейчас. Дополнительно отображается общая ситуация по стакану в виде совокупного количества бидов и асков.
Достаточно популярная вещь у иностранцев, присутствует в большинстве импортных терминалов под названиями BookMap/HeatMap. Однако везде имеется мощный недостаток — при изменении ТФ или любого параметра, сформированный на графике рисунок «следов» исчезает. Почему? Потому что история стакана не сохраняется. Наша разработка лишена этого минуса. Меняете ли вы тайм-фрейм, какую-то настройку отображения скрипта — неважно, метки на графике остаются. Скрипт собирает историю с момента включения Квика. Все что от вас требуется — открытый стакан по инструменту.

for i = 0.1, 0.3, 0.1 do
message(tostring(i))
endРезультат:
Цикл:
for i = 0.1, 0.5, 0.1 do
message(tostring(i))
endРезультат: