Не срабатывает while Run and trans_Status == nil do sleep(1); end;

Страницы: 1
RSS
Не срабатывает while Run and trans_Status == nil do sleep(1); end;
 
Здравствуйте. В коде не срабатывает  while Run and trans_Status == nil do sleep(1); end;
Скажите пожалуйста как исправить или иначе написать.
--[[
]]

--/*НАСТРАИВАЕМЫЕ ПАРАМЕТРЫ*/
--ACCOUNT           = 'NL0011100043';       -- Идентификатор счета
ACCOUNT           = 'SPBFUT0026E';        -- Идентификатор счета
--CLASS_CODE        = 'QJSIM';              -- Код класса
CLASS_CODE        = 'SPBFUT';             -- Код класса
--SEC_CODE          = 'SBER';               -- Код бумаги
SEC_CODE          = 'SiM7';               -- Код бумаги
NPos=2   --размер открываемых позиций одной сделкой
Price1="PRICE"  --ссылка на график цены
ParMed1="SMA1"     --синий, ссылка на график


INTERVAL          = INTERVAL_M1;          -- Таймфрейм графика (для построения скользящих)

--/*РАБОЧИЕ ПЕРЕМЕННЫЕ РОБОТА (менять не нужно)*/
SEC_PRICE_STEP    = 0;                    -- ШАГ ЦЕНЫ ИНСТРУМЕНТА
SEC_NO_SHORT      = false;                -- Флаг, что по данному инструменту запрещены операции шорт
DS                = nil;                  -- Источник данных графика (DataSource)
ROBOT_STATE       ='В ПОИСКЕ ТОЧКИ ВХОДА';-- СОСТОЯНИЕ робота ['В ПРОЦЕССЕ СДЕЛКИ', либо 'В ПОИСКЕ ТОЧКИ ВХОДА']
trans_id          = os.time();            -- Задает начальный номер ID транзакций
trans_Status      = nil;                  -- Статус текущей транзакции из функции OnTransPeply
trans_result_msg  = '';                   -- Сообщение по текущей транзакции из функции OnTransPeply
CurrentDirect     = 'BUY';                -- Текущее НАПРАВЛЕНИЕ ['BUY', или 'SELL']
LastOpenBarIndex  =  0;                   -- Индекс свечи, на которой была открыта последняя позиция (нужен для того, чтобы после закрытия по стопу тут же не открыть еще одну позицию)
Run               = true;                 -- Флаг поддержания работы бесконечного цикла в main
Napravlenie_Sdelki=false --направление открытия позиции  ,Napravlenie_Sdelki='ПОЗИЯ КУПЛЕНА, ОТКРЫТА'   Napravlenie_Sdelki='ПОЗИЯ ПРОДАНА, ОТКРЫТА'


function crossOverMed()   --функция пересечения
if  tPrice1[0].close<tPrice2[0].close and tPrice1[1].close>tPrice2[1].close    then
    return true
else return false
end
end

function crossUnderMed()   --функция пресечения
if  tPrice1[0].close>tPrice2[0].close and tPrice1[1].close<tPrice2[1].close    then
    return true
else return false
end
end





-- Функция первичной инициализации скрипта (ВЫЗЫВАЕТСЯ ТЕРМИНАЛОМ QUIK в самом начале)
function OnInit()
  -- Получает доступ к свечам графика
  local Error = '';
  DS,Error = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL);
  -- Проверка
  if DS == nil then
     message('Простой MA-робот:ОШИБКА получения доступа к свечам! '..Error);
     -- Завершает выполнение скрипта
     Run = false;
     return;
  end;

  -- Получает ШАГ ЦЕНЫ ИНСТРУМЕНТА
  SEC_PRICE_STEP = getParamEx(CLASS_CODE, SEC_CODE, "SEC_PRICE_STEP").param_value;
end;

