Мелкие утилиты и индикаторы

Страницы: 1
RSS
Мелкие утилиты и индикаторы, Может кому пригодится
 
В процессе разбирательства с АПИ написал несколько полезных для меня утилит.
Скорее всего они примитивные, но возможно кому-то понадобятся.
Или пригодятся как примеры.

Я не знаю как прицепить к сообщению аттач, поэтому воткну тут самый примитивный из индикаторов
Остальное уже большевато для вставки в текст, а как прицепить файл я не нашел.
Если кому понадобится что-нить - свистите.

Предназначен для показа всех параметров свечи в одном индикаторе, чтобы не добавлять\убирать если что-то надо.
[URL=http://radikal.ru/fp/50b20ef2e0af4ae298ceeb4ae6d04b98][IMG]http://s020.radikal.ru/i709/1502/3d/17d1f53f8d02t.jpg[/IMG][/URL];


Код
 -- ********************************************************************
-- Can displays every candle field as separate graph (see "Settings" for details)

-- ********************************************************************
-- Stupid QUIK: dofile() doesnt work in Indicators :-/
-- ********************************************************************
LOG_FILE = "..\\quick_lua.log";

function log(fmt, ... )
-- Decomment next line to allow global logging
--  _log( fmt, ... )
end

function _log( fmt, ... )
  local f = io.open( LOG_FILE, "a+" );
  if not f then
    f = io.open( LOG_FILE, "w" );
  end
  if not f then
    out( "Error write log file: %s", LOG_FILE );
    abort();
  end
  f:write( strtime(os.date("*t")) .. " " .. string.format( fmt, ... ) .. "\n" );
  f:close();
end

function out( fmt, ... )  message( string.format( fmt, ... ), 3) end
function abort(fmt, ... ) out( fmt, ... ); PROGRAMM_ABORT(); end
function iif( cond, y, n ) if cond then return y; else return n; end end
function strtime( tm ) return string.format("%4d-%02d-%02d %02d:%02d:%02d", tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec) end

-- ********************************************************************
-- ********************************************************************
Settings={
 Name = "!__Values",
 line = {
  { Name = "High",   Color = RGB( 112,112,112 ), Width = 1, Type = TYPE_LINE },
  { Name = "Low",    Color = RGB( 112,112,112 ), Width = 1, Type = TYPE_LINE },
  { Name = "Open",   Color = RGB( 112,255,255 ), Width = 1, Type = TYPE_LINE },
  { Name = "Close",  Color = RGB( 112,255,255 ), Width = 1, Type = TYPE_LINE },
  { Name = "Vol",    Color = RGB( 128,128,255 ), Width = 6, Type = TYPE_HISTOGRAM },
  { Name = "Median", Color = RGB( 100,215,0 ),   Width = 1, Type = TYPE_LINE },
  { Name = "Triple", Color = RGB( 200,67,22 ),   Width = 1, Type = TYPE_LINE },
  { Name = "Wide",   Color = RGB( 190,30,170 ),  Width = 1, Type = TYPE_LINE },
  nil
 },

 Open     = "n",    -- If set to 'y' will display candle.open graph
 Close    = "n",    -- If set to 'y' will display candle.close graph
 High     = "y",    -- If set to 'y' will display candle.high graph
 Low      = "y",    -- If set to 'y' will display candle.low graph
 Vol      = "n",    -- If set to 'y' will display candle.volume graph
 Median   = "y",    -- If set to 'y' will display calculated "median" graph
 Triple   = "n",    -- If set to 'y' will display calculated "triple" graph
 Wide     = "n",    -- If set to 'y' will display calculated "wide" graph

 Margin   = 0.01,   -- Additional bounds added to High, Low, Open and Close fields on display
                    -- Used just for better graph view
 nil
}

function Init()
    return 8
end

function OnCalculate(idx)
  local h = H(idx)
  local l = L(idx)

  if not h or h < 10 then
    return nil
  end

  if h < l then h,l = l,h; end

  local o = O(idx)
  local c = C(idx)
  if o < c then o,c = c,o; end

  local v = V(idx)
  local m = (h+l)/2
  local t = (h+l+C(idx))/3
  local w = (h+l+C(idx)*2)/4

  if Settings.Open   ~= "y" then o = nil; else o = o + Settings.Margin; end
  if Settings.Close  ~= "y" then c = nil; else c = c - Settings.Margin; end
  if Settings.High   ~= "y" then h = nil; else h = h + Settings.Margin; end
  if Settings.Low    ~= "y" then l = nil; else l = l - Settings.Margin; end
  if Settings.Vol    ~= "y" then v = nil; end
  if Settings.Median ~= "y" then m = nil; end
  if Settings.Triple ~= "y" then t = nil; end
  if Settings.Wide   ~= "y" then w = nil; end

  return h,l, o,c, v,m,t,w;
end

Вот еще один, которым постоянно пользуюсь
Предназначен за рисованием коридора для средне-взвешенного значения инструмента по всем сделкам.
Т.е. после установки сделки начинает рисовать коридор профит\лос (там на графике треугольники сделки и горизонтальные линии границы).
[URL=http://radikal.ru/fp/eb4e1ac6826140a5a48423cc46bb1377][IMG]http://s018.radikal.ru/i520/1502/39/3bb965470ed2t.jpg[/IMG][/URL];

Из утилит сделал экспорт данных свечей с графиков в CSV т.к. не смог найти средство как это сделать штатно.
И еще утилитка рассчета суммарной прибыльности по сделкам:
[URL=http://radikal.ru/fp/6f660bd4842941e7842e2ddd37026b6f][IMG]http://s010.radikal.ru/i313/1502/a2/a9d90aa9df2at.jpg[/IMG][/URL];
 
за примеры - однозначно, спасибо. но, лучше, если есть возможность, залей их на gitHUB или sourceforge.net, или сделай торрент. так сохранней будет.
 
Блин
Картинки порипались, а письма тут исправить походу невозможно.





 
а как нарисовать с помощью qlua вертикальную линию на определенной свече (которая была в определенное время)?
 
Цитата
Валентин пишет:
а как нарисовать с помощью qlua вертикальную линию на определенной свече (которая была в определенное время)?
Здравствуйте,
Через Lua можно рисовать такие линии только через механизм работы с метками
 
Если вас устроит вертикальная линия, идущая от самого низа графика до уровня, заданного определенным значением цены, то можно обойтись без меток и нарисовать ее с помощью индикатора, пример которого приведен ниже:

Код
Settings =
{
  Name = "v_line",
  line =
  {
    {
      Name = "vertical_line",
      Color = RGB(0, 255, 255),  -- 
      Type = TYPE_HISTOGRAM  -- важно задать тип "гистограмма", тогда получатся вертикальные линии
    }
  }
}

function Init()
  return 1
end

function OnCalculate(index)
  if (T(index).hour == 10) and (T(index).min == 0) then
    return H(index) + (H(index) - L(index))  -- линия идет от самого низа графика и оканчивается немного выше нужной нам свечи
  end
end

Этот индикатор будет рисовать вертикальную линию на свече, которая была в 10:00.

Чтобы вертикальная линия не перекрывала тени свечи, можно после наложения на график индикатора поменять "Порядок графиков (индикаторов)" с помощью пункта контекстное меню "Параметры текущего окна".
 
приветствую всех

подскажите пжл каким кодом сделаны вот эти горизонтальные линии
https://s.mail.ru/46gcnwqsabaj/img-2016-01-19-19-32-48.png


1) сколько штук их можно сделать на одном графике?
2) можно задать тип линии и толщину?
спасибо заранее за ответ
С Уважением
Алексей Шафиков 8-927357-5755
Управление брокерскими счетами
https://www.foresight-invest.ru/model-portfolio#blog ;
 
то есть вообще кодом qlua горизонтальная линия на определенной цене от бара до бара вообще возможна?
С Уважением
Алексей Шафиков 8-927357-5755
Управление брокерскими счетами
https://www.foresight-invest.ru/model-portfolio#blog ;
 
Цитата
Алексей Шафиков пишет:
то есть вообще кодом qlua горизонтальная линия на определенной цене от бара до бара вообще возможна?
череззаднепроходно, но да
Цитата
Алексей Шафиков пишет:
приветствую всех

подскажите пжл каким кодом сделаны вот эти горизонтальные линии
https://s.mail.ru/46gcnwqsabaj/img-2016-01-19-19-32-48.png


1) сколько штук их можно сделать на одном графике?
2) можно задать тип линии и толщину?
спасибо заранее за ответ
код - ниже
1. сколько угодно (константное число)
2. толщину - не помню, а тип - да, из набора существующих. их, если правильно помню, штук 5, в доке не описаны, но можно просто перебрать числами от 0
 
