Роман
Роман личный блог
23 августа 2017, 14:44

Таблица "Портфель" в QUIKе


    Представляю таблицу для портфельных инвестиций. В квике до сих пор такого нет. Цвет строки меняется если Прибыль%<>5%. Обновление каждые 5 сек.
Таблица "Портфель" в QUIKе

Для её создания необходимо:
1. Создать файл «tablePortfolio.txt» в папке «C:\QUIK\Scripts». Если папки нет, создать её.
2. Скопировать туда код скрипта
3. Сохранить, выбрав кодировку «ANSI», иначе вместо русских букв могут быть кракозябры.
4. Сменить расширение файла с ".txt" на ".lua"
5. Запустить скрипт командой Сервисы->Lua  скрипты->Добавить (выбрать файл tablePortfolio.lua) ->Запустить

Код скрипта:
IsRun = true
class_code="TQBR"

function main()
   -- Получает доступный id для создания
   t_id = AllocTable()   
   
   -- добавить столбцы
   AddColumn(t_id, 1, "Бумага",       true, QTABLE_STRING_TYPE, 20)
   AddColumn(t_id, 2, "Кол-во",       true, QTABLE_INT_TYPE,     7)
   AddColumn(t_id, 3, "Цена покупки", true, QTABLE_DOUBLE_TYPE, 14)
   AddColumn(t_id, 4, "Цена текущая", true, QTABLE_DOUBLE_TYPE,   14)
   AddColumn(t_id, 5, "Прибыль, р",   true, QTABLE_DOUBLE_TYPE,   14)
   AddColumn(t_id, 6, "Прибыль, %",   true, QTABLE_DOUBLE_TYPE, 14)
   t = CreateWindow(t_id)

   for iRow=1, getNumberOf("depo_limits")-1, 1 do
      rowInPortfolioTable = getItem("depo_limits", iRow) -- получить текущую строку из таблицы "Лимиты по бумагам"            
      qtyBoughtLots  = tonumber(rowInPortfolioTable.currentbal)         
      limitKind = rowInPortfolioTable.limit_kind          
      if qtyBoughtLots>0 and limitKind<1 then      
         InsertRow(t_id, iRow)-- добавить новую строку вниз таблицы   
      end
   end
   local rows, columns = GetTableSize (t_id)
   InsertRow(t_id, rows+1) -- добавить новую строку вниз таблицы для "Итого"
   
   SetWindowCaption(t_id, "Портфель: прибыли и убытки    © [email protected]") 

   -- исполнять цикл, пока пользователь не остановит скрипт или не закроет окно таблицы
   while IsRun do 
      if IsWindowClosed(t_id)==true then
         IsRun=false
      end

      local currentPrice=0
      local qtyBoughtLots=0
      local profitAbs = 0
      local profitPerc = 0
      local currentSecCode= ""
      local fullNameOfInstrument = ""
      local limitKind = 0
      local rowInPortfolioTable = {}    -- строка из таблицы "Лимиты по бумагам"
      local tableInstrument = {}    -- данные "Таблицы текущих торгов"
      local iRowInOutTable = 1
	  local totalInvest = 0
	  local totalPortfolio = 0
	  local totalProfit = 0
	  local totalPercent = 0

      for iRow=0, getNumberOf("depo_limits")-1, 1 do
         rowInPortfolioTable = getItem("depo_limits", iRow) -- получить текущую строку из таблицы "Лимиты по бумагам"         
         
         qtyBoughtLots  = tonumber(rowInPortfolioTable.currentbal)
         
         limitKind = rowInPortfolioTable.limit_kind 
         
         if qtyBoughtLots>0 and limitKind<1    then      -- если кол-во лотов >0 и тип лимита T0
            currentSecCode = rowInPortfolioTable.sec_code
            fullNameOfInstrument =  tostring(getParamEx(class_code, currentSecCode, "SHORTNAME").param_image or "0") --"LONGNAME"
            avgPrice       = tonumber(rowInPortfolioTable.awg_position_price)                  
            currentPrice = GetAskPrice(currentSecCode)   
            profitAbs = (currentPrice-avgPrice)*qtyBoughtLots      
            profitPerc    = 100*currentPrice/avgPrice   - 100
			
			totalInvest = totalInvest + avgPrice*qtyBoughtLots  
			totalPortfolio = totalPortfolio + currentPrice*qtyBoughtLots   
            
            SetCell(t_id, iRowInOutTable, 1, fullNameOfInstrument) -- "Бумага"
            SetCell(t_id, iRowInOutTable, 2, tostring(qtyBoughtLots)) -- "Кол-во"RemoveZero(tostring(qtyBoughtLots)))
            SetCell(t_id, iRowInOutTable, 3, tostring( math_round(avgPrice, 3) ))  -- tostring(avgPrice))   -- "Цена покупки"
            SetCell(t_id, iRowInOutTable, 4, RemoveZero(tostring(currentPrice)))   -- "Цена текущая"
            SetCell(t_id, iRowInOutTable, 5, tostring( math_round( profitAbs, 0)) ) -- "Прибыль, р"
            SetCell(t_id, iRowInOutTable, 6, tostring(math_round(profitPerc, 1)) .."%") -- "Прибыль, %"
            
            if profitPerc >5 then       -- окрашиваем
               ColourRowInGreen(iRowInOutTable)
            elseif profitPerc<-5 then 
               ColourRowInRed(iRowInOutTable)
            else 
               ColourRowInYellow(iRowInOutTable)
            end   
            iRowInOutTable = iRowInOutTable+1
         end
      end
      totalProfit = totalPortfolio - totalInvest 
      totalPercent   = 100*totalProfit/totalInvest  
	  SetCell(t_id, iRowInOutTable, 1, "Итого") 
      SetCell(t_id, iRowInOutTable, 3, tostring( math_round(totalInvest, 0) ))  
      SetCell(t_id, iRowInOutTable, 4, tostring( math_round(totalPortfolio, 0)))  
      SetCell(t_id, iRowInOutTable, 5, tostring( math_round( totalProfit, 0)) ) 
      SetCell(t_id, iRowInOutTable, 6, tostring(math_round(totalPercent, 1)) .."%") 
	  
	  if profitPerc >5 then       -- окрашиваем
               ColourRowInGreen(iRowInOutTable)
            elseif profitPerc<-5 then 
               ColourRowInRed(iRowInOutTable)
            else 
               ColourRowInYellow(iRowInOutTable)
            end   
            iRowInOutTable = iRowInOutTable+1
      sleep(5000) -- пауза 5 сек.
      end
   --message("script table portfolio finished")