function main()
  -- Выводит сообщение
  message('Простой MA-робот: '..ROBOT_STATE);
  -- "Бесконечный" цикл
  while Run do
  NumCandles1=getNumCandles(Price1)
  NumCandles2=getNumCandles(ParMed1)

    tPrice1,n1,s1 = getCandlesByIndex (Price1, 0, NumCandles1-2, 2)   --считывает данные с графика цены
    tPrice2,n2,s2 = getCandlesByIndex (ParMed1, 0, NumCandles2-2, 2)  --считывает данные с графика сма


 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
 --механизм открытия позиции
 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------

 --Если СОСТОЯНИЕ робота "В ПРОЦЕССЕ СДЕЛКИ"
     if ROBOT_STATE == 'В ПРОЦЕССЕ СДЕЛКИ' then
        -- Выводит сообщение
        message('Робот: В ПРОЦЕССЕ СДЕЛКИ');
        -- Делает 10 попыток открыть сделку
        local Price = false; -- Переменная для получения результата открытия позиции (цена, либо ошибка(false))
        for i=1,10 do
           if not Run then return; end; -- Если скрипт останавливается, не затягивает процесс
           -- Если первый раз пытается открыть SELL, а операции шорт по данному инструменту запрещены
           if CurrentDirect == "SELL" and SEC_NO_SHORT then
              -- Прерывает цикл FOR
              break;
           end;
           -- Совершает СДЕЛКУ указанного типа ["BUY", или "SELL"] по рыночной(текущей) цене размером в 1 лот,
           --- возвращает цену открытой сделки, либо FALSE, если невозможно открыть сделку
           Price = Trade(CurrentDirect);
           -- Если сделка открылась
           if Price ~= false then
              -- Прерывает цикл FOR
              break;
           end;
           sleep(100); -- Пауза в 100 мс между попытками открыть сделку
        end;
        if not Run then return; end; -- Если скрипт останавливается, не затягивает процесс
        -- Если сделка открыта
        if Price ~= false then
ROBOT_STATE = 'ОТКРЫЛ ПОЗИЦИЮ №1'
message('Робот: ОТКРЫЛ ПОЗИЦИЮ №1');
       end;
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--откоытие позиции
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     else
        -- СОСТОЯНИЕ робота 'В ПОИСКЕ ТОЧКИ ВХОДА'
        -- Если на этой свече еще не было открыто позиций
        if DS:Size() > LastOpenBarIndex then
           -- Если быстрая пересекла медленную СНИЗУ ВВЕРХ
          -- if FastMA(DS:Size()-1) <= SlowMA(DS:Size()-1) and FastMA() > SlowMA() then
  if crossOverMed() and ROBOT_STATE == 'В ПОИСКЕ ТОЧКИ ВХОДА' then
              -- Задает направление НА ПОКУПКУ
              CurrentDirect = 'BUY';
              message('CurrentDirect = "BUY"');
              -- Меняет СОСТОЯНИЕ робота на "В ПРОЦЕССЕ СДЕЛКИ"
              ROBOT_STATE = 'В ПРОЦЕССЕ СДЕЛКИ';
           -- Если быстрая пересекла медленную СВЕРХУ ВНИЗ
           elseif         crossUnderMed() and ROBOT_STATE == 'В ПОИСКЕ ТОЧКИ ВХОДА' then
              -- Если по данному инструменту не запрещены операции шорт
              if not SEC_NO_SHORT then
                 -- Задает направление НА ПРОДАЖУ
                 CurrentDirect = 'SELL';
                 message('CurrentDirect = "SELL"');
                 -- Меняет СОСТОЯНИЕ робота на "В ПРОЦЕССЕ СДЕЛКИ"
                 ROBOT_STATE = 'В ПРОЦЕССЕ СДЕЛКИ';
              end;
           end;
        end;
     end;

     sleep(10);--Пауза 10 мс, для того, чтобы не перегружать процессор компьютера
  end;
end;

-- Функция вызывается терминалом QUIK при получении ответа на транзакцию пользователя
function OnTransReply(trans_reply)
  -- Если поступила информация по текущей транзакции
  if trans_reply.trans_id == trans_id then
     -- Передает статус в глобальную переменную
     trans_Status = trans_reply.status;
     -- Передает сообщение в глобальную переменную
     trans_result_msg  = trans_reply.result_msg;
 message('Робот: trans_Status '..trans_Status..' trans_result_msg '..trans_result_msg);
  end;