Скрипт рисующий границы:

Код
-- ********************************************************************
-- Trades graphs
-- Display bounds for every trade you made with profit and loss bounds.
-- Automatically calculate balanced $$ cost

-- Graph has 3 lines:
-- 1. Green line - 'profit' value.
--    If you overcome of this line you balance increases
-- 2. Blue line - 'zero' value.
--    At this value you trade will have zero balance
--    Note: Blue line exists only if you $$ balance nonzero.
-- 3. Red line - 'possible loss' value
--    Indicates value of acceptable loss.
--    If you overcome this line you must make a dessision to close the deal in MINUS or hope price will grows back...
-- ********************************************************************

-- ********************************************************************
-- Stupid QUIK: dofile() doesnt work in Indicators :-/
-- So we must declare all utils in a single file.
-- !!NOTES!!:
--   For use logging you must set "LOG_FILE" to correct log file name
--   For enable global logging decomment "_log" call in "log()" function below
-- ********************************************************************
LOG_FILE = "..\\quick_lua.log";

function log(fmt, ... )
-- Decomment next line to allow global logging
--  _log( fmt, ... )
end

function _log( fmt, ... )
  local f = io.open( LOG_FILE, "a+" );
  if not f then
    f = io.open( LOG_FILE, "w" );
  end
  if not f then
    out( "Error write log file: %s", LOG_FILE );
    abort();
  end
  f:write( strtime(os.date("*t")) .. " " .. string.format( fmt, ... ) .. "\n" );
  f:close();
