Блог им. Bondiator

Вопрос по Луа 3 - работа циклов


Зарегистрировался для развития на форуме Арки и в разделе по программированию на Луа нашел код (https://forum.quik.ru/forum10/topic5664/)
Смысл в том, что автор хочет продавать актив поштучно пока в портфеле не останется какое-то количество бумаг.
На мой взгляд полезная вещь.
Когда я его попробовал на демо квике, то начались бесконечные продажи (как и у автора).
Судя по записям, проблема не решена.
Может кто подскажет как решить вопрос?

<code class="rainbow" data-language="lua">   while stopped == false do

      Quotes_1 = getQuoteLevel2("SPBFUT", "SRU0")

      Bid_Count_1 = tonumber(Quotes_1.bid_count)

      if Bid_Count_1>1 then
         aa= tonumber(Quotes_1.bid[Bid_Count_1].quantity)
         SetCell(Table, 1, 1, tostring(aa))
      end

      local asset = getFuturesHolding("SPBFUT", "SPBFUT****","SRU0",0).totalnet

      repeat

            if aa>1 and asset>0 then

               local ID_B_Order=10
               local OrderSell = {
                     ["ACTION"]="NEW_ORDER",
                     ["ACCOUNT"]= "SPBFUT****",
                            ["OPERATION"] = "S",
                     ["CLASSCODE"]="SPBFUT",
                            ["SECCODE"] = "SRU0",
                            ["PRICE"] = "0",
                     ["QUANTITY"] = tostring(1),
                     ["TRANS_ID"] = tostring(ID_B_Order),
                     ["TYPE"] = "M",
                     }
               local Err_Order = sendTransaction(OrderSell)
               message(Err_Order)
            end

            asset=asset-1

            sleep(1000)

      until asset==5<br />end</code>
Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
  • обсудить на форуме:
  • Quik Lua
839 | ★2
16 комментариев
там же на форуме уже разжевали почему так. Зациклился while, которого у вас нет в вашем примере
avatar
Андрей К, видел. Вопрос как его расциклить с минимумом текста
Врач-бондиатОр, в вычислении asset учитывать ещё и открытые заявки по нему, которые наставились в предыдущих итерациях цикла
avatar
Андрей К, есть в примере, притаился сверху ))) только end для него нема
avatar
kachanov, это где вы увидали? End я могу добавить
Врач-бондиатОр, первая строка
<code class="rainbow" data-language="lua">   while stopped == false do
начало цикла 
while stopped == false do

P.S. только обычно такую конструкцию не используют
гораздо понятней while is_run do  end

avatar
Врач-бондиатОр, о, end тоже не сразу разглядел )) он есть!
в данном коде достаточно поставить после цикла repeat остановку while

типа
 stopped = true (или любое число или символ)
т.е. последняя строка примет вид
  until asset==5   stopped = true  end</code>
останется 5 бумаг, если все транзакции сработают. Если нужен контроль за их исполнением, то написали ниже как это делать
avatar

Алгоритм примерно такой:

1. Отправляем заявку на продажу. Скрипт запоминает trans_id этой заявки.

2. Через колбек OnOrder получаем информацию о всех заявках. Смотрим, когда у заявки с запомненным trans_id статус поменяется на «исполнена».

3. Как только заявка с запомненным trans_id исполнена, отправляем новую заявку

 
avatar
Chalyj7, то есть, если нужно продать 7 бумаг, то нужно отследить 7 заявок на продажу?
Врач-бондиатОр, да. Не имеет значения сколько заявок. Надо ждать исполнения отправленной заявки и только потом отправлять следующую.
avatar
Chalyj7, я могу это представить если заявки две (их можно в коде зафиксировать). А если количество задается переменной, то как быть?

Врач-бондиатОр, смотрите, тут уже писали, собираю все в кучу.

у Вас в коде

Quotes_1 = getQuoteLevel2(«SPBFUT», «SRU0»)

Bid_Count_1 = tonumber(Quotes_1.bid_count)

if Bid_Count_1>1 then
aa= tonumber(Quotes_1.bid[Bid_Count_1].quantity)
SetCell(Table, 1, 1, tostring(aa))
end

запрашиваете стакан и первую цену бида (но почему то только один раз)

local asset = getFuturesHolding(«SPBFUT», «SPBFUT****»,«SRU0»,0).totalnet