end;

-- Функция ВЫЗЫВАЕТСЯ ТЕРМИНАЛОМ QUIK при остановке скрипта
function OnStop()
  Run = false;
end;

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ --
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-- Совершает СДЕЛКУ указанного типа (Type) ["BUY", или "SELL"] по рыночной(текущей) цене размером в 1 лот,
--- возвращает цену открытой сделки, либо FALSE, если невозможно открыть сделку
function Trade(Type)
  --Получает ID транзакции
  trans_id = trans_id + 1;

  local Price = 0;
  local Operation = '';
  --Устанавливает цену и операцию, в зависимости от типа сделки и от класса инструмента
  if Type == 'BUY' then
     if CLASS_CODE ~= 'QJSIM' and CLASS_CODE ~= 'TQBR' then Price = getParamEx(CLASS_CODE, SEC_CODE, 'offer').param_value + 10*SEC_PRICE_STEP;end; -- по цене, завышенной на 10 мин. шагов цены
     Operation = 'B';
  else
     if CLASS_CODE ~= 'QJSIM' and CLASS_CODE ~= 'TQBR' then Price = getParamEx(CLASS_CODE, SEC_CODE, 'bid').param_value - 10*SEC_PRICE_STEP;end; -- по цене, заниженной на 10 мин. шагов цены
     Operation = 'S';
  end;
  -- Заполняет структуру для отправки транзакции
  local Transaction={
     ['TRANS_ID']   = tostring(trans_id),
     ['ACTION']     = 'NEW_ORDER',
     ['CLASSCODE']  = CLASS_CODE,
     ['SECCODE']    = SEC_CODE,
     ['OPERATION']  = Operation, -- операция ("B" - buy, или "S" - sell)
     ['TYPE']       = 'M', -- по рынку (MARKET)
     ['QUANTITY']   = tostring(NPos), -- количество
     ['ACCOUNT']    = ACCOUNT,
     ['PRICE']      = tostring(Price),
     ['COMMENT']    = 'Простой MA-робот'
  }
  -- Отправляет транзакцию
  sendTransaction(Transaction);
  -- Ждет, пока получит статус текущей транзакции (переменные "trans_Status" и "trans_result_msg" заполняются в функции OnTransReply())
  while Run and trans_Status == nil do sleep(1); end;
  -- Запоминает значение
  local Status = trans_Status;
  -- Очищает глобальную переменную
  trans_Status = nil;
  -- Если транзакция не выполнена по какой-то причине
  if Status ~= 3 then
     -- Если данный инструмент запрещен для операции шорт
     if Status == 6 then
        -- Выводит сообщение
        message('Робот: Данный инструмент запрещен для операции шорт!');
        SEC_NO_SHORT = true;
     else
        -- Выводит сообщение с ошибкой
        message('Робот: Транзакция не прошла!\nОШИБКА: '..trans_result_msg);
     end;
     -- Возвращает FALSE
     return false;
  else --Транзакция отправлена
     local OrderNum = nil;
     --ЖДЕТ пока ЗАЯВКА на ОТКРЫТИЕ сделки будет ИСПОЛНЕНА полностью
     --Запоминает время начала в секундах
     local BeginTime = os.time();
     while Run and OrderNum == nil do
        --Перебирает ТАБЛИЦУ ЗАЯВОК
        for i=0,getNumberOf('orders')-1 do
           local order = getItem('orders', i);
           --Если заявка по отправленной транзакции ИСПОЛНЕНА ПОЛНОСТЬЮ
           if order.trans_id == trans_id and order.balance == 0 then
              --Запоминает номер заявки
              OrderNum  = order.order_num;
              --Прерывает цикл FOR
              break;
           end;
        end;
        --Если прошло 10 секунд, а заявка не исполнена, значит произошла ошибка
        if os.time() - BeginTime > 9 then
           -- Выводит сообщение с ошибкой
           message('Робот: Прошло 10 секунд, а заявка не исполнена, значит произошла ошибка');
           -- Возвращает FALSE
           return false;
        end;
        sleep(10); -- Пауза 10 мс, чтобы не перегружать процессор компьютера
     end;

     --ЖДЕТ пока СДЕЛКА ОТКРЫТИЯ позиции будет СОВЕРШЕНА
     --Запоминает время начала в секундах
     BeginTime = os.time();
     while Run do
        --Перебирает ТАБЛИЦУ СДЕЛОК
        for i=0,getNumberOf('trades')-1 do
           local trade = getItem('trades', i);
           --Если сделка по текущей заявке
           if trade.order_num == OrderNum then
              --Возвращает фАКТИЧЕСКУЮ ЦЕНУ открытой сделки
  if Type == 'BUY' then Napravlenie_Sdelki='ПОЗИЯ КУПЛЕНА, ОТКРЫТА' elseif Type == 'SELL' then Napravlenie_Sdelki='ПОЗИЯ ПРОДАНА, ОТКРЫТА' end  -- флаг направления позиции

              return trade.price;
           end;
        end;
        --Если прошло 10 секунд, а сделка не совершена, значит на демо-счете произошла ошибка
        if os.time() - BeginTime > 9 then
           -- Выводит сообщение с ошибкой
           message('Робот: Прошло 10 секунд, а сделка не совершена, значит на демо-счете произошла ошибка');
           -- Возвращает FALSE
           return false;
        end;
        sleep(10); -- Пауза 10 мс, чтобы не перегружать процессор компьютера
     end;
  end;