end


function ColourRowInRed(num_row)
   SetColor(t_id, num_row, QTABLE_NO_INDEX, RGB(255,150,150), RGB(0,0,0), RGB(255,150,150), RGB(0,0,0))
end
function ColourRowInYellow(num_row)
   SetColor(t_id, num_row, QTABLE_NO_INDEX, RGB(255,255,200), RGB(0,0,0), RGB(255,255,200), RGB(0,0,0))
end
function ColourRowInGreen(num_row)
   SetColor(t_id, num_row, QTABLE_NO_INDEX, RGB(150,255,150), RGB(0,0,0), RGB(150,255,150), RGB(0,0,0))
end
function GetAskPrice(inp_Sec_Code )
   local ask = tostring(getParamEx(class_code, inp_Sec_Code, "OFFER").param_value or 0)
   return ask
end
-- Округляет число до указанной точности
function math_round (num, idp)
   local mult = 10^(idp or 0)
   return math.floor(num * mult + 0.5) / mult
end
-- удаление точки и нулей после нее
function RemoveZero(str)
   while (string.sub(str,-1) == "0" and str ~= "0") do
      str = string.sub(str,1,-2)
   end
   if (string.sub(str,-1) == ".") then 
      str = string.sub(str,1,-2)
   end   
   return str
end
function OnStop()
   DestroyTable(t_id)
   IsRun = false   
