Тейк профит и стоп-МАРКЕТ заявка для луа

Страницы: 1
RSS
Тейк профит и стоп-МАРКЕТ заявка для луа, стоп-заявка проскальзывает, так как стоит стоп-лимит
 
Коллеги, привет!
Скрипт работает уже давно, используется заявка тейк-профит и стоп-лимит, но в пятницу размер стопа не спас ситуацию, нефть слишком упала, и заявку протащило. Поэтому возник вопрос: как сделать заявку тейк-профит и стоп-маркет, чтобы таких ситуаций избегать?
Испробована версия с выставлением нулевых параметров, но система логично такую историю отвергает, в итоге и стоп- не стоит, и позиция взята, слишком рисково.

Как получилось на реальном примере: выставлена заявка на закрытие фьюча по нефти, тейк 83, стоп 81,7, цена стопа 81,55. Что вышло на практике? нефть упала в 80 в начале торговой сессии, стоп выставил заявку на продажу по 81,55, и пришлось закрыть сделку руками. Как сделать так, чтобы при прохождении 81,7 у меня выставлялась заявка на продажу по маркету?
Думала сама над двумя связанными заявками, но может, у кого есть попроще решение?

Коды все рабочие, представлены ниже. Заранее большое спасибо за ответ!

Как выглядит заявка (тут все тоже рабочее):
Код
function stop2_calc()
   if (PRICEMAX-ZZ12)>500 then
   stop=PRICEMAX-500
   else stop = ZZ12
   end
end

function BUY(FLOTS)
   ORDER(FLOTS,"B",dD(PRICEMAX+0,0))
   stop2_calc()
   message("stop "..stop)
   TAKESTOPORDER(FLOTS,"S",dD(ZZ31+0,0), dD(stop,0),dD(stop-0,15,0),100,100)
end   
функция стопа (она рабочая)
Код
function TAKESTOPORDER(FLOTS,FDIRECTION,FSTOP,FSTOP2,FPRICE,FOTSTUP,FSPREAD)
   q = {
      ["ACTION"]= "NEW_STOP_ORDER",      
      ["CLASSCODE"]=CLASSCODE,      
      ["SECCODE"]=INSTRUMENT,
      ["ACCOUNT"]= ACCOUNT,
      ["STOP_ORDER_KIND"] = "TAKE_PROFIT_AND_STOP_LIMIT_ORDER",
      ["TYPE"]="L",
      ["OPERATION"]=FDIRECTION,
      ["QUANTITY"]=tostring(FLOTS),
      ["STOPPRICE"]=tostring(FSTOP),
      ["STOPPRICE2"]=tostring(FSTOP2),
      ["PRICE"]=tostring(FPRICE),
      ["OFFSET"] = tostring(FOTSTUP),
        ["OFFSET_UNITS"] = "PRICE_UNITS",
        ["SPREAD"] = tostring(FSPREAD),
        ["SPREAD_UNITS"] = "PRICE_UNITS",
        ["EXPIRY_DATE"] = "GTC",
      ["TRANS_ID"]=tostring(id_take),
      ["CLIENT_CODE"]=Robot
     }
   res=sendTransaction(q)
   message(res,1)
end
 
Есть варианты:
- увеличивать отступ исполнения стоп-ордера, чтобы была больше вероятность исполнения отправленной лимитной заявки (но, возможно, больше будет ГО)
- не ставить стоп физически, а отслеживать цену алгоритмом и закрывать "по рынку" исходя из текущей ситуации, если алгоритм решил, что стоп сработал.
- более сложный вариант отслеживания активации стопа. После того как получен признак что стоп исполнен, проверять установку связанного с ним лимитного ордера и его исполнение. Если он не исполнен, снимать его алгоритмом и ставить новый исходя из текущей цены. Т.е. реализовать алгоритм "гонки за ценой". Т.к. мы никогда не знаем какая в будущем будет ситуация в момент активации стопа (т.е. угадать отступ), то, по хорошему, какой-то вариант "гонки" все равно необходимо реализовать.

Также не стоит забывать про битовые флаги 10 и 11 стоп ордера:

бит 10 (0x400)      -   Стоп-заявка сработала, но была отвергнута торговой системой
бит 11 (0x800)      -   Стоп-заявка сработала, но не прошла контроль лимитов

Ордер может исполнится, а лимитный ордер вообще не прошел. Позиция останется, если это не контролировать.
 
Цитата
Nikolay написал:
- не ставить стоп физически, а отслеживать цену алгоритмом и закрывать "по рынку" исходя из текущей ситуации, если алгоритм решил, что стоп сработал.
Предпочитаю именно этот подход
 
Цитата
Предпочитаю именно этот подход
Да, но важно отметить, что в таком случае важно обеспечить постоянную работоспособность алгоритма, вне зависимости от отключения связи и электропитания.
 
