Отображение на графике индикатора из другого графика

Автор записи: Sergey

Понадобилось мне видеть на 5-и минутном графике индикатор из другого окна. Вот написал свой индикатор, который загружает данные из любого графика, беря его данные по уникальному идентификатору в QUIK.

Чтобы этот индикатор смог найти искомый индикатор, зайдите в свойства этого индикатора, перейдите на закладку Дополнительно, и в поле Идентификатор укажите уникальное имя этого индикатора. В моем случае это "B4H_20_2" (без кавычек).

Сам файл кода нужно положить в папку QUIK, в поддиректорию "LuaIndicators". Если его нет, то создайте.  После этого при добавлении нового индикатора вы увидите его в общем списке.

Вот код, у меня он назван BBfromOtherPeriod_common.lua :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
-- по умолчанию берет значения болинов из графика 4 часа
-- график должен называться "B_20_2" (в настройках исходного индикатора нужно зайти в поле дополнительно и там указать имя индикатора)
 
-- для получения данных с других графиков, можно создать вызывающий файл из 4х строк в коротом
-- присвоить начальные параметры
-- ======= начало файла (строки надо раскоментировать) ==========
-- Color = RGB(255, 128, 64) -- оранжевый цвет
-- Width = 3
-- NameAndSource = "B_20_2"
-- и вызовом главного
-- dofile (getWorkingFolder().."\\LuaIndicators\\BBfromOtherPeriod_common.lua")
-- ======= конец файла ==========
 
if Color == nil then
   Color = RGB(255, 128, 64) -- оранжевый
end
if Width == nil then
   Width = 3
end
if NameAndSource == nil then
   NameAndSource = "B4H_20_2"
end
 
Settings = {
   Name = NameAndSource,
   line = {{
         Name = NameAndSource.."_c",
         Type = TYPE_LINE,
         Color = Color,
         Width = Width
      },
      {
         Name = NameAndSource.."_h",
         Type = TYPE_LINE,
         Color = Color,
         Width = Width
      },
      {
         Name = NameAndSource.."_l",
         Type = TYPE_LINE,
         Color = Color,
         Width = Width
      }
   }
}
 
function datetimeToSec2(datetime)
   return datetime.year*31104000 + (datetime.month-1)*2592000 + (datetime.day-1) * 86400 + datetime.hour * 3600 + datetime.min * 60
end
 
function toYYYY_MM_DD(DateTime,OtkudaZapusk)
   if type(DateTime) ~= 'table' then
      message("в функцию toYYYY_MM_DD передано неверно значение даты "..tostring(DateTime).. " / "..tostring(OtkudaZapusk))
      return ""
   else
      if otladka_toYYYY_MM_DD then message("toYYYY_MM_DD из ",OtkudaZapusk) end
      local Res = tostring(DateTime.year);
      Res = Res.."/"
      local month = tostring(DateTime.month);
      if #month == 1 then Res = Res.."0"..month; else Res = Res..month; end;
      Res = Res.."/"
      local day = tostring(DateTime.day);
      if #day == 1 then Res = Res.."0"..day; else Res = Res..day; end;
      return Res;
   end
end --toYYYY_MM_DD
 
function toHH_MM(DateTime)
   if type(DateTime) ~= 'table' then
      message("в функцию toHH_MM передано неверно значение даты "..tostring(DateTime))
      return ""
   else
      local Res = ""
      local hour = tostring(DateTime.hour)
      if #hour == 1 then Res = Res.."0"..hour; else Res = Res..hour; end
      Res = Res..":"
      local minute = tostring(DateTime.min)
      if #minute == 1 then Res = Res.."0"..minute; else Res = Res..minute; end
      return Res
   end
end
 
function toYYYY_MM_DD_HH_MM(DateTime)
   return toYYYY_MM_DD(DateTime).." "..toHH_MM(DateTime)
end
 