end;

-- ПРИНУДИТЕЛЬНО ЗАКРЫВАЕТ ОТКРЫТУЮ ПОЗИЦИЮ переданного типа (Type) ["BUY", или "SELL"]
function KillPos(Type)
  -- Дается 10 попыток
  local Count = 0; -- Счетчик попыток
  if Type == 'BUY' then
     -- Пока скрипт не остановлен и позиция не закрыта
     while Run and not Trade('SELL') do -- Открывает SELL, тем самым закрывая BUY, если Trade('SELL') вернет TRUE, цикл прекратится
        Count = Count + 1; -- Увеличивает счетчик
        -- Если за 10 попыток не удалось закрыть позицию
        if Count == 10 then
           -- Возвращает NIL
           return nil;
        end;
        sleep(100); -- Пауза 100 мс, чтобы изменилась ситуация на сервере
     end;
  else
     -- Пока скрипт не остановлен и позиция не закрыта
     while Run and not Trade('BUY') do -- Открывает BUY, тем самым закрывая SELL, если Trade('BUY') вернет TRUE, цикл прекратится
        Count = Count + 1; -- Увеличивает счетчик
        -- Если за 10 попыток не удалось закрыть позицию
        if Count == 10 then
           -- Возвращает NIL
           return nil;
        end;
        sleep(100); -- Пауза 100 мс, чтобы изменилась ситуация на сервере
     end;
  end;
  -- Возвращает TRUE, если удалось принудительно закрыть позицию
  return true;
end;
-----
 
kvazar1988
Правильно ли я понял, что эту программу написали  не Вы?
 
Я ее частично позаимствовал. И где то она зацикливается при покупке и начинает бесконечно  покупать...
 
Цитата
kvazar1988 написал:
Я ее частично позаимствовал. И где то она зацикливается при покупке и начинает бесконечно  покупать...
Тогда Вы не совсем правильно задали вопрос в теме.
--------------------------------
Правильно получается так:
-------------------------
"Почему эта программа где то зацикливается при покупке и начинает бесконечно  покупать."
----------------------------
Чтобы ответить на этот вопрос надо сделать следующее:
1) восстановить алгоритм по тексту
2) поставить отладочную печать
3) сравнить результаты в файле отладки с алгоритмом и найти ошибку, а может быть и не одну.
--------------------
Как думаете, кто-нибудь, кроме Вас, будет это делать?
=========================
 
Врятли. Но дебагер говорил что с кодом все нормально.  
Страницы: 1
Читают тему
Наверх