end

function out( fmt, ... )  message( string.format( fmt, ... ), 3) end
function abort(fmt, ... ) out( fmt, ... ); PROGRAMM_ABORT(); end
function iif( cond, y, n ) if cond then return y; else return n; end end
function strtime( tm ) return string.format("%4d-%02d-%02d %02d:%02d:%02d", tm.year, tm.month, tm.day, tm.hour, tm.min, tm.sec) end

function cmptime( e, b )
  if e.year > b.year then return 1; end
  if e.year < b.year then return -1; end
  if e.month > b.month then return 1; end
  if e.month < b.month then return -1; end
  if e.day > b.day then return 1; end
  if e.day < b.day then return -1; end
  if e.hour > b.hour then return 1; end
  if e.hour < b.hour then return -1; end
  if e.min > b.min then return 1; end
  if e.min < b.min then return -1; end
  if e.sec > b.sec then return 1; end
  if e.sec < b.sec then return -1; end
  return 0;
end

-- ********************************************************************
-- Settings
-- ********************************************************************

Settings = {
 Name = "!__Trades",
 line = {
  { Name = "Balans",       Color = RGB( 4,53,106 ),  Type = 4, Width = 1 },
  { Name = "BalPositive",  Color = RGB( 47,143,7 ),  Type = 4, Width = 1 },
  { Name = "BalProtect",   Color = RGB( 244,72,70 ), Type = 4, Width = 1 },
 },

 Add_Positive   = 0.05,             -- Value addon to indicate positive balans including all trade comissions
 Add_Protect    = 0.15,             -- Possible loss value

 EmptyValue     = -1,               -- Value will be used to set in graph if you do not have open trades.
                                    -- Value of -1 indicates what value will not be stored.
 UseGraphClass  = 0,                -- If nonzero trades will use sec_code attached to graph
                                    -- If zero the USD_TOM and USD_TOD will be used simultaneous
 USD_TOM        = "USD000UTSTOM",   -- Money codes used if "UseGraphClass=0" (sec_code  STRING  Код бумаги заявки)
 USD_TOD        = "USD000000TOD",
 CLASS_CODE     = "CETS",           -- Class code used to access money code (class_code  STRING  Код класса)

 Day_StartValue = 0,                -- Starting day value
                                    -- Amount of $$ you have already at your account at start of trading day
                                    -- If zero, Trades will use first trade made as starting point.
 Day_StartPrice = 0,                -- Balance price of account $$. Useless if "Day_StartValue = 0"

 Day_LastOnly   = 1,                -- Calculate whole trades or the current day only
                                    -- If "Day_LastOnly=1" all trades in days before "Day_xxx" will be ignored

 Day_year       = 2015,             -- Current trades day (year)
 Day_mon        = 1,                -- Current trades day (month)
 Day_day        = 30,               -- Current trades day (day)
}