function SavePeremToFile (name, znach) -- возвращает массив всех данных
   local Lines = {}
 
   local level = 0
   local function Rec(a)
      local first = true
      level = level + 1
      local s = '' for i=1,level do s = ' '..s end
      for key, val in pairs(a) do
         if not first then Lines[#Lines] = Lines[#Lines]..',' end
         local k = '[\''..key..'\']'
         if type(key) == 'number' then k = '['..key..']' end
         if type(val) ~= 'table' then
            if type(val) == 'string' then
               val = '\''..val..'\''
            else
               val = tostring(val)
            end
            table.insert(Lines, s..k..'='..val)
            first = false
         else
            table.insert(Lines, s..k..'={')
            first = false
            Rec(val)
            table.insert(Lines, s..'}')
            level = level - 1
         end
      end
   end
 
   -- message("type(znach)="..tostring(type(znach)))
   -- если параметр текстовый, но можно преобразовать в число, то преобразует в число
   if type(znach) == "string" then
      local znach_tmp = tonumber(znach)
      if znach_tmp ~= nil then
         znach = znach_tmp
      end
   end
 
   if type(znach) == "string" then
      table.insert(Lines, name ..' = \"'..znach.."\"")
   elseif type(znach) == "table" then
      -- Lines = TableToArray(znach)
      table.insert(Lines, name.." = {")
      Rec(znach)
      table.insert(Lines, '}')
   else
      table.insert(Lines, name ..' = '..tostring(znach))
   end
 
   local f = io.open(getScriptPath()..'\\params'..NameAndSource, 'w')
   for i=1,#Lines do
      f:write(Lines[i]..'\n')
      f:flush()
   end
   f:close()
   return Lines
end --SavePeremToFile
 
function LoadPeremFromFile ()
   local FPath = getScriptPath()..'\\params'..NameAndSource
   local func, err = loadfile(FPath)
   -- message("err="..tostring(err))
   -- если файл нормально прочитан
   if err == nil then
      if not func then
         message('Ошибка загрузки таблицы из файла: '..err)
         return nil
      else
         return func()
      end
   -- если ошибка чтения из файла
   else
      message("LoadPeremFromFile: не найден файл "..FPath)
   end
end --LoadPeremFromFile
 
function Init()
   message ("Init индикатор "..Settings.Name)
   local source = Settings.Name
   local B_size_now = getNumCandles(source)
   B_20_c, B_20_max_n, l = getCandlesByIndex (source, 0, 0, B_size_now);
   if B_20_max_n == nil or B_20_max_n == 0 then
      message ("Не найден график с меткой, из которого надо брать данные: "..source)
      return
   else
      message ("Подключен к крафику с меткой: "..source)
      message("Есть данные "..tostring(B_20_max_n).." свечей")
      return #Settings.line
   end
end
 
function OnCalculate(index)
   -- if index > 3000 then
   -- if index > 2500 then
   local loking_time = T(index)
   local seconds_which_loking = datetimeToSec2(loking_time)
   local source = Settings.Name
   local B_size_now = getNumCandles(source)
   local B_20_2_h, B_20_max_n, l = getCandlesByIndex (source, 1, 0, B_size_now);
   local B_20_2_l, B_20_max_n, l = getCandlesByIndex (source, 2, 0, B_size_now);
   local B_20_c, B_20_max_n, l = getCandlesByIndex (source, 0, 0, B_size_now);
   local B_20_max_n = B_20_max_n-1
   -- message("при index="..index.." ищем "..tostring(toYYYY_MM_DD_HH_MM(loking_time)))
   -- message("B_20_max_n="..tostring(B_20_max_n))
   -- message(" B_20_c[0]="..toYYYY_MM_DD_HH_MM(B_20_c[0].datetime))
   -- message(" B_20_c[1]="..toYYYY_MM_DD_HH_MM(B_20_c[1].datetime))
   -- message("B_20_c["..B_20_max_n.."]="..toYYYY_MM_DD_HH_MM(B_20_c[B_20_max_n].datetime))
   -- LoadPeremFromFile ()
 
   -- message("finded_interval перед поиском с прошлого раза ="..tostring(finded_interval))
   if finded_interval ~= nil then
      n = finded_interval
      -- если пересекли начало следующего большого интервала, то передвигаем вперед на него
      if seconds_of_next_interval <= seconds_which_loking and finded_interval < B_20_max_n then
         n = finded_interval + 1
      else
         n = finded_interval
      end
   else
      n = B_20_max_n
   end
 
   while n >= 0 and datetimeToSec2(B_20_c[n].datetime) > seconds_which_loking do
      -- message("пропустил B_20_c["..n.."]="..toYYYY_MM_DD_HH_MM(B_20_c[n].datetime).." т.к. ищу"..seconds_which_loking.." а сейчас "..datetimeToSec2(B_20_c[n].datetime))
      n = n - 1
   end
   finded_interval = n
   if finded_interval < B_20_max_n then
      seconds_of_next_interval = datetimeToSec2(B_20_c[finded_interval+1].datetime)
   end
 
   -- message("при index="..index.." ищем "..tostring(toYYYY_MM_DD_HH_MM(loking_time)).." найден B_20_c["..finded_interval.."]="..toYYYY_MM_DD_HH_MM(B_20_c[finded_interval].datetime).." знач."..tostring(B_20_c[finded_interval].open))
   return B_20_c[finded_interval].open, B_20_2_h[finded_interval].open, B_20_2_l[finded_interval].open
   -- else
   -- return nil, nil, nil
   -- end
end