Отслеживание Скользящей средней.

Страницы: 1
RSS
Отслеживание Скользящей средней., Помощь в написании робота.
 
Добрый день. Начал изучать lua для quik. Не могу разобраться в некоторых функциях. Робота пишу по ma10. Вход по пробитию закрытием часа ma(с низу вверх-лонг, сверху в низ - шорт). Выход по стопам, при пробитии стопа - входить в противоположную сделку по открытию следующего часа. Так же выход при пробитии закрытием свечи в обратную сторону(если лонг и закрытие свечи пробила с верху в низ - переворот).
1)Не могу понять в какую часть когда записать следующее условие: нужно что бы робот выходил при пробитии закрытия свечи ma и делал переворот.
2)Как прописать условие переворота после выбивание стопа.
3)Как прописать перенос сделок через ночь(я слышал, что есть какие-то базы данных для луа, куда можно записывать все сделки, для того, что бы утром робот торговал "своё" количество контрактов).

P.S. стоп-лосса - в пунктах
тейк-профит - в процентах

Буду благодарен за помощь.
Код
-- ТОРГОВЫЙ РОБОТ ПО СИСТЕМЕ СКОЛЬЗЯЩЕЙ СРЕДНЕЙ --  
  Account          = ""; -- счет клиента
  ClientCode       = ""; -- код клиента
  FirmCode         = ""; -- код фирмы
  SecCode          = ""; -- код инструмента
  ClassCode        = ""; -- класс инструмента
  Tag              = SecCode .. "_PRICE"; -- идентификатор графика цены
  EMA1             = SecCode .. "_EMA1"
  EMA2             = SecCode .. "_EMA2"
  Run              = true; -- отвечает за работу скрипта
  LastOpenBarIndex = 0; 
  FlagOrder        = false; -- флаг наличия активной заявки
  FlagStopOrder    = false;
  OrderNumber      = 0; -- номер заявки
  trans_id         = os.time(); -- уникальный id транзакции
  trans_number     = 0; -- номер транзакции
  trans_status     = 0; -- статус транзакции
  ClosePosition    = true;
  Count            = 0;
  Cycles           = 60;
  Rest             = 1; -- остаток в заявке 
  Start            = 65955; -- начало работы скрипта
  Stop             = 233000; -- конец работы скрипта
  StopLossl         = 350; -- размер стоп-лосса
  StopLosss         = 405; -- размер стоп-лосса
  TakeProfit      = 3.8/100
  Step             = 1; -- шаг цены
  Slip             = 0; -- проскальзывание цены
  Unit             = 10; -- количество лотов в заявке
  
   -- Главная функция скрипта --  
   function main()
       -- Основной цикл скрипта --
      while Run do
          if IsWindowClosed(t_id) then -- при закрытие окна торгового робота скрипт останавливается!!!
           Run = false;
           message("Stop trading robot!!!");
          end;
         
         if not_trade() then
         
             file = io.open(getScriptPath() .. "/LastOpenBarIndex.txt", "r");
            if file ~= nil then
               LastOpenBarIndex = tonumber(file:read("*n"));
              file:close();
            end;
          
            if LastOpenBarIndex == nil then LastOpenBarIndex = 0 end;
          
             if FlagOrder then
            
              done_order()
             
            elseif FlagStopOrder then
            
              stop_order()
             
            elseif LastOpenBarIndex < getNumCandles(Tag) then
            
              Predict = predict() -- получаем прогноз
             Position = position() -- узнаем позицию по инструменту
              
                if Predict > 0 and Position <= 0 then
                   if Position < 0 then
                     QtyBuy = math.abs(Position) + Unit;
                  elseif Position == 0 then
                   QtyBuy = Unit;
                  end;
                 buy(QtyBuy) -- покупаем
               elseif Predict < 0 and Position >= 0 then
                   if Position > 0 then
                     QtySell = Position + Unit;
                  elseif Position == 0 then
                    QtySell = Unit;
                  end;
                 sell(QtySell) -- продаем
               end;
               
             LastOpenBarIndex = getNumCandles(Tag);
             
             file = io.open(getScriptPath() .. "/LastOpenBarIndex.txt", "w");
               if file ~= nil then
                    file:write(tostring(LastOpenBarIndex));    
                     file:close();
               end;
            
            end;
              
          -- вывод параметров скрипта в таблицу --  
          SetCell(t_id, 1, 1, tostring(getInfoParam("SERVERTIME")));
           SetCell(t_id, 1, 2, SecCode);
           SetCell(t_id, 1, 3, tostring(position()));
           SetCell(t_id, 1, 4, tostring(round(tonumber(predict()), 10)));
           SetCell(t_id, 1, 5, tostring(round(tonumber(getPortfolioInfo(FirmCode, ClientCode).total_limit_open_pos), 2)));
           SetCell(t_id, 1, 6, tostring(round(tonumber(getPortfolioInfo(FirmCode, ClientCode).varmargin), 2)));
          
          sleep(1000);
            
         else
            sleep(1000);
         end;
      end;
   end;
   
   function not_trade()
     local Error = true;
       if isConnected() == 1 then
        local Time = 0;
       
        SERVER_TIME = getInfoParam("SERVERTIME"); 
       
         if string.len(SERVER_TIME) == 8 then
           Time = tonumber(SERVER_TIME:sub (1,2) .. SERVER_TIME:sub (4,5) .. SERVER_TIME:sub (7,8));
         else
           Time = tonumber(SERVER_TIME:sub (1,1) .. SERVER_TIME:sub (3,4) .. SERVER_TIME:sub (6,7));
         end;    
         
         if Time == nil then Time = 0 end;
         
         if Time < Start then
          Error = false;
          SetCell(t_id, 1, 1, "ErrorTime");
            for i = 2,6 do
               SetCell(t_id, 1, i, "0");
             end;
         elseif Time > 135900 and Time < 140600 then
           Error = false;
          SetCell(t_id, 1, 1, "Clearing");
            for i = 2,6 do
               SetCell(t_id, 1, i, "0");
             end;
         elseif Time > 184400 and Time < 190600 then
           Error = false;
          SetCell(t_id, 1, 1, "Clearing");
            for i = 2,6 do
               SetCell(t_id, 1, i, "0");
             end;
         elseif Time > Stop then
           Error = false;
          SetCell(t_id, 1, 1, "ErrorTime");
            for i = 2,6 do
               SetCell(t_id, 1, i, "0");
             end;
            
          -- закрытие позиции и снятие стоп-заявки в конце торговой сессии --
          --[[local Position = position();
             if Position ~= 0 then
                if ClosePosition then
                   if Position > 0 then
                    Slip = 0;
                      sell(Position);
                    elseif Position < 0 then
                    Slip = 0;
                      buy(math.abs(Position));
                   end;
                FlagOrder = false;
                 ClosePosition = false;
               end;
            elseif Position == 0 then
              stop_order()
             ClosePosition = true;
            end;]]
         end;
      else
        Error = false;
       SetCell(t_id, 1, 1, "ErrorConnection");
         for i = 2,6 do
           SetCell(t_id, 1, i, "0");
         end;
      end;
    return Error;  
   end;
   
   -- Функция покупки --
   function buy(QtyBuy)
     local PriceBuy = 0; -- цена по которой покупаем
   
       while PriceBuy <= 0 do
        PriceBuy = tonumber(getParamEx(ClassCode, SecCode, "offer").param_value) - Step * Slip -- получаем лучшую цену предложения
      end;
     
    message("Order to buy at the price: " .. PriceBuy .. ", qty: " .. QtyBuy);
      
    trans_id = trans_id + 1;
    local trans_params = {
        ['TRANS_ID']    = tostring(trans_id),
         ['ACTION']      = "NEW_ORDER",
         ['CLASSCODE']   = ClassCode,
         ['SECCODE']     = SecCode,
         ['OPERATION']   = "B", 
         ['TYPE']        = "M", 
         ['QUANTITY']    = tostring (math.floor(QtyBuy)), 
         ['ACCOUNT']     = Account,
         ['PRICE']       = tostring(math.floor(PriceBuy)),
       ['CLIENT_CODE'] = ClientCode 
                         }
                    
    trans_status = 0;
     trans_number = 0;
    
    sendTransaction(trans_params)
      
      while trans_status ~= 3 do
       sleep(20);
      end;
      
    OrderNumber = trans_number;
    FlagOrder = true; 
   end;

   -- Функция продажи --
   function sell(QtySell)
     local PriceSell = 0; -- цена по которой продаем
    
       while PriceSell <= 0 do
        PriceSell = tonumber(getParamEx(ClassCode, SecCode, "bid").param_value) - Step * Slip -- получаем лучшую цену спроса
      end;
      
    message("Order to sell at the price: " .. PriceSell .. ", in the quantity: " .. QtySell);
      
    trans_id = trans_id + 1;
    local trans_params = {
        ['TRANS_ID']    = tostring(trans_id),
         ['ACTION']      = "NEW_ORDER",
         ['CLASSCODE']   = ClassCode,
         ['SECCODE']     = SecCode,
         ['OPERATION']   = "S", 
         ['TYPE']        = "M", 
         ['QUANTITY']    = tostring (math.floor(QtySell)), 
         ['ACCOUNT']     = Account,
         ['PRICE']       = tostring(math.floor(PriceSell)),
       ['CLIENT_CODE'] = ClientCode    
                         }
                    
    trans_status = 0;
     trans_number = 0;
    
    sendTransaction(trans_params) 
    
      while trans_status ~= 3 do
       sleep(20);
      end;
      
    OrderNumber = trans_number;
    FlagOrder = true; 
   end;

   -- Функция контроля исполнения активной заявки --
   function done_order()
     local QtyOrder = 0;
     local PriceOrder = 0;
          
      for i = 0, getNumberOf("orders") - 1 do
          if getItem("orders", i).order_num == OrderNumber then
           Rest = getItem("orders", i).balance;
             while PriceOrder <= 0 do
              PriceOrder = getItem("orders", i).price;
             QtyOrder = getItem("orders", i).qty;
             sleep(20);
            end;
         end;
      end;
     
      -- если заявка полностью исполнилась --
      if Rest == 0 then
        message(getInfoParam("SERVERTIME") .. " Order №" .. OrderNumber .. " fully executed, at the price without slipping: " .. PriceOrder .. " in quantity: " .. QtyOrder, 1)
        FlagOrder = false;
       FlagStopOrder = true;
       Count = 0;
       
      -- если заявка не исполнилась, снимаем отстаток --    
      elseif Count > Cycles then
        kill_order(OrderNumber);
        message(getInfoParam("SERVERTIME") .. " Order №" .. OrderNumber .. " canceled, rest: " .. Rest, 1)
       Count = 0;
       FlagOrder = false;
       
         if position() ~= 0 then
          FlagStopOrder = true;
          end;
        
       file = io.open(getScriptPath() .. "/LastOpenBarIndex.txt", "w");
        file:write("");
         file:close();
        
      -- если заявка еще не исполнилась, но время на исполнение еще осталось --
      elseif Rest > 0 then
        Count = Count + 1;
      end;
     sleep(1000);
   end;   
 
  -- Функция выставления stop_loss --
   function stop_order()
       
       local PriceStopOrder = 0;
      local Position = position();
      
      -- снимаем старую стоп-заявку --
      for i = 0, getNumberOf("stop_orders") - 1 do
           if bit.test(getItem("stop_orders", i).flags, 0) == true then
          kill_stop_order(getItem("stop_orders", i).order_num);
           end;            
      end;
      
       -- определяем цену по которой заключена сделка --
      if Position ~= 0 then
           for i = 0, getNumberOf("trades") - 1 do
              if getItem("trades", i).order_num == OrderNumber then
                 while PriceStopOrder <= 0 do
                  PriceStopOrder = getItem("trades", i).price;
                 sleep(20);
                end;
             end;
          end;
      end;
   
      if PriceStopOrder > 0 and Position ~= 0 then
      
          if Position > 0 then
           StopPrice = PriceStopOrder - StopLossl;
          PriceX = PriceStopOrder - Step * 200;
          QtyStopOrder = Position;
          Operation = "S";
         elseif Position < 0 then
           StopPrice = PriceStopOrder + Step * StopLosss;
          PriceX = PriceStopOrder + Step * 200;
          QtyStopOrder = math.abs(Position);
          Operation = "B";
         end;
         
           trans_id = trans_id + 1; 
           local trans_params = {
           ['TRANS_ID']        = tostring(trans_id),
           ['ACTION']          = "NEW_STOP_ORDER",
         ['STOP_ORDER_KIND'] = "SIMPLE_STOP_ORDER",
         ['EXPIRY_DATE']     = "TODAY",
         ['STOPPRICE']       = tostring(math.floor(StopPrice)),
           ['CLASSCODE']       = ClassCode,
           ['SECCODE']         = SecCode,
           ['PRICE']           = tostring(math.floor(PriceX)),
           ['OPERATION']       = Operation, 
           ['TYPE']            = "L", 
           ['QUANTITY']        = tostring(math.floor(QtyStopOrder)), 
           ['ACCOUNT']         = Account,
         ['CLIENT_CODE']     = ClientCode
                              }
                  
          trans_status = 0; -- сбрасываем прошлый статус транзакции
    
           sendTransaction(trans_params); -- отправляем транзакцию
    
          while trans_status ~= 3 do
            sleep(20);
          end; 
         if Position > 0 then
           StopPrice = PriceStopOrder - StopLossl;
          PriceX = PriceStopOrder - Step * 200;
          QtyStopOrder = Position;
          Operation = "S";
         elseif Position < 0 then
           StopPrice = PriceStopOrder + Step * StopLosss;
          PriceX = PriceStopOrder + Step * 200;
          QtyStopOrder = math.abs(Position);
          Operation = "B";
         end;
         
           trans_id = trans_id + 1; 
           local trans_params = {
           ['TRANS_ID']        = tostring(trans_id),
           ['ACTION']          = "NEW_STOP_ORDER",
         ['STOP_ORDER_KIND'] = "SIMPLE_STOP_ORDER",
         ['EXPIRY_DATE']     = "TODAY",
         ['STOPPRICE']       = tostring(math.floor(StopPrice)),
           ['CLASSCODE']       = ClassCode,
           ['SECCODE']         = SecCode,
           ['PRICE']           = tostring(math.floor(PriceX)),
           ['OPERATION']       = Operation, 
           ['TYPE']            = "L", 
           ['QUANTITY']        = tostring(math.floor(QtyStopOrder)), 
           ['ACCOUNT']         = Account,
         ['CLIENT_CODE']     = ClientCode
                              }
                  
          trans_status = 0; -- сбрасываем прошлый статус транзакции
    
           sendTransaction(trans_params); -- отправляем транзакцию
    
          while trans_status ~= 3 do
            sleep(20);
          end; 
         --[[]]
         if Position > 0 then
           StopPrice = PriceStopOrder *(TakeProfit+1) ;
          PriceX = PriceStopOrder - Step * 200;
          QtyStopOrder = Position;
          Operation = "S";
         elseif Position < 0 then
           StopPrice = PriceStopOrder *(1-TakeProfit);
          PriceX = PriceStopOrder + Step * 200;
          QtyStopOrder = math.abs(Position);
          Operation = "B";
         end;
         
           trans_id = trans_id + 1; 
           local trans_params = {
           ['TRANS_ID']        = tostring(trans_id),
           ['ACTION']          = "NEW_STOP_ORDER",
         ['STOP_ORDER_KIND'] = "SIMPLE_STOP_ORDER",
         ['EXPIRY_DATE']     = "TODAY",
         ['STOPPRICE']       = tostring(math.floor(StopPrice)),
           ['CLASSCODE']       = ClassCode,
           ['SECCODE']         = SecCode,
           ['PRICE']           = tostring(math.floor(PriceX)),
           ['OPERATION']       = Operation, 
           ['TYPE']            = "L", 
           ['QUANTITY']        = tostring(math.floor(QtyStopOrder)), 
           ['ACCOUNT']         = Account,
         ['CLIENT_CODE']     = ClientCode
                              }
                  
          trans_status = 0; -- сбрасываем прошлый статус транзакции
    
           sendTransaction(trans_params); -- отправляем транзакцию
    
          while trans_status ~= 3 do
            sleep(20);
          end; 
         
         FlagStopOrder = false;
       end;
   end;
   
   -- Функция снятия заявки --
   function kill_order(Number)
     trans_id = trans_id + 1;
     local trans_params = {
         ['TRANS_ID']   = tostring(trans_id),
         ['ACTION']     = "KILL_ORDER",
         ['CLASSCODE']  = ClassCode,
         ['SECCODE']    = SecCode,
         ['ACCOUNT']    = Account,
        ['ORDER_KEY']  = tostring(Number)
                          }
     sendTransaction(trans_params);
   end;
   
   -- Функция снятия стоп-заявки --
   function kill_stop_order(Number)
     trans_id = trans_id + 1;
     local trans_params = {
         ['TRANS_ID']   = tostring(trans_id),
         ['ACTION']     = "KILL_STOP_ORDER",
         ['CLASSCODE']  = ClassCode,
         ['SECCODE']    = SecCode,
         ['ACCOUNT']    = Account,
        ['STOP_ORDER_KEY']  = tostring(Number)
                          }
     sendTransaction(trans_params);
   end;
   
   -- Функция прогнозирования движения цены инструмента --
   function predict()
     local t, n, l = nil,nil,nil
      while t == nil do
       x1 = getNumCandles('Tag')
       t, n, l = getCandlesByIndex('Tag', 0, 0, x1)
       ma_1 = t[0].close
       for i=1, x1-1 do
       local C = t[i].close
       local C1 = t[i-1].close
       local C2 = t[i-2].close
       local C3 = t[i-3].close
       local C4 = t[i-4].close
       local C5 = t[i-5].close
       local C6 = t[i-6].close
       local C7 = t[i-7].close
        local C8 = t[i-8].close
        local C9 = t[i-9].close
        ma_2 = (C1+C2+C3+C4+C5+C6+C7+C8+C9+C)/10 

       ma_1 = ma_2
       end
        --
       sleep(10)
       end;
      local ema2 = ma_1;
      
      local ema1 = t[x1].close
     
    local result
      if ema1 > ema2 then
         result = 1;
      elseif ema1 < ema2 then
         result = -1
      end;
    return result;
   end;
   
   -- Функция определения позиции по инструменту --   
   function position()
     local res = 0;
      for i = 0, getNumberOf("futures_client_holding") - 1 do
         if getItem("futures_client_holding", i).sec_code == SecCode then
            res = tonumber(getItem("futures_client_holding", i).totalnet);
          end;
      end;
    return res;
   end;
 
   -- Функция обратного вызова запускается первой и создает таблицу торгового робота --
   function OnInit()
     message("Start trading robot!");
     t_id = AllocTable(); -- создаем таблицу
    AddColumn (t_id,1,"Time", true, QTABLE_TIME_TYPE, 15);
    AddColumn (t_id,2,"Sec_Code", true, QTABLE_STRING_TYPE, 10);
    AddColumn (t_id,3,"Position", true, QTABLE_STRING_TYPE, 10);
    AddColumn (t_id,4,"Predict", true, QTABLE_STRING_TYPE, 15);
    AddColumn (t_id,5,"Balance", true, QTABLE_STRING_TYPE, 10);
    AddColumn (t_id,6,"Margin", true, QTABLE_STRING_TYPE, 10);
    CreateWindow(t_id); -- создаем окно таблицы
    SetWindowCaption(t_id, "Trading robot");
    InsertRow(t_id, 1);
   end;
   
   -- Функция обратного вызова для получения результата отправки транзакции --   
   function OnTransReply(trans_reply)
       if trans_reply.trans_id == trans_id then
         trans_status = trans_reply.status;
       trans_number = trans_reply.order_num;
      end;
   end;
   
   -- Функция обратного вызова остановки скрипта --   
   function OnStop()
     Run = false;
    DestroyTable(t_id);
   end;
   
   -- Функция округления чисел --   
   function round(x, n)
     n = math.pow(10, n or 0)
     x = x * n
     if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end;
     return x / n
   end;
Страницы: 1
Читают тему
Наверх