Врач-бондиатОр
Врач-бондиатОр личный блог
23 июля 2020, 18:48

Вопрос по Луа 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>
16 Комментариев
  • Андрей К
    23 июля 2020, 19:11
    там же на форуме уже разжевали почему так. Зациклился while, которого у вас нет в вашем примере
      • Андрей К
        23 июля 2020, 20:13
        Врач-бондиатОр, в вычислении asset учитывать ещё и открытые заявки по нему, которые наставились в предыдущих итерациях цикла
    • kachanov
      23 июля 2020, 19:59
      Андрей К, есть в примере, притаился сверху ))) только end для него нема
        • kachanov
          23 июля 2020, 21:13
          Врач-бондиатОр, первая строка
          <code class="rainbow" data-language="lua">   while stopped == false do
          начало цикла 
          while stopped == false do

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

        • kachanov
          23 июля 2020, 21:27
          Врач-бондиатОр, о, end тоже не сразу разглядел )) он есть!
          в данном коде достаточно поставить после цикла repeat остановку while

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

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

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

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

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

     
      • Chalyj7
        23 июля 2020, 19:46
        Врач-бондиатОр, да. Не имеет значения сколько заявок. Надо ждать исполнения отправленной заявки и только потом отправлять следующую.
          • Chalyj7
            23 июля 2020, 22:19

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

            у Вас в коде

            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

             

             

            • Chalyj7
              23 июля 2020, 22:21
              т.е. там реально поменять порядок строк и добавить 5 новых строчек, чтобы все заработало. 

  • Френк френков
    23 июля 2020, 21:11
    Цикл счётчик поставь
  • Винни Пух
    23 июля 2020, 21:13
    Просто каждый раз запрашивайте кол-во бумаг заново. Все.
    На случай крайний поменяйте логику условия.
          repeat
              local asset = getFuturesHolding("SPBFUT", "SPBFUT****","SRU0",0).totalnet
              ****
          until asset==5

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

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