— == QUICk/QLUA: авто-перестановка лимитной покупки на +1 тик от лучшего бида ==
— -------------------------
— CONFIG: настроить под себя
— -------------------------
local CONFIG = {
CLASS_CODE = «TQBR», — класс инструмента (акции T+ обычно TQBR)
SEC_CODE = «GAZP», — тикер
ACCOUNT = «L01-00000F00»,-- торговый счет (trdaccid для T+)
CLIENT_CODE = "", — клиентский код (может быть пустым)
QUANTITY = 100, — лот/кол-во
BROKERREF = «autobid+1», — пометка брокеру (необязательно)
ALLOW_CROSS = false, — true чтобы разрешить пересечение спреда (мгновенное исполнение)
MIN_REPLACE_MS= 800, — не чаще чем раз в N мс (анти-флуд)
PRICE_ROUND = 6 — точность округления цены
}
— -------------------------
— Внутренние переменные
— -------------------------
local last_action_ms = 0
local current_order_num = nil — Биржевой номер активной заявки
local current_price = nil — Текущая цена активной заявки
local price_step = nil — Шаг цены инструмента
local best_bid, best_ask = nil, nil
local running = true
— -------------------------
— Утилиты
— -------------------------
local function now_ms()
return os.time() * 1000 + (getInfoParam(«LOCAL_TIME_MCS») ~= "" and math.floor(tonumber(getInfoParam(«LOCAL_TIME_MCS»))/1000)%1000 or 0)
end
local function to_num(x)
if x == nil then return nil end
local n = tonumber(tostring(x):gsub(",", "."))
return n
end
local function round_price(p)
if not p then return nil end
local scale = 10^CONFIG.PRICE_ROUND
return math.floor(p*scale + 0.5)/scale
end
local function fetch_price_step()
— В QUIK параметр шага цены: «SEC_PRICE_STEP»
local p = getParamEx(CONFIG.CLASS_CODE, CONFIG.SEC_CODE, «SEC_PRICE_STEP»)
if p and p.param_type ~= 0 and p.param_value ~= "" then
return to_num(p.param_value)
end
— запасной путь (иногда брокеры публикуют STEPPRICe/PRICESTEP)
local p2 = getParamEx(CONFIG.CLASS_CODE, CONFIG.SEC_CODE, «PRICESTEP»)
if p2 and p2.param_type ~= 0 and p2.param_value ~= "" then
return to_num(p2.param_value)
end
message(«Не удалось определить SEC_PRICE_STEP — проверьте настройки инструмента», 3)
return nil
end
local function read_l2_best()
local book = getQuoteLevel2(CONFIG.CLASS_CODE, CONFIG.SEC_CODE)
if not book then return nil, nil end
local bid = nil
if book.bid_count and book.bid_count > 0 then
bid = to_num(book.bid[1].price)
end
local ask = nil
if book.offer_count and book.offer_count > 0 then
ask = to_num(book.offer[1].price)
end
return bid, ask
end
local function desired_price()
if not best_bid or not price_step then return nil end
local p = best_bid + price_step
if not CONFIG.ALLOW_CROSS and best_ask and p >= best_ask then
— Чуть ниже оффера, чтобы не сделать рыночную покупку
if best_ask — price_step > 0 then
p = best_ask — price_step
else
— если шаг не позволяет опуститься — остаёмся на бест бид + шаг (может исполниться)
end
end
return round_price(p)
end
local function can_replace()
return (now_ms() — last_action_ms) >= CONFIG.MIN_REPLACE_MS
end
local function kill_current_order()
if not current_order_num then return end
local t = {
[«TRANS_ID»] = tostring( os.time()… «01» ),
[«ACTION»] = «KILL_ORDER»,
[«CLASSCODE»] = CONFIG.CLASS_CODE,
[«SECCODE»] = CONFIG.SEC_CODE,
[«ORDER_KEY»] = tostring(current_order_num)
}
sendTransaction(t)
last_action_ms = now_ms()
end
local function sync_order()
if not can_replace() then return end
local want = desired_price()
if not want then return end
if current_price and math.abs(current_price — want) < 1e-10 then
return — уже на нужной цене
end
— Убираем старую и ставим новую
if current_order_num then
kill_current_order()
end
place_order(want)
end
— -------------------------
— Callbacks
— -------------------------
function OnInit()
price_step = fetch_price_step()
best_bid, best_ask = read_l2_best()
message(string.format(«Автобид запущен: %s/%s, шаг=%.10f, cross=%s»,
CONFIG.CLASS_CODE, CONFIG.SEC_CODE, price_step or -1,
tostring(CONFIG.ALLOW_CROSS)), 1)
end
function OnQuote(class_code, sec_code)
if not running then return end
if class_code ~= CONFIG.CLASS_CODE or sec_code ~= CONFIG.SEC_CODE then return end
best_bid, best_ask = read_l2_best()
sync_order()
end
function OnOrder(order)
if not running then return end
if order.class_code ~= CONFIG.CLASS_CODE or order.sec_code ~= CONFIG.SEC_CODE then return end
if order.trans_id and order.flags then
— flags битовый; 0x1=покупка; 0x2=продажа; 0x4=активна и т.д.
— Отслеживаем размещение и изменение своей лимитки
if order.brokerref == CONFIG.BROKERREF and order.account == CONFIG.ACCOUNT then
— Сохраняем актуальную заявку
if bit and bit.band(order.flags, 0x4) ~= 0 then
current_order_num = order.order_num
current_price = to_num(order.price)
else
— Заявка снята/исполнена
if current_order_num == order.order_num then
current_order_num = nil
current_price = nil
end
end
end
end
end
function OnTrade(trade)
— Если частично/полностью исполнилась — в зависимости от вашей логики
— можно сразу выставлять заново оставшийся объём на +тик
end
function OnStop(sign)
running = false
— По желанию можно снять остаток:
— if current_order_num then kill_current_order() end
message(«Автобид остановлен», 1)
end
Тейк сам по себе конечно не переставляется так как это всего лишь условие порожденя лимитки или рыночной заявки
Здесь не написано что происходит при повышении цены
А происходит следущее — от последней максимальной цены сделки тейк следит куда идет цена, если вниз — то при достижении отступа срабатывает условие(как написано в справке)
А вот если цена идет вверх то тейк продолжает следить и постоянно увеличивает значение «последней максимальной цены» постоянно сдвигаясь вверх следом за ценой последней сделки, считайте что условие срабатывания тейка постоянно пересчитывается в сторону увеличения
И сработает тейк только когда тренд изменится и цена начнет снижаться
Не знаю что делает упомянутый скрипт но по описанию похоже что то же самое что и сам тейк, иными словами — ничего
Добровольная оферта от ПКО "СЗА" по выпуску облигаций серии БО-04
❗️Старт приема заявок — сегодня, 27 мая, с 10:00 до 18:00 по МСК.
📌 Основные условия по оферте: • Объем приобретения: до 20 000 бумаг
• Цена приобретения выпуска: 98,5% от номинала +...
⚡️ Эксперт Positive Technologies помог устранить уязвимость в процессорах AMD
Поиск недостатков безопасности в программах, сервисах и различных устройствах — задача, которой мы занимаемся уже много лет. Только за последние три года наши эксперты нашли более 850 уязвимостей...
🏛️ Софтлайн: импортозамещение ИТ в Республике Марий Эл
Друзья, мы уже делились отличной новостью — на конференции ЦИПР-2026 Софтлайн заключил более 20 новых соглашений о сотрудничестве! Сегодня подробнее расскажем об одном из них: 🤝 Софтлайн и...
Дата проведения заседания Собрания: 17 июня 2026 г
Повестка дня Собрания:
1. Об избрании членов Совета директоров Общества;
2. О назначении аудиторской организации (аудиторских организаций) О...
Почему крепкий рубль - фундамент новой индустриализации Эпоха покупок бус у американцев завершается, если кто не понял. Очень много статей пишут о девальвации рубля, что понятно, люди привыкли за свою...
📌 26.05.2026 состоялась выплата купонного дохода по облигациям СИМПЛСК1Р2 (ISIN RU000A10EPV4).
📌 Общий размер выплаченных доходов: 12 082 000 руб.
📌 Размер доходов, подлежащих выплате по одной обл...
tocka, три года сидел в бумагах, продал недавно. Тухлая история, московские чиновники сидят на деньгах ЗИЛа, крутят их и это может продолжаться сколько угодно долго.
Romul7, они показали их только на вечерке и только на 5 минут и только в одном выпуске — увидели единицы. Насчет хомяков — хомяки разве не по 1000 покупают и потом по 70 продают?
СД Совкомбанк рекомендовал дивиденды за 2025 год в размере 0,35 руб./акцию (ДД: 2,95%) СД Совкомбанк рекомендовал дивиденды за 2025 год в размере 0,35 руб./акцию (ДД: 2,95%)ГОСА — 30 июня отсечка — 13...
— == QUICk/QLUA: авто-перестановка лимитной покупки на +1 тик от лучшего бида ==
— -------------------------
— CONFIG: настроить под себя
— -------------------------
local CONFIG = {
CLASS_CODE = «TQBR», — класс инструмента (акции T+ обычно TQBR)
SEC_CODE = «GAZP», — тикер
ACCOUNT = «L01-00000F00»,-- торговый счет (trdaccid для T+)
CLIENT_CODE = "", — клиентский код (может быть пустым)
QUANTITY = 100, — лот/кол-во
BROKERREF = «autobid+1», — пометка брокеру (необязательно)
ALLOW_CROSS = false, — true чтобы разрешить пересечение спреда (мгновенное исполнение)
MIN_REPLACE_MS= 800, — не чаще чем раз в N мс (анти-флуд)
PRICE_ROUND = 6 — точность округления цены
}
— -------------------------
— Внутренние переменные
— -------------------------
local last_action_ms = 0
local current_order_num = nil — Биржевой номер активной заявки
local current_price = nil — Текущая цена активной заявки
local price_step = nil — Шаг цены инструмента
local best_bid, best_ask = nil, nil
local running = true
— -------------------------
— Утилиты
— -------------------------
local function now_ms()
return os.time() * 1000 + (getInfoParam(«LOCAL_TIME_MCS») ~= "" and math.floor(tonumber(getInfoParam(«LOCAL_TIME_MCS»))/1000)%1000 or 0)
end
local function to_num(x)
if x == nil then return nil end
local n = tonumber(tostring(x):gsub(",", "."))
return n
end
local function round_price(p)
if not p then return nil end
local scale = 10^CONFIG.PRICE_ROUND
return math.floor(p*scale + 0.5)/scale
end
local function fetch_price_step()
— В QUIK параметр шага цены: «SEC_PRICE_STEP»
local p = getParamEx(CONFIG.CLASS_CODE, CONFIG.SEC_CODE, «SEC_PRICE_STEP»)
if p and p.param_type ~= 0 and p.param_value ~= "" then
return to_num(p.param_value)
end
— запасной путь (иногда брокеры публикуют STEPPRICe/PRICESTEP)
local p2 = getParamEx(CONFIG.CLASS_CODE, CONFIG.SEC_CODE, «PRICESTEP»)
if p2 and p2.param_type ~= 0 and p2.param_value ~= "" then
return to_num(p2.param_value)
end
message(«Не удалось определить SEC_PRICE_STEP — проверьте настройки инструмента», 3)
return nil
end
local function read_l2_best()
local book = getQuoteLevel2(CONFIG.CLASS_CODE, CONFIG.SEC_CODE)
if not book then return nil, nil end
local bid = nil
if book.bid_count and book.bid_count > 0 then
bid = to_num(book.bid[1].price)
end
local ask = nil
if book.offer_count and book.offer_count > 0 then
ask = to_num(book.offer[1].price)
end
return bid, ask
end
local function desired_price()
if not best_bid or not price_step then return nil end
local p = best_bid + price_step
if not CONFIG.ALLOW_CROSS and best_ask and p >= best_ask then
— Чуть ниже оффера, чтобы не сделать рыночную покупку
if best_ask — price_step > 0 then
p = best_ask — price_step
else
— если шаг не позволяет опуститься — остаёмся на бест бид + шаг (может исполниться)
end
end
return round_price(p)
end
local function can_replace()
return (now_ms() — last_action_ms) >= CONFIG.MIN_REPLACE_MS
end
local function kill_current_order()
if not current_order_num then return end
local t = {
[«TRANS_ID»] = tostring( os.time()… «01» ),
[«ACTION»] = «KILL_ORDER»,
[«CLASSCODE»] = CONFIG.CLASS_CODE,
[«SECCODE»] = CONFIG.SEC_CODE,
[«ORDER_KEY»] = tostring(current_order_num)
}
sendTransaction(t)
last_action_ms = now_ms()
end
local function place_order(price)
local t = {
[«TRANS_ID»] = tostring( os.time()… «02» ),
[«ACTION»] = «NEW_ORDER»,
[«CLASSCODE»] = CONFIG.CLASS_CODE,
[«SECCODE»] = CONFIG.SEC_CODE,
[«ACCOUNT»] = CONFIG.ACCOUNT,
[«CLIENT_CODE»]= CONFIG.CLIENT_CODE,
[«OPERATION»] = «B», — Покупка
[«PRICE»] = string.format("%."..CONFIG.PRICE_ROUND..«f», price),
[«QUANTITY»] = tostring(CONFIG.QUANTITY),
[«TYPE»] = «L», — Лимитка
[«BROKERREF»] = CONFIG.BROKERREF
}
sendTransaction(t)
last_action_ms = now_ms()
end
local function sync_order()
if not can_replace() then return end
local want = desired_price()
if not want then return end
if current_price and math.abs(current_price — want) < 1e-10 then
return — уже на нужной цене
end
— Убираем старую и ставим новую
if current_order_num then
kill_current_order()
end
place_order(want)
end
— -------------------------
— Callbacks
— -------------------------
function OnInit()
price_step = fetch_price_step()
best_bid, best_ask = read_l2_best()
message(string.format(«Автобид запущен: %s/%s, шаг=%.10f, cross=%s»,
CONFIG.CLASS_CODE, CONFIG.SEC_CODE, price_step or -1,
tostring(CONFIG.ALLOW_CROSS)), 1)
end
function OnQuote(class_code, sec_code)
if not running then return end
if class_code ~= CONFIG.CLASS_CODE or sec_code ~= CONFIG.SEC_CODE then return end
best_bid, best_ask = read_l2_best()
sync_order()
end
function OnOrder(order)
if not running then return end
if order.class_code ~= CONFIG.CLASS_CODE or order.sec_code ~= CONFIG.SEC_CODE then return end
if order.trans_id and order.flags then
— flags битовый; 0x1=покупка; 0x2=продажа; 0x4=активна и т.д.
— Отслеживаем размещение и изменение своей лимитки
if order.brokerref == CONFIG.BROKERREF and order.account == CONFIG.ACCOUNT then
— Сохраняем актуальную заявку
if bit and bit.band(order.flags, 0x4) ~= 0 then
current_order_num = order.order_num
current_price = to_num(order.price)
else
— Заявка снята/исполнена
if current_order_num == order.order_num then
current_order_num = nil
current_price = nil
end
end
end
end
end
function OnTrade(trade)
— Если частично/полностью исполнилась — в зависимости от вашей логики
— можно сразу выставлять заново оставшийся объём на +тик
end
function OnStop(sign)
running = false
— По желанию можно снять остаток:
— if current_order_num then kill_current_order() end
message(«Автобид остановлен», 1)
end
Заявки тейк-профит именно так и работают, постоянно переставляясь все выше по тренду
Здесь не написано что происходит при повышении цены
А происходит следущее — от последней максимальной цены сделки тейк следит куда идет цена, если вниз — то при достижении отступа срабатывает условие(как написано в справке)
А вот если цена идет вверх то тейк продолжает следить и постоянно увеличивает значение «последней максимальной цены» постоянно сдвигаясь вверх следом за ценой последней сделки, считайте что условие срабатывания тейка постоянно пересчитывается в сторону увеличения
И сработает тейк только когда тренд изменится и цена начнет снижаться
Не знаю что делает упомянутый скрипт но по описанию похоже что то же самое что и сам тейк, иными словами — ничего