Врач-бондиатОр
Врач-бондиатОр личный блог
07 июля 2020, 20:29

Вопрос 2 по Lua

Всем привет!

Продолжаю изучать волшебный мир Луа в волшебном мире Квика и добрался до размещения скриптом заявок.
На текущий момент есть такой скрипт (в общем виде).

local SecCode = «LKU0»
local Quantity=1

function main()

while stopped == false do


local Quotes = getQuoteLevel2(«SPBFUT», SecCode)
local Offer_Price = tonumber(Quotes.offer[1].price)
local Offer_Vol = tonumber(Quotes.offer[1].quantity)

--отправка формы заявки
local LimitOrderBuy = { ххххх}

--условие входа в лонг

if Offer_Vol>10 then
message(Order)
local Order = sendTransaction(LimitOrderBuy)
end

sleep (200)
end

Смысл его такой: если количество лукойла в первой строке стакана больше 10, то покупается 1 бумага и работа скрипта завершается.
Так как скрипт срабатывает при определенном условии, то для перезапуска используется while stopped == false do и sleep (200).
Прикол в том, что при наступлении условия, скрипт начинает бомбить заявки по 1 шт  пока не кончаются деньги (виртуальные).

Вопрос: какой размыкатель цикла можно тут использовать, чтобы после покупки 1 бумаги работа скрипта завершилась?

На ресурсах есть getItem, битовые флаги и пр., но изложено это как-то непонятно.
Помогите плиз..)
ЗЫ: обещаю поставить лайк хорошим ответам )