-- ********************************************************************
-- Local data
-- ********************************************************************
TradeTable       = {}
TradeTableLength = 0
LastTableLength  = 0
GraphCC          = "";
GraphSC          = "";
CalcStartTime    = nil

-- ********************************************************************
function Filter( cc, sc, fl )
  if Settings.UseGraphClass > 0 then
    if cc ~= GraphSC then return false; end
    if sc ~= GraphCC then return false; end
   else
    if cc ~= Settings.CLASS_CODE then return false; end
    if sc ~= Settings.USD_TOM and sc ~= Settings.USD_TOD then return false; end
  end;

  -- бит 0 (0x1)  Заявка активна, иначе - не активна
  -- бит 1 (0x2)  Заявка снята. Если флаг не установлен и значение бита <0> равно <0>, то заявка исполнена
  -- бит 2 (0x4)  Заявка на продажу, иначе - на покупку. Данный флаг для сделок и сделок для исполнения определяет направление сделки (BUY/SELL)
  if bit.band(fl,0x1) == 0x1 then return false; end
  if bit.band(fl,0x2) == 0x2 then return false; end

  return true;
end

function FillTradeTable()
  local num = getNumberOf("trades")
  if num == 0 then
    TradeTable = {};
    TradeTableLength = 0;
    LastTableLength = 0;
    return;
  end
  if num <= LastTableLength then
    return;
  end
log( "FillTradeTable %d->%d", LastTableLength, num );

  it = {}
  while LastTableLength < num do
    it = getItem( "trades", LastTableLength );
    if Filter( it.class_code, it.sec_code, it.flags ) then
      log( "add[%d]: %2d) qty: %3d, price: %3.4f, bs: %s, tm: %s",
           TradeTableLength, LastTableLength,
           it.qty,
           it.price,
           iif( bit.band(it.flags,0x04) == 0x04, "SELL", "BUY " ),
           strtime(it.datetime),
           nil );

      TradeTable[ TradeTableLength ] = {
        Count = it.qty,
        Price = it.price,
        Sell  = iif( bit.band(it.flags,0x04) == 0x04, true, false ),
        Time  = it.datetime,
      }
      TradeTableLength = TradeTableLength + 1;
    end
    LastTableLength = LastTableLength+1;
  end

log( "Added %d items (%d)", TradeTableLength, LastTableLength );
end

function CalcValue( tm )
  if cmptime( CalcStartTime, tm ) > 0 then
    return 0,0;
  end

  local n
  local hdr = false
  local vol   = Settings.Day_StartValue
  local price = Settings.Day_StartPrice

  for n=0,TradeTableLength-1 do
    it = TradeTable[n];
    if it == nil then return 0,0; end;
    if cmptime( it.Time, tm ) > 0 then
      break;
    end;

--  if not hdr then log( "CalcValue[%s]", strtime(tm) ); hdr = true; end

    cn = iif( it.Sell, -it.Count, it.Count );
    oldv = vol

    vol = vol + cn
    if vol ~= 0 then
      price = price*oldv/vol + it.Price*cn/vol;
     else
      price = it.Price;
    end;

--log( "time [%s] %d / %3.4f = %3d / %3.4f", strtime(it.Time), iif(it.Sell,-it.Count,it.Count), it.Price, vol, price );
  end

  return price, vol;
end

function OnCalculate(idx)

  if GraphCC == "" then
    ds = getDataSourceInfo();
    GraphCC = ds.sec_code;
    GraphSC = ds.class_code;
log( "Init codes: cc: %s, sc: %s", ds.class_code, ds.sec_code );
    if GraphCC == "" or GraphSC == "" then
      message( string.format("Invalid CC/SC: [%s]/[%s]", GraphCC, GraphSC) );
      GraphCC = "-";
      return nil;
    end
  end
  if GraphCC == "" or GraphSC == "" then
    return nil;
  end

  if not CalcStartTime then
    if Settings.Day_LastOnly then
      CalcStartTime = { year = Settings.Day_year, month = Settings.Day_mon, day = Settings.Day_day, hour = 10, min = 0, sec = 0 };
     else
      CalcStartTime = T(idx)
    end
  end

  FillTradeTable();

  price, vol = CalcValue( T(idx) );

  if vol == 0 and price == 0 then
    if Settings.EmptyValue < 0 then
      return nil;
     else
      return Settings.EmptyValue,Settings.EmptyValue,Settings.EmptyValue;
    end
   elseif vol == 0 then
    return nil,
           price-Settings.Add_Positive,
           price+Settings.Add_Protect;
   else
    return price,
           iif( vol > 0, price+Settings.Add_Positive, price-Settings.Add_Positive ),
           iif( vol > 0, price-Settings.Add_Protect, price+Settings.Add_Protect );
  end
