Yerlan (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: 1
Просто открыть сделку на инструменте проблема, Работает стабильно код на языке луа но дает ошибку
 
Нормально работает но каждый раз после рестарта терминала выдает ошибку error cliring  один раз на старте. Это довольно напрягает и можно не заметить что сделка не состоялась.
Просто открыть сделку на инструменте проблема, Работает стабильно код на языке луа но дает ошибку
 
Код
local ver = '1.4'   --   06.03.2016
local lastPos = 0
local lastPrice = 0
local string_gmatch=string.gmatch
local string_find=string.find
local string_sub=string.sub
local string_len=string.len
local string_format=string.format
local math_modf=math.modf
local SeaGreen=12713921      --   RGB(193, 255, 193)
local RosyBrown=12698111   --   RGB(255, 193, 193)
local logFile
local trades = {} -- Таблица_01 - получили сделку
local _trades = {} -- временная таблица наших сделок для отлова дублей в QUIK ver. 7.1.0
local orders = {}   --   Таблица заявок
local scriptPath = getScriptPath()
local Terminal_Version=getInfoParam('VERSION')

local function versionLess(ver1,ver2)
   local begin,ver_1=0
   for ver_2 in string_gmatch(ver2,'%d+') do
      _,begin,ver_1=string_find(ver1,'(%d+)',begin+1)
      if ver_1~=ver_2 then return not ver_1 or ver_1+0<ver_2+0 end
   end
   return false
end
local  v = '6.17'
local table_insert
local table_remove
local table_concat
if versionLess(Terminal_Version,v ) then
   table_insert=table.ins ert
   table_remove=table.remove
   table_concat=table.concat
else   
   table_insert=table.sinsert
   table_remove=table.sremove
   table_concat=table.sconcat
end
-----

local dc = QTABLE_DEFAULT_COLOR

local testQuik = true -- подписка на OnTransReply, OnTrade, OnOrder
--local testQuik = false -- без подписки

function firm_id()
  for i = 0, getNumberOf("money_limits") - 1 do
    local row = getItem("money_limits", i)
    if row ~= nil and row.firmid ~= nil then
      local ss = tostring(string_sub(row.firmid, 2, 2))
      if ss == "C" or ss == "R" or ss == "B" then
        return tostring(row.firmid)
      end
    end
  end
  return nil
end

local is_forts = true
--настройки
function getInitParameter()
   if is_forts then
      account = ''
      classCode = ''
      secCode = 'RIM9'
      OpenSlippage = 50
      
      CLASS_CODE           = 'SPBFUT'        -- Код класса
      SEC_CODE             = 'RIM9'          -- Код инструмента
   else
      account="NL0011100043"
      ClientCode = "99914"
      classCode = 'QJSIM'
      secCode = 'SBER'
      OpenSlippage = 0.5
      firm_id = firm_id()
      message('firm_id = '..firm_id)
   end
   workSize = 4 -- рабочий размер
   logFileName1 = 'logFile1.txt'   -- файл для укороченного протоколирования коллбэков
   logFileName2 = 'logFile2.txt'   -- файл для печати всех полей коллбэков
end
---------------------------------------------------------
-- Округляет число до указанной точности
math_round = function(num, idp)
  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
end
-- Приводит переданную цену к требуемому для транзакции по инструменту виду
GetCorrectPrice = function(price) -- STRING
   -- Получает точность цены по инструменту
   local scale = getSecurityInfo(CLASS_CODE, SEC_CODE).scale
   -- Получает минимальный шаг цены инструмента
   local PriceStep = tonumber(getParamEx(CLASS_CODE, SEC_CODE, "SEC_PRICE_STEP").param_value)
   -- Если после запятой должны быть цифры
   if scale > 0 then
      price = tostring(price)
      -- Ищет в числе позицию запятой, или точки
      local dot_pos = price:find('.')
      local comma_pos = price:find(',')
      -- Если передано целое число
      if dot_pos == nil and comma_pos == nil then
         -- Добавляет к числу ',' и необходимое количество нулей и возвращает результат
         price = price..','
         for i=1,scale do price = price..'0' end
         return price
      else -- передано вещественное число         
         -- Если нужно, заменяет запятую на точку 
         if comma_pos ~= nil then price:gsub(',', '.') end
         -- Округляет число до необходимого количества знаков после запятой
         price = math_round(tonumber(price), scale)
         -- Корректирует на соответствие шагу цены
         price = math_round(price/PriceStep)*PriceStep
         price = string.gsub(tostring(price),'[\.]+', ',')
         return price
      end
   else -- После запятой не должно быть цифр
      -- Корректирует на соответствие шагу цены
      price = math_round(price/PriceStep)*PriceStep
      return tostring(math.floor(price))
   end
end

-- Возвращает корректную цену для рыночной заявки по текущему инструменту (принимает 'S',или 'B')
GetPriceForMarketOrder = function(operation) -- STRING
   -- Получает минимальный шаг цены инструмента
   local PriceStep = tonumber(getParamEx(CLASS_CODE, SEC_CODE, "SEC_PRICE_STEP").param_value)
   -- В зависимости от направления
   if operation == 'B' then -- BUY
      -- Пытается получить максимально возможную цену для инструмента
      local PriceMax = tonumber(getParamEx(CLASS_CODE,  SEC_CODE, 'OFFER').param_value)
      -- Если максимально возможная цена получена
      if PriceMax ~= nil and PriceMax ~= 0 then
         -- Возвращает ее в нужном для транзакции формате
         return GetCorrectPrice(PriceMax)
      -- Иначе, максимально возможная цена не получена
      else
         -- Получает цену последней сделки
         local Last = tonumber(getParamEx(CLASS_CODE,  SEC_CODE, 'LAST').param_value)
         -- Возвращает ее в нужном для транзакции формате, увеличив перед этим на 50 шагов цены
         return GetCorrectPrice(Last + 50*PriceStep)
      end
   else                     -- SELL
      -- Пытается получить минимально возможную цену для инструмента
      local PriceMin = tonumber(getParamEx(CLASS_CODE,  SEC_CODE, 'BID').param_value)
      -- Если минимально возможная цена получена
      if PriceMin ~= nil and PriceMin ~= 0 then
         -- Возвращает ее в нужном для транзакции формате
         return GetCorrectPrice(PriceMin)
      -- Иначе, минимально возможная цена не получена
      else
         -- Получает цену последней сделки
         local Last = tonumber(getParamEx(CLASS_CODE,  SEC_CODE, 'LAST').param_value)
         -- Возвращает ее в нужном для транзакции формате, уменьшив перед этим на 50 шагов цены
         return GetCorrectPrice(Last - 50*PriceStep)
      end
   end 
end

function isModule(modname)
   if not package.loaded[modname] then   -- Если модуль modname не загружен ранее
      for i, v in ipairs(package.loaders) do
         local loader = v(modname)
         if type(loader) == 'function' then
            package.preload[modname] = loader
            return true
         end
      end
   end
end
--
local modname = "socket.socket"
local isSocket
local _mes
if isModule(modname) then
   isSocket = require(modname)
else   
   _mes = modname..' No exist!'; message(_mes,3)
end


function getHRTime()
   -- возвращает время с милисекундами или без них, в зависимости от наличия socket.socket
   if isSocket then 
      local now = socket.gettime() 
      return string_format("%s,%03d",os.date("%X",now),select(2,math_modf(now))*1000)
   else 
      return os.date("%X", os.time()) 
   end
end
--

function event_callback_tblH(t_id, msg, par1, par2)
   if msg == QTABLE_LBUTTONDOWN then   -- нажата левая кнопка мыши
      local mes = ''
      lastPos = futures_position()
      local status = tonumber(getParamEx(classCode, secCode,"status").param_value)
      if status ~= 1 or par1 == 1 then -- если бумага не торгуется, заявку не подаем
         Highlight(t_id, par1, par2, RosyBrown, dc, 500)      -- подсветка, RosyBrown
         if status ~= 1 then
            mes = 'error cliring'
            
            message(mes); io_log(mes);
         end
         return
      end
      Highlight(t_id, par1, par2, SeaGreen, dc, 500)      -- подсветка SeaGreen
      if par1 == 2 and par2 == 1 then
         if lastPos < 0 then
            mes = secCode..'; Pressed: Buy, '..-lastPos
            Buy(classCode, secCode, -lastPos, 'CloseShort')
         elseif    lastPos == 0 then
            mes = secCode..'; Pressed: Buy, '..workSize
            Buy(classCode, secCode, workSize, 'OpenLong')
         else
            mes = secCode..'; Pressed: Buy. My v longah ne pokupaem!'
         end
      elseif par1 == 2 and par2 == 2 then   -- продать, левая кнопка
         if lastPos > 0 then
            mes = secCode..'; Pressed: Sell, '..lastPos
            Sell(classCode, secCode, lastPos, 'CloseLong')
         elseif    lastPos == 0 then
            mes = secCode..'; Pressed: Sell, '..workSize
            Sell(classCode, secCode, workSize, 'OpenShort')
         else
            mes = secCode..'; Pressed: Sell. my v shortah ne prodaem!'
         end
      elseif par1 == 2 and par2 == 3 then   -- закрыть позиции
         if lastPos > 0 then
            mes = secCode..'; Pressed: закрыть лонги, '..lastPos
            Sell(classCode, secCode, lastPos, 'CloseAll')
         elseif    lastPos < 0 then
            mes = secCode..'; Pressed: закрыть шорты, '..-lastPos
            Buy(classCode, secCode, -lastPos, 'CloseAll')
         else
            mes = secCode..'; Pressed: закрыть. No position for close!'
         end
      elseif par1 == 3 and par2 == 1 then
         if lastPos < 0 then
            mes = secCode..'; Pressed: Buy-, '..-lastPos
            BuyBid(classCode, secCode, -lastPos, 'CloseShort')
         elseif    lastPos == 0 then
            BuyBid(classCode, secCode, workSize, 'OpenLong')
            mes = secCode..'; Pressed: Buy-, '..workSize
         else
            mes = secCode..'; Pressed: Buy-. My v longah ne pokupaem!'
         end
      elseif par1 == 3 and par2 == 2 then
         if lastPos > 0 then
            SellOffer(classCode, secCode, lastPos, 'CloseLong')
            mes = secCode..'; Pressed: Sell+, '..lastPos
         elseif    lastPos == 0 then
            SellOffer(classCode, secCode, workSize, 'OpenShort')
            mes = secCode..'; Pressed: Sell+, '..workSize
         else
            mes = secCode..'; Pressed: Sell+. Мmy v shortah ne prodaem!'
         end
      elseif par1 == 3 and par2 == 3 then
         mes = secCode..'; Pressed: Remove all orders!'
         KillOrders()
      end
      message(mes); io_log(mes);
   elseif msg == QTABLE_CLOSE then
      OnStop()
   end   
end
--

QTable ={}
QTable.__index = QTable
-- Создать и инициализировать экземпляр таблицы QTable
function QTable.new()
   local t_id = AllocTable()
   if t_id ~= nil then
      q_table = {}
      setmetatable(q_table, QTable)
      q_table.t_id=t_id
      q_table.caption = ""
      q_table.created = false
      q_table.curr_col=0
      -- таблица с описанием параметров столбцов
      q_table.columns={}
      return q_table
   else
      return nil
   end
end
tblH = QTable:new() -- для ручной торговли
--

function get_trans_id()
   local s = tostring(os.clock())
   local x, g = string_find(s, "(%d+)")
   s = string_sub(s, g + 2)
   for i = 1, 3 - string_len(s) do
      s = "0" .. s
   end
   return os.date("%H%M%S") .. s
end
--
--- Функция отправки ордера
function send_order(client, class, seccode, account, operation, quantity, price)
   
   local gcp=GetPriceForMarketOrder(operation) 
   local trans_id = get_trans_id()
   local trans_params = {
      CLASSCODE = class,
      CLIENT_CODE = client,
      SECCODE = seccode,
      ACCOUNT = account,
      TYPE = new_type,
      TRANS_ID = trans_id,
      OPERATION = operation,
      QUANTITY = tostring(quantity),
      PRICE = tostring(gcp),
      ACTION = "NEW_ORDER"
      }
   return sendTransaction(trans_params)
end
--

function Buy(classCode, secCode, size, action)
   local best_offer = getParamEx(classCode, secCode, "offer").param_value
   local buyPrice = best_offer + (OpenSlippage or 0)
   local res = send_order(action, classCode, secCode, account, "B", size, buyPrice)
   if string_len(res) ~= 0 then
      local mes = 'Error: '..res..', '.. action..', '..secCode..', '.."B"..', '..size..', price='..buyPrice
      message(mes,3); io_log(mes);
   end
end
--

function Sell(classCode, secCode, size, action)
   local best_bid = getParamEx(classCode, secCode, "bid").param_value
   local sellPrice = best_bid - (OpenSlippage or 0)
   local res = send_order(action, classCode, secCode, account, "S", size, sellPrice)
   if string_len(res) ~= 0 then
      local mes = 'Error: '..res..', '.. action..', '..secCode..', '.."S"..', '..size..', price='..sellPrice
      message(mes,3); io_log(mes);
   end
end
--

function BuyBid(classCode, secCode, size, action)
   local best_bid = getParamEx(classCode, secCode, "bid").param_value
   local buyPrice = best_bid - (OpenSlippage or 0)
   local res = send_order(action, classCode, secCode, account, "B", size, buyPrice)
   if string_len(res) ~= 0 then
      local mes = 'Error: '..res..', '.. action..', '..secCode..', '.."B"..', '..size..', price='..buyPrice
      message(mes,3); io_log(mes);
   end
end
--

function SellOffer(classCode, secCode, size, action)
   local best_offer = getParamEx(classCode, secCode, "offer").param_value
   local sellPrice = best_offer + (OpenSlippage or 0)
   local res = send_order(action, classCode, secCode, account, "S", size, sellPrice)
   if string_len(res) ~= 0 then
      local mes = 'Error: '..res..', '.. action..', '..secCode..', '.."S"..', '..size..', price='..sellPrice
      message(mes,3); io_log(mes);
   end
end
--

function KillOrders()
   local NumberOf = getNumberOf("orders")
   for i = 0, NumberOf - 1 do
      local ord = getItem("orders", i)
      if ord.sec_code == secCode and ord.account == account  then
         local order_flag = get_order_status(ord.flags)
         if order_flag.status == "active" then
            trans_id = get_trans_id()
            local trans_params = {
                  ["CLASSCODE"] = classCode,
                  ["TRANS_ID"] = trans_id,
                  ["ACTION"] = "KILL_ORDER",
                  ["ORDER_KEY"] = tostring(ord.order_num)
                  }
            local res =  sendTransaction(trans_params)
            if 0 < string_len(res) then
               local mes = 'Error: '..res
               message(mes,3); io_log(mes);
            end
         end
      end
   end
end
--

function HandleBS()
   local t = tblH.t_id
   AddColumn(t, 1, 'Bumaga', true,QTABLE_CACHED_STRING_TYPE,12)
   AddColumn(t, 2, 'Tcp', true,QTABLE_STRING_TYPE,12)
   AddColumn(t, 3, 'Last price.', true,QTABLE_STRING_TYPE,17)
   CreateWindow(t)
   SetWindowCaption(t, "SuperScalp "..ver)   --SetWindowCaption(t, "Scalper:"..account)
   SetWindowPos(t, 0, 100, 250, 120)
   local li=InsertRow(t, -1)
   SetCell(t, li, 1, secCode)
   SetCell(t, li, 2, lastPos)
   SetCell(t, li, 3, '7503')   --Ожидание
   local li=InsertRow(t, -1)
   SetCell(t, li, 1, 'Buy')
   SetCell(t, li, 2, 'Sell')
   SetCell(t, li, 3, 'Close')
   local li=InsertRow(t, -1)
   SetCell(t, li, 1, 'Buy —')
   SetCell(t, li, 2, 'Sell +')
   SetCell(t, li, 3, 'Close All')
   SetTableNotificationCallback(t,event_callback_tblH)
end
--

--прочитать ТТП и вытащить ТЧП.
function futures_position()
   if is_forts then
      local count=getNumberOf("futures_client_holding") --Позиции по клиентским счетам (фьючерсы)
      for i=0,count-1, 1 do
         local row=getItem("futures_client_holding",i)
         if row.trdaccid~=nil then
            local seccode=row.sec_code      --Код фьючерсного контракта, "Инструмент"
            local totn=row.totalnet         --Текущие чистые позиции   "ТЧП"
            if seccode == secCode then
               return totn
            end
         end
      end
   else
      local t = getDepoEx(firm_id, ClientCode, secCode, account, 0)
      if t then
         local T = t.currentbal
         SetCell(tblH.t_id, 1, 2, tostring(T))
         positionColor(T)
         return T
      end
   end
   return 0
end
--

function positionColor(tot)
   if tot>0 then
      SetColor(tblH.t_id,1,2, SeaGreen, dc, dc, dc)   -- подсветка SeaGreen
   elseif tot<0 then
      SetColor(tblH.t_id,1,2, RosyBrown, dc, dc, dc)   -- подсветка, RosyBrown
   else   
      SetColor(tblH.t_id,1,2,dc, dc, dc, dc)
   end 
end
--

function get_order_status(flags)
  local rt = {}
  local band = bit.band
  local tobit = bit.tobit
  if band(tobit(flags), 1) ~= 0 and band(tobit(flags), 2) == 0 then
    rt.status = "active"
  elseif band(tobit(flags), 1) == 0 and band(tobit(flags), 2) ~= 0 then
    rt.status = "cancelled"
  elseif band(tobit(flags), 1) == 0 and band(tobit(flags), 2) == 0 then
    rt.status = "filled"
  else
    rt.status = "unknown"
  end
  if band(tobit(flags), 4) ~= 0 then
    rt.operation = "S"
  else
    rt.operation = "B"
  end
  return rt
end
--

--запись лога с текущим простым временем
function io_log(str)
   local file, err = io.open(logFile, "a")
   assert(file, "Error write "..logFile..", \n"..str)
   local str0 = getHRTime()   -- время с миллисекундами
   str0 = str0..'; '.. str
   file:write(str0 .. "\n")
   file:flush()
   file:close()
   return true
end
--

if testQuik then
   -- 2.2.17 - Функция вызывается терминалом QUIK при получении ответа на транзакцию пользователя.
   function OnTransReply(reply)
      if reply.account == account then
         if running then
            local mes =  reply.sec_code..'; OnTrans, o_n '..reply.order_num..', '..tostring(reply.price)..' x '..
            tostring(reply.quantity)..', t_id = '..reply.trans_id
            message(mes); io_log(mes);
         end
         toLog(scriptPath..'\\'..logFileName2,reply, 'reply')
      end
   end
   -- 2.2.3 Функция вызывается терминалом QUIK при получении сделки.
   function OnTrade(trade)
      if trade.account == account then   -- только если заявка из нашего счета - 01.11.2014
         if running then
            if not _trades[trade.trade_num] then
               local mes = trade.sec_code..'; OnTrade, 1, o_n = '..trade.order_num..', t_n = '..trade.trade_num..' ('..trade.price..'x'..trade.qty..')'
               message(mes); io_log(mes);
               _trades[trade.trade_num] = true  -- Добавим в очередь
               _trades[trade.tradenum] = 1
               table_insert(trades,trade)
            else   
               _trades[trade.tradenum] = _trades[trade.tradenum] + 1
               local mes = trade.sec_code..'; OnTrade, '.._trades[trade.tradenum]..', o_n = '..trade.order_num..', t_n = '..trade.trade_num..' ('..trade.price..'x'..trade.qty..')'
               message(mes); io_log(mes);
            end
            toLog(scriptPath..'\\'..logFileName2,trade, 'trade')
         end
      end
   end
   --2.2.4   OnOrder   Функция вызывается терминалом QUIK при получении новой заявки или при изменении параметров существующей заявки.
   function OnOrder(order)
      if order.account == account then
         local order_flag = get_order_status(order.flags)
         local op = order_flag.operation
         local mes = order.sec_code..'; OnOrder, '..op.. ', o_n = '..order.order_num..' ('..order.price..'x'..order.qty.."), t_id = "..order.trans_id..', flag = '..order.flags..", "..order.brokerref..", balance = "..order.balance..', '..order_flag.status
         io_log(mes)
         toLog(scriptPath..'\\'..logFileName2,order, 'order')
      end   
   end
end
--

function toLog(file_path,value,txt)
   -- запись в файл параметра value
   -- value может быть числом, строкой или таблицей
   -- file_path  -  путь к файлу
   -- файл открывается на дозапись и закрывается после записи строки
   local now = getHRTime()   -- c мс
   if file_path~=nil and value~=nil then
      local lf, err = io.open(file_path, "a")
      assert(lf, "Ошибка записи "..file_path..", \n")
      if lf~=nil then
         lf:write(txt.."\n")
         if type(value)=="string" or type(value)=="number" then
            lf:write(now.." "..value.."\n")
         elseif type(value)=='boolean' then
            lf:write(now.." "..tostring(value).."\n")
         elseif type(value)=="table" then
            lf:write(now.."\n"..table2string(val ue).."\n")
         end
         lf:flush()
         if io.type(lf)=="file" then   lf:close() end
      end
   end
end
--

function table2string(table)
   local k,v,str=0,0,""
   for k,v in pairs(table) do
      if type(v)=="string" or type(v)=="number" then
         str=str..k.."="..v..';\n'   --  в 1
         --str=str..k.."="..v..'; '   --  в 2
      elseif type(v)=="table"then
         str=str..k.."={\n"..table2string(v).."};\n"
      elseif type(v)=="function" or type(v)=='boolean' then
         str=str..k..'='..tostring(v)..';\n'
      end
   end
   return str
end
--

-- 2.2.8   OnFuturesClientHolding
-- Функция вызывается терминалом QUIK при изменении позиции по срочному рынку.
function OnFuturesClientHolding(tab)
   local sec_code = tab.sec_code
   local totalnet = tab.totalnet
   if running and sec_code == secCode then -- выбираем нужную нам бумагу
      local t= tonumber(totalnet)
      if t ~= nil then
         SetCell(tblH.t_id, 1, 2, tostring(totalnet), totalnet)
         positionColor(t)
      end
   end
end
--
-- 2.2.5  Функция вызывается терминалом QUIK при получении изменений текущей позиции по счету.
-- (ТОЛЬКО ДЛЯ БРОКЕРА).
function OnAccountBalance(acc_bal)
   if acc_bal.sec_code==secCode then
      local t= acc_bal.currentpos
      if t ~= nil then
         SetCell(tblH.t_id, 1, 2, tostring(t))
         positionColor(t)
      end
   end
end

--   2.2.18   OnParam
--   Функция вызывается терминалом QUIK при изменении текущих параметров.
function OnParam(class, seccode)
   if seccode == secCode then -- выбираем нужную нам бумагу
      local lp = tonumber(getParamEx(class, seccode, "last").param_value)
      if lp > lastPrice then
         Highlight(tblH.t_id, 1, 3, SeaGreen, dc, 1000)      -- подсветка мягкий, зеленый
         lastPrice = lp   -- цена последней сделки
         SetCell(tblH.t_id, 1, 3, tostring(lastPrice))
      elseif lp < lastPrice then
         Highlight(tblH.t_id, 1, 3, RosyBrown, dc, 1000)      -- подсветка
         lastPrice = lp
         SetCell(tblH.t_id, 1, 3, tostring(lastPrice))
      end
   end   
end
--

-- 2.2.24 OnStop
-- Функция вызывается терминалом QUIK при остановке скрипта из диалога управления и при
-- закрытии терминала QUIK.
function OnStop()
   local mes = 'Stop SuperScalp.'
   message(mes); io_log(mes);
   running = false
   DestroyTable(tblH.t_id)
end
--

-- 2.2.25 OnInit
-- Функция вызывается терминалом QUIK перед вызовом функции main().
function OnInit()
   getInitParameter()
   logFile = scriptPath..'\\'..logFileName1
   local mes = 'Start SuperScalp '..ver..', QUIK '..Terminal_Version
   message(mes); io_log(mes);
   running = true
   HandleBS()
   lastPos = futures_position()
   SetCell(tblH.t_id, 1, 2, tostring(lastPos))
   positionColor(lastPos)
end
--

-- 2.2.26 main
-- Функция, реализующая основной поток выполнения в скрипте.
function main()
   while running do
      sleep(1000)
      if not is_forts then
         local t = getDepoEx(firm_id, ClientCode, secCode, account, 0)
         local T = t.currentbal
         SetCell(tblH.t_id, 1, 2, tostring(T))
         positionColor(T)
      end
      
   end
end
C++ + Луа, Стандартные библиотеки
 
Хотелось бы писать своего робота на языке С++ но велосипед изобретать смысла думаю нет. Может есть уже готовые стандартные библиотеки с++ для работы с QUICK?
Вроде поискав нашел пару 1 - 2 проектов довольно серьезных но не похоже на стандартную библиотеку. Нет классов наследования все как то странно незначительно плохо читабельно.  
C++ или луа, На каком выборе остановится на чистом с++ или луа?
 
Цитата
s_mike@rambler.ru написал:
Думать особо не надо чем. Первый робот нужно писать на луа. После того как вы напишете десяток роботов, у вас появится (или не появится) потребность расширить возможности и вы напишете себе свои собственные расширения на на с++.

писать сразу же на с++ - дело бессмысленное - куча лишних сложностей, которые ничем не окупаются.
Ну я более менее понимаю С++ а вот луа, очень сложен для чтения.  Но lua хранит все цифры double, вроде абсолютно не рекомендуется, double переводит в int и обратно. Также куча подводных камней которых не видно. Хотелось бы услышать хотя бы основные, от господ экспертов, луа с++ строителей.  
C++ или луа, На каком выборе остановится на чистом с++ или луа?
 
Обдумываю как написать свой первый робот для терминала quick. Но вот не задача что выбрать LUA или C++. Склоняюсь писать все на С++ и регистрировать в луа функции. Хотелось бы понять минусы, создания роботов для quick на чистом С++.
Фьючесный контракт некорректные цены, EDH9 цена в стакане на данный момент 1.1306
 
Все разобрался тему можно удалить. Неплохо бы с кодом ошибки выдавать пояснения, старые советники все используют max min цены. В недоумении Человек от таких выкрутасов терминала.
Фьючесный контракт некорректные цены, EDH9 цена в стакане на данный момент 1.1306
 
Все разобрался, на смартлабе и на этом форуме, нашел информацию.
А как узнать цены для открытия сделки, для робота?
Фьючесный контракт некорректные цены, EDH9 цена в стакане на данный момент 1.1306
 
Если ордер, открывать лимитными и закрывать, то журнал сделок показывает корректно цены. Но вот стоит маркет ордер в дело пустить так тут цены совсем не корректные. Но при этом,  денежные средства отнимаются корректно, то есть в пределах спреда и нормы.  
Фьючесный контракт некорректные цены, EDH9 цена в стакане на данный момент 1.1306
 
Код
-- Приводит переданную цену к требуемому для транзакции по инструменту виду
GetCorrectPrice = function(price) -- STRING
   -- Получает точность цены по инструменту
   local scale = getSecurityInfo(CLASS_CODE, SEC_CODE).scale
   -- Получает минимальный шаг цены инструмента
   local PriceStep = tonumber(getParamEx(CLASS_CODE, SEC_CODE, "SEC_PRICE_STEP").param_value)
   -- Если после запятой должны быть цифры
   if scale > 0 then
      price = tostring(price)
      -- Ищет в числе позицию запятой, или точки
      local dot_pos = price:find('.')
      local comma_pos = price:find(',')
      -- Если передано целое число
      if dot_pos == nil and comma_pos == nil then
         -- Добавляет к числу ',' и необходимое количество нулей и возвращает результат
         price = price..','
         for i=1,scale do price = price..'0' end
         return price
      else -- передано вещественное число         
         -- Если нужно, заменяет запятую на точку 
         if comma_pos ~= nil then price:gsub(',', '.') end
         -- Округляет число до необходимого количества знаков после запятой
         price = math_round(tonumber(price), scale)
         -- Корректирует на соответствие шагу цены
         price = math_round(price/PriceStep)*PriceStep
         price = string.gsub(tostring(price),'[\.]+', ',')
         return price
      end
   else -- После запятой не должно быть цифр
      -- Корректирует на соответствие шагу цены
      price = math_round(price/PriceStep)*PriceStep
      return tostring(math.floor(price))
   end
end


Функция тоже показывает не реальные цены  
Фьючесный контракт некорректные цены, EDH9 цена в стакане на данный момент 1.1306
 
EDH9 цена в стакане на данный момент 1.1306  при покупке не лимитной заявкой то есть по рынку цены вылетают в обе стороны 1.16 и 1.09 с копейками. Это даже не в пределах спреда такие движения за месяц редко бывают.
Страницы: 1
Наверх