25 Комментариев
  • Свой Мужик
    07 июля 2020, 20:43
    exit есть в луа? )
  • Свой Мужик
    07 июля 2020, 20:44
    ну или обычно конструкция работает так
    while (stopped == false) and (buyed==false)

    не знаю по правилам луа нужны там скобки или нет?
    а при покупке ставишь buyed=true

    if Offer_Vol>10 then
    buyed=true
    message(Order)
    local Order = sendTransaction(LimitOrderBuy)
    end

    p.s. на луа ничего ни разу не писал )))
  • kachanov
    07 июля 2020, 20:51
    то покупается 1 бумага и работа скрипта завершается.

    по приведенному тексту не видно, чтобы работа завершалась.
    Возможно, в теле условия имеет смысл написать типа
    stopped = true
      • kachanov
        08 июля 2020, 21:16
        Врач-бондиатОр, возможно. Покажите полный текст — смогу сказать точней почему.
        Например, я не вижу как и где Вы присвоили первое значение переменной stopped.
        Если не присвоили нигде, то будет работать, так как по умолчанию она будет nil, который по умолчанию в логических конструкциях определяется как false.
        Допускаю, что Вы в условии написали local stopped = true (просто судя по количеству local по тексту). Тоже не будет работать, если требуется могу пояснить почему.
        Общий принцип Вам уже изложили и он работает.
        Использовать return тоже вариант, но, рано или поздно это решение исчерпает себя.
  • Ask
    07 июля 2020, 21:07
    Вначале проги поставь is_run=true, а после выполнения покупки вставь is_run=false
    • Ask
      07 июля 2020, 21:09
      Ask, А покупку вставь в конструкцию  while is_run do
        • Ask
          07 июля 2020, 21:41
          Врач-бондиатОр, 
          Надо в самом начале программы поставить is_run=false
          Потом все что написано выше в

          function main()
          while is_run do
          ...
            покупка
            is_run=false
          ...

          end
          end

  • Vitaliy
    07 июля 2020, 21:40
    Вам нужен счетчик позиций или проверка прошла ли транзакция (купилась ли бумага). В первом случае проверяете если в портфеле есть один контракт, то далее не покупать. Во втором случае просто флаг фалс или тру на успешную транзакцию. Так же можно отслеживать и считать позицию в функции OnTrade
  • Vitaliy
    07 июля 2020, 21:42

    function OnTrade(trd)

    if trd[«account»] and trd[«account»] == account and trd[«trade_num»] > untrade and trd[«sec_code»] == sec then
    if bit.band(tonumber(trd[«flags»]), 4) > 0 then — bit.band(tonumber(trd[«flags»]), 4) > 0 флаг 4 больше нуля — продажа
    Position = Position — tonumber(trd[«qty»]) — продажа
    else
    Position = Position + tonumber(trd[«qty»]) — покупка
    end
    if Position ~= 0 then




    elseif Position == 0 then




    end

    untrade = trd[«trade_num»] 
    end

    end

  • tashik
    07 июля 2020, 21:54
    В глобальной области в одной переменной храните плановое кол-во лотов, во второй — подтвержденное набранное. Значение во второй переменной обновляете по мере исполнения заявок. Как только плановое кол-во лотов совпало с подтвержденным набранным, обнуляете плановое. В цикле выставления заявки прописываете условие о том, что цикл должен выполняться, если плановое кол-во лотов > 0 и > набранного. Как-то так.
  • PSH
    07 июля 2020, 23:56
    return — выход из функции
    break — выход из цикла

    То есть, по логике «покупается бумага и работа скрипта завершается» необходимо

    if Offer_Vol>10 then
    message(Order)
    local Order = sendTransaction(LimitOrderBuy)
    return
    end
  • PSH
    08 июля 2020, 00:00
    Но вообще, конечно, кровь из глаз такие скрипты :)
      • PSH
        08 июля 2020, 21:14
        Врач-бондиатОр, Москва не сразу строилась, я без претензий, не подумайте, это мой внутренний перфекционист лютует :)
  • PSH
    08 июля 2020, 21:23
    Что тут особенно зубодробительно:
    while stopped == false

    Сравнение булевой переменной с булевым значением для того только, чтобы получить булево значение, абсолютно избыточно. К тому же, переменная stopped вообще нигде не инициализируется, то есть равно null

    Работать будет и

    while not stopped

    но читать удобнее второе.

    Более того, раз нам нужно впасть в бесконечный цикл, вполне достаточно будет

    while true

    Тут вообще никаких переменных нет и сразу видно, что это бесконечный цикл
  • PSH
    08 июля 2020, 21:26
    Вообще, использование бесконечных циклов — это плохая практика. Функция должна что-то сделать и отвалиться, а не зависать на неопределенный срок
  • Viacheslav Merten
    14 июля 2020, 19:17

    function OnInit()

    is_run = true

    end

    function main()

    CurrentPos() — проверка начального остатка

    local StarttNetPos = TotalNetPos — запоминание остатка

    while is_run do

    — ваше условие выставление ордера

    CurrentPos() — проверка остатка по бумажке

    if TotalNetPos ~= StarttNetPos then is_run = false end — если изменился, то сделка исполнена — ОСТАНОВКА СКРИПТА

    end

    end

    function CurrentPos()

    for i = 0, getNumberOf(«FUTURES_CLIENT_HOLDING») — 1 do

    if getItem(«FUTURES_CLIENT_HOLDING»,i).sec_code == p_SECCODE and getItem(«FUTURES_CLIENT_HOLDING»,i).totalnet ~= 0 then

    TotalNetPos = getItem(«FUTURES_CLIENT_HOLDING»,i).totalnet

    end

    end

    end

    Вот так будет работать

  • Viacheslav Merten
    14 июля 2020, 19:19
     Только единственное вместо этого FUTURES_CLIENT_HOLDING надо посмотреть как обращаться к таблице с остатками по акциям
  • Viacheslav Merten
    14 июля 2020, 19:29
     

    function OnInit()

    SecCode = «LKU0»
    Quantity=1

    is_run = true

    end

    function main()

    CurrentPos() — проверка начального остатка

    local StarttNetPos = TotalNetPos — запоминание остатка

    while is_run do

    local Quotes = getQuoteLevel2(«SPBFUT», SecCode)
    local Offer_Price = tonumber(Quotes.offer[1].price)
    local Offer_Vol = tonumber(Quotes.offer[1].quantity)

    --отправка формы заявки
    local LimitOrderBuy = {xxx}

    --условие входа в лонг

    if Offer_Vol>10 then
    message(Order)
    local Order = sendTransaction(LimitOrderBuy)
    end

    sleep (200)

    CurrentPos() — проверка остатка по бумажке

    if TotalNetPos ~= StarttNetPos then is_run = false end — если изменился, то сделка исполнена — ОСТАНОВКА СКРИПТА

    end

    end

    function CurrentPos()

    for i = 0, getNumberOf(«ACCOUNT_BALANCE») — 1 do

    if getItem(«ACCOUNT_BALANCE»,i).sec_code == SecCode and getItem(«ACCOUNT_BALANCE»,i).currentpos ~= 0 then

    TotalNetPos = getItem(«ACCOUNT_BALANCE»,i).currentpos

    else

    TotalNetPos = 0

    end

    end

    end

    Вот так будет точнее

Активные форумы
Что сейчас обсуждают

Старый дизайн
Старый
дизайн