снова один раз запрашиваете количество бумаг

дальше 

repeat — until — он заходит в цикл в любом случае один раз… не понятно, почему именно этот вид цикла выбран… ну ладно...

что надо сделать:

1. завести еще одну переменную, в ней хранить номер (trans_id) отправляемой заявки. В Вашем коде каждой заявке Вы присваиваете один и тот же номер. Квик такое пропускает, но в этом нет смысла.

2. Добавить обработку колбека OnOrder, чтобы он сбрасывал в ноль хранимый номер.

т.е. код должне выглядеть примерно так:

local Active_Trans_Id = 0 — храним номер заявки тут
local ID_B_Order=10

while getFuturesHolding(«SPBFUT», «SPBFUT****»,«SRU0»,0).totalnet > 0

if Active_Trans_Id == 0 then -- 

Quotes_1 = getQuoteLevel2(«SPBFUT», «SRU0»)
Bid_Count_1 = tonumber(Quotes_1.bid_count)

if Bid_Count_1>1 then
aa= tonumber(Quotes_1.bid[Bid_Count_1].quantity)
SetCell(Table, 1, 1, tostring(aa))
end

if aa>1 then

local OrderSell = {
[«ACTION»]=«NEW_ORDER»,
[«ACCOUNT»]= «SPBFUT****»,
[«OPERATION»] = «S»,
[«CLASSCODE»]=«SPBFUT»,
[«SECCODE»] = «SRU0»,
[«PRICE»] = «0»,
[«QUANTITY»] = tostring(1),
[«TRANS_ID»] = tostring(ID_B_Order),
[«TYPE»] = «M»,
}
local Err_Order = sendTransaction(OrderSell)
Active_Trans_Id = ID_B_Order — заполняем переменную номером TRANS_ID
ID_B_Order = ID_B_Order + 1 — увеличивает TRANS_ID, чтобы он был разный для каждой заявки
message(Err_Order)
end
sleep(1000)
end

— где-то за пределами main
— добавьте обработку колбека OnOrder
function OnOrder(order)
if order == Active_Trans_Id and (тут надо найти вставить проверку, что заявка исполнена проверяя биты order.flags) then
Active_Trans_Id = 0 — обнуляем номер активной заявки
end
end


т.е. если Active_Trans_Id равен 0, но программа отправляет заявку и присваитвает переменной Active_Trans_Id номер заявки.

В следующем проходе никакая заявка отправляться не будет, так как Active_Trans_Id не равен 0.

Колбек OnOrder смотрит, прошла ли заявка с номером Active_Trans_Id и если прошла, обнуляет Active_Trans_Id.

P.S. код писал в блокноте, не проверял. Под номером заявки, имею ввиде Trans_Id

 

 

avatar
т.е. там реально поменять порядок строк и добавить 5 новых строчек, чтобы все заработало. 

avatar
Chalyj7, спасибо! ) Как все непросто…
Цикл счётчик поставь
avatar
Просто каждый раз запрашивайте кол-во бумаг заново. Все.
На случай крайний поменяйте логику условия.
      repeat
          local asset = getFuturesHolding("SPBFUT", "SPBFUT****","SRU0",0).totalnet
          ****
      until asset==5
avatar

Читайте на SMART-LAB:
Фото
📌 МГКЛ после IPO: розничная сеть выросла почти вдвое — до 215 отделений
После выхода на биржу в декабре 2023 года МГКЛ продолжила расширять розничную сеть и развивать формат, объединяющий ломбардные услуги и...
Фото
Операционные результаты Х5 за 3 квартал 2026 года
Спешим поделиться с вами операционными итогами 3 квартала!   Несмотря на замедление рынка продовольствия в июле-августе 2026, мы смогли...
Фото
Lumentum: почему акции производителя лазеров выросли почти в 7 раз за год
Павел Гаврилов После нескольких лет тишины российским инвесторам вновь доступен рынок США через вечные фьючерсы. Продолжаем цикл материалов...
Фото
Обсуждаем стратегию Элвиса по рынку акций
На этой неделе Элвис выложил видео со своими идеями по рынку. Предлагаю его обсудить и поспорить с ним.

теги блога Врач-бондиатОр

....все тэги



UPDONW
Новый дизайн