end
19 Комментариев
  • qwerty
    23 августа 2017, 14:58
    Спасибо!
      • qwerty
        24 августа 2017, 11:42
        Роман, Сегодня только включил терминал, что бы опробовать Ваш скрипт. Всё работает отлично, только изменил на Т2.
        А можно ли как нибудь прикрутить ещё фьючерсы, они у меня тоже в «долгосрок», было бы очень удобно видеть всё в процентах.
        Ещё раз спасибо!
  • Орехов Вячеслав
    23 августа 2017, 15:23
    Классная штучка, жалко акциями бросил заниматься.
  • sstroh
    23 августа 2017, 15:31
    Спасибо, а как поменять количество бумаг Т0 на Т2?
  • KarL$oH
    23 августа 2017, 15:50
    Красава! Спасибо.
  • френк френков
    23 августа 2017, 16:09
    Спасибо.
    Торговать с неё можно.
    Меньше пяти стоп, больше стоп продвинуть?
    Модерново
  • Григорий
    23 августа 2017, 16:50
    есть такое в квике-таблица «состояние счета». Но есть возможность улучшить: выводите прибыль не только полную, но и за текущий день, чтобы можно было понять за счет чего переоценился портфель.
  • В. Н.
    23 августа 2017, 18:43
    не работает ((



  • doc42
    24 августа 2017, 04:45
    Спасибо!
  • Вяткин Александр
    24 августа 2017, 10:26
    Собрал Вашу таблицу.Работает реально.Спасибо клево! Только по иис показывает убыток в 100%
  • Oleg
    24 августа 2017, 14:33
    Спасибо! все работает!
  • Андрей Шадрин
    06 февраля 2019, 17:04
    С облигациями не работает
  • Ramil Shahattudinov
    15 сентября 2022, 12:29
    С современными реалиями, что-то в этих скриптах работает не так.



    Первая таблица с жёлтым полем это самый первый верхний скрипт, нижняя таблица с зелёным полем, это скрипт доработанный автором, приведён в комментах. Как бы одно и тоже, но не совсем. Может кто знает, где закралась ошибка?
  • Андрей
    20 сентября 2022, 20:18
    присоединяюсь, можно как то убрать задублирование строк и предусмотерть тот факт что есть еще позиции по акциям в шорт?
  • Андрей
    20 сентября 2022, 20:36

    IsRun = true
    class_code = «TQBR»
    class_code2 = «TQTF»

    function main()
    — Получает доступный id для создания
    t_id = AllocTable()

    — добавить столбцы
    AddColumn(t_id, 1, «Бумага», true, QTABLE_STRING_TYPE, 20)
    AddColumn(t_id, 2, «Кол-во», true, QTABLE_INT_TYPE, 7)
    AddColumn(t_id, 3, «Цена покупки», true, QTABLE_DOUBLE_TYPE, 14)
    AddColumn(t_id, 4, «Цена текущая», true, QTABLE_DOUBLE_TYPE, 14)
    AddColumn(t_id, 5, «Прибыль, р», true, QTABLE_INT_TYPE, 14)
    AddColumn(t_id, 6, «Прибыль, %», true, QTABLE_INT_TYPE, 14)
    t = CreateWindow(t_id)

    for iRow=1, getNumberOf(«depo_limits»)-1, 1 do
    rowInPortfolioTable = getItem(«depo_limits», iRow) — получить текущую строку из таблицы «Лимиты по бумагам»
    qtyBoughtLots = tonumber(rowInPortfolioTable.currentbal)
    limitKind = rowInPortfolioTable.limit_kind
    if qtyBoughtLots~=0 and limitKind>2 then
    InsertRow(t_id, iRow)-- добавить новую строку вниз таблицы
    end
    end
    local rows, columns = GetTableSize (t_id)
    InsertRow(t_id, rows+1) — добавить новую строку вниз таблицы для «Итого»

    SetWindowCaption(t_id, «Портфель: прибыли и убытки»)

    — исполнять цикл, пока пользователь не остановит скрипт или не закроет окно таблицы
    while IsRun do


    local currentPrice=0
    local qtyBoughtLots=0
    local profitAbs = 0
    local profitPerc = 0
    local currentSecCode= ""
    local fullNameOfInstrument = ""
    local limitKind = 0
    local rowInPortfolioTable = {} — строка из таблицы «Лимиты по бумагам»
    local tableInstrument = {} — данные «Таблицы текущих торгов»
    local iRowInOutTable = 1
    local totalInvest = 0
    local totalPortfolio = 0
    local totalProfit = 0
    local totalPercent = 0

    for iRow=0, getNumberOf(«depo_limits»)-1, 1 do
    rowInPortfolioTable = getItem(«depo_limits», iRow) — получить текущую строку из таблицы «Лимиты по бумагам»

    qtyBoughtLots = tonumber(rowInPortfolioTable.currentbal)

    limitKind = rowInPortfolioTable.limit_kind

    if qtyBoughtLots~=0 and limitKind>2 then — если кол-во лотов >0 и тип лимита T0
    currentSecCode = rowInPortfolioTable.sec_code
    fullNameOfInstrument = tostring(getParamEx(class_code, currentSecCode, «SHORTNAME»).param_image ) --«LONGNAME» or
    if fullNameOfInstrument == "" then
    fullNameOfInstrument = currentSecCode or «0»
    end
    avgPrice = tonumber(rowInPortfolioTable.awg_position_price)
    currentPrice = GetAskPrice(currentSecCode)
    profitAbs = (currentPrice-avgPrice)*qtyBoughtLots
    profitPerc = 100*currentPrice/avgPrice — 100

    totalInvest = totalInvest + avgPrice*qtyBoughtLots
    totalPortfolio = totalPortfolio + currentPrice*qtyBoughtLots

    SetCell(t_id, iRowInOutTable, 1, fullNameOfInstrument) — «Бумага»
    SetCell(t_id, iRowInOutTable, 2, RemoveZero(tostring(qtyBoughtLots))) — «Кол-во»RemoveZero(tostring(qtyBoughtLots)))
    SetCell(t_id, iRowInOutTable, 3, RemoveZero(tostring( math_round(avgPrice, 3) ))) — tostring(avgPrice)) — «Цена покупки»
    SetCell(t_id, iRowInOutTable, 4, RemoveZero(tostring(currentPrice))) — «Цена текущая»
    SetCell(t_id, iRowInOutTable, 5, RemoveZero(tostring( math_round( profitAbs, 0)) )) — «Прибыль, р»
    SetCell(t_id, iRowInOutTable, 6, tostring(math_round(profitPerc, 1)) .."%") — «Прибыль, %»

    if profitPerc >5 then — окрашиваем
    ColourRowInGreen(iRowInOutTable)
    elseif profitPerc<-5 then
    ColourRowInRed(iRowInOutTable)
    else
    ColourRowInYellow(iRowInOutTable)
    end
    iRowInOutTable = iRowInOutTable+1
    end
    end
    totalProfit = totalPortfolio — totalInvest
    totalPercent = 100*totalProfit/totalInvest
    SetCell(t_id, iRowInOutTable, 1, «Итого»)
    SetCell(t_id, iRowInOutTable, 3, tostring( math_round(totalInvest, 0) ))
    SetCell(t_id, iRowInOutTable, 4, tostring( math_round(totalPortfolio, 0)))
    SetCell(t_id, iRowInOutTable, 5, tostring( math_round( totalProfit, 0)) )
    SetCell(t_id, iRowInOutTable, 6, tostring(math_round(totalPercent, 1)) .."%")

    if profitPerc >5 then — окрашиваем
    ColourRowInGreen(iRowInOutTable)
    elseif profitPerc<-5 then
    ColourRowInRed(iRowInOutTable)
    else
    ColourRowInYellow(iRowInOutTable)
    end
    iRowInOutTable = iRowInOutTable+1
    sleep(5000) — пауза 5 сек.
    if IsWindowClosed(t_id) then isRun = false end
    end
    --message(«script table portfolio finished»)

    end


    function ColourRowInRed(num_row)
    SetColor(t_id, num_row, QTABLE_NO_INDEX, RGB(255,150,150), RGB(0,0,0), RGB(255,150,150), RGB(0,0,0))
    end
    function ColourRowInYellow(num_row)
    SetColor(t_id, num_row, QTABLE_NO_INDEX, RGB(255,255,200), RGB(0,0,0), RGB(255,255,200), RGB(0,0,0))
    end
    function ColourRowInGreen(num_row)
    SetColor(t_id, num_row, QTABLE_NO_INDEX, RGB(150,255,150), RGB(0,0,0), RGB(150,255,150), RGB(0,0,0))
    end
    function GetAskPrice(inp_Sec_Code )
    local ask = tostring(getParamEx(class_code, inp_Sec_Code, «LAST»).param_value or getParamEx(class_code2, inp_Sec_Code, «OFFER»).param_value or 0) — «OFFER
    if tonumber(ask) == 0 then
    ask = tostring(getParamEx(class_code2, inp_Sec_Code, „LAST“).param_value or 0)
    end
    return ask
    end
    — Округляет число до указанной точности
    function math_round (num, idp)
    local mult = 10^(idp or 0)
    return math.floor(num * mult + 0.5) / mult
    end
    — удаление точки и нулей после нее
    function RemoveZero(input)
    local str = tostring(input)

    --if str:find(»%.")==nil and str:find(",")==nil then
    if not str:find("%.") and not str:find(",") then
    return str
    end

    while (string.sub(str,-1) == «0» and str ~= «0») do
    str = string.sub(str,1,-2)
    end
    if (string.sub(str,-1) == ".") then
    str = string.sub(str,1,-2)
    end
    if (string.sub(str,-1) == ",") then
    str = string.sub(str,1,-2)
    end

    return str
    end
    function OnStop()
    DestroyTable(t_id)
    IsRun = false
    end



    может кому пригодится, сделал только Т2 и теперь отображаются и короткие позиции
    • Ramil Shahattudinov
      05 января 2023, 18:26
      Андрей, немного не так считает %, я так понял от входа в сделку он считает как 100%, а дальше как идёт движение в твою сторону уменьшает %.



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

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