end

function Init()
  return 3
end

-- For test run as std script
function main()
  FillTradeTable();
  tm = { year = 2015, month = 1, day = 30, hour = 16, min = 0, sec = 0 };
  price, vol = CalcValue( tm );
  log( "price: %3.4f, vol: %d", price, vol );
end

 
 
это штриховая линия, тип 4 .
толщину можно менять.
 
Чтобы не рисовалась переходы с горизонтальных участков надо в самом квике установить тип графика то ли в гистограму то ли еще что-то подобное
Не помню уже
 
вопрос тако
с помощью данного решения я допустим реализую индикатор который будет рисовать аналоги баз из 4-5 баров
и это все на 35 графиках - будет ли все это тормозить или нормально работать
почему спрашиваю - сделал просто поиск баз с выводом в текстовое окно в атф транзак - когда 1-4 графика обсчитывает вроде еще ничего - но как 10-15 жуткие тормоза!
С Уважением
Алексей Шафиков 8-927357-5755
Управление брокерскими счетами
https://www.foresight-invest.ru/model-portfolio#blog ;
 
А возможно ли на Lua нарисовать динамический POC, который будет
отрисовывать максимальный объём.
Например на 1,3240 прошёл объём 300, индикатор рисует линию и рисует её до тех пор пока на определенном уровне не появиться больший объём, например 1,3250   400.
Вот пример. И не будет ли после добавления индикатора тормозить график...?

 
Цитата
AndrejNaMillion пишет:
А возможно ли на Lua нарисовать динамический POC, который будет
отрисовывать максимальный объём.
Например на 1,3240 прошёл объём 300, индикатор рисует линию и рисует её до тех пор пока на определенном уровне не появиться больший объём, например 1,3250 400.
Вот пример. И не будет ли после добавления индикатора тормозить график...?
Можно. Тормозить не будет.
 
Цитата
Дмитрий написал:
Если вас устроит вертикальная линия, идущая от самого низа графика до уровня, заданного определенным значением цены, то можно обойтись без меток и нарисовать ее с помощью индикатора, пример которого приведен ниже:

Код
  Settings  = 
{
  Name  =   "v_line" ,
  line  = 
  {
    {
      Name  =   "vertical_line" ,
      Color  =   RGB ( 0 ,  255 ,  255 ),   --  
      Type  =  TYPE_HISTOGRAM   -- важно задать тип "гистограмма", тогда получатся вертикальные линии 
    }
  }
}

 function   Init ()
   return   1 
 end 

 function   OnCalculate (index)
   if  (T(index).hour  =  =   10 )  and  (T(index).min  =  =   0 )  then 
     return  H(index)  +  (H(index)  -  L(index))   -- линия идет от самого низа графика и оканчивается немного выше нужной нам свечи 
   end 
 end 
  

Этот индикатор будет рисовать вертикальную линию на свече, которая была в 10:00.

Чтобы вертикальная линия не перекрывала тени свечи, можно после наложения на график индикатора поменять "Порядок графиков (индикаторов)" с помощью пункта контекстное меню "Параметры текущего окна".
Доброго дня.
Подскажите, а есть возможность настраивать время отображения индикатора.?
Скажем нужно отметить новости в 15:30, 16:30, 21:00. как это сделать что бы прописать сразу?
 
Цитата
RayIntraday написал:
Подскажите, а есть возможность настраивать время отображения индикатора.?Скажем нужно отметить новости в 15:30, 16:30, 21:00. как это сделать что бы прописать сразу?
Добавьте внутри кода индикатора анализ времени свечи, чтобы он рисовался только на свечах с заданным временем, а в остальных случаях возвращал значение nil
Страницы: 1
Читают тему (гостей: 1)
Наверх