Цитата
Nikolay написал:
Цитата
Предпочитаю именно этот подход
Да, но важно отметить, что в таком случае важно обеспечить постоянную работоспособность алгоритма, вне зависимости от отключения связи и электропитания.
Подход хороший и понятный, но не читается почему-то значение, записанное в файл. То есть я пошла следующим путем: открывается сделка, записываю все параметры в файл, читаю потом из файла то самое значение, которое будет стопом, но цифры после точки не считываются почему-то. Функций округления при этом нет. Инструмент - нефть. И было бы понятно, если бы он не читал эти данные в формулах где-то, но он из файла их не читает. При этом сепаратором стоит ;.
 
Скорее всего просто нарушено форматирование при сохранении или уже при чтении проблема алгоритма.


Лучше пойти путем хранения самого контекста скрипта.
Для примера, есть некое состояние, скажем State - это таблица с необходимыми данными. Мы ее сохраняем в файл в виде сериализованой таблицы.
Тогда чтение будет через одну единственную команду loadfile.

Для сериализации таблицы состояния можно воспользоваться любым итерационным (рекурсивным) методом:http://lua-users.org/wiki/TableSerialization

Лишь бы он позволял хранить восстанавливаемые данные через loadfile.

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

return {
   filed = 1,
   field2 = 'some_string',
   inner_t = {
       b = 2,
       c = 3
   }

}

т.е. как простой код lua
 
Что-то вас куда-то не туда повело...

Да, лично я сроду не ставил никаких стопов и даже никогда не закрывал "по рынку" (только лимитными заявками), "если алгоритм решил, что стоп сработал". От отключения связи и электропитания не страхуюсь (в конце концов, скачки курса, когда наша биржа не работает, куда более вероятны, чем обрыв связи), но при чём здесь вообще файл? Работаем в ОЗУ! Я сбрасываю, конечно, дамп состояния в файл каждые 5 минут (страховка от отвисания Квика, которые в последнее время происходят всё чаще), но это лишь для того, чтобы не потерять ВСЕ свои сделки за сеанс.
 
Коллеги, спасибо за помощь и наводки! В итоге скрипт заработал. Мало ли кому будет надо, выкладываю. Просьба не обращать внимание на комменты, я после ковида очень боюсь опять потерять память, поэтому все себе комментирую.
Как работает? Забирает отклик при отправке транзакции, если она выполнена, записывает в файл (этого тут нет), далее в файле находит строку и забирает оттуда значение для стопа, которое записано в файлике. Таким образом ничего не теряется. Ошибка нечтения была именно в неверном формате чтения, не записи.
Код
function ReadCsv(FP) -- чтение файла и присвоение значений ТР и стопу
   f = io.open(FP,"r+")
   local N_CSV_BEGIN = 2
   local LINE_A = {}
   local Datetime = {}           -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Instr = {}         -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Total = {}              -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Activity = {}           -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Price = {}              -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Ordernumber = {}        -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Ordertype = {}          -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Account= {}             -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Robot_name = {}         -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Status = {}         -- МАССИВ СТРОК ИЗ ОСНОВНОГО ФАЙЛА
   local Stops = {}
   if f==nil then 
      message("НЕТ ФАЙЛА ",3)
      EXIT = 1
      SL = 10000  -- 10000
   else
      -- message("ФАЙЛ ЕСТЬ",3)
      EXIT = 0
      SL = 1000
      j = 1
      for line in f:lines() do 
         LINE_A[j] = tostring(line)
         --message("I'm here")
         --message("Строка "..j.." ="..LINE_A[j],1)
         j = j + 1
      end
      f:close()
      NCSV = j - N_CSV_BEGIN
      --message("NCSV= "..NCSV,1)
      if NCSV<1 then Stopqty=0 end
        for i = NCSV, 1,-1 do
      if idx==1 then break end
      -- Парсим все строки на массивы
         --message("LINE_A[N_CSV_BEGIN+i-1]  ="..LINE_A[N_CSV_BEGIN+i-1],1)
           Datetime[i],Instr[i], Total[i], Activity[i], Price[i], Ordernumber[i],Ordertype[i],Account[i], Robot_name[i], Status[i], Stops[i] = string.match(LINE_A[N_CSV_BEGIN+i-1],"(.*);(.*);(.*);(.*);(.*);(%d*);(.*);(.*);(.*);(.*);(.*)")
          --message("I'm here")
          Datetime[i] = tostring(Datetime[i])
          Instr[i] = tostring(Instr[i])
          Total[i] = tonumber(Total[i])
          Activity[i] = tostring(Activity[i])
          Price[i] = tonumber(Price[i])+0.00
          Ordernumber[i] = Ordernumber[i]+0.00
          Ordertype[i] = tostring(Ordertype[i])
          Account[i] = tostring(Account[i])
          Robot_name[i] = tostring(Robot_name[i])
          Stops[i] = (tonumber(Stops[i])+0.00)
          Status[i] = tostring(Status[i])

         Stopqty = Stops[i]
         message("Stopqty "..Stopqty,1)
         idx=1
      end --end for
   end --if else
end   --   function
Страницы: 1
Читают тему
Наверх