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

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

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 82 След.
Совершить сделку по цене открытия бара, Как выставить заявку, не зная цену?
 
нажимаете мышкой на открытие свечи .
открывается окно выставления заявки с ценой открытия. с количеством по умолчанию.
MoveOrder - цену меняет, а объем не меняет. Что это., Пытаюсь использовать стандартные возможности функции. Не меняется объем. На новую позицию заявка переезжает.
 
Цитата
Михаил Понамаренко написал:
first_order_new_quantity=1.0
может количество задано не в том формате?
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Код
function OnStop (signal)
   if t_id then DestroyTable (t_id) end -- Завершение!
    StopFlag = true
  return 1000 -- Тайм-аут 1 сек вместо стандартных 5
end

function Create (caption, rowNum, cols)
   t_id = AllocTable()
  for i = 1, #cols do         -- name       *    type       width
    assert (1==AddColumn (t_id,i,cols[i][1],true,cols[i][2],cols[i][3])
      ,string.format ("%2d %s %s %s", i, tostring(cols[i][1])
        ,tostring (cols[i][2]), tostring (cols[i][3])))
  end -- * false - all cells invisible
  assert (1 == CreateWindow (t_id))
  assert (SetWindowCaption (t_id, caption))
  local top, left, bottom, right = GetWindowRect (t_id)
  local totalWidth = right - left + 10 -- Эмпирика |
  local frameHeight = 60                      --"- |
  local rowHeight   = 20                      --"- |
  for i = 1, rowNum do
    local row = InsertRow (t_id, -1)
    assert (row == i)
    assert (SetCell (t_id, row, 1, "row".. i))
    for j = 2, #cols do
      local val = i * 10 + j
      assert (SetCell (t_id, row, j, tostring(val), val))
    end
  end
  assert (SetWindowPos (t_id, left, top
    ,totalWidth, frameHeight + rowHeight * rowNum))
end -- Cre ate ()

 function main()
  local rowNum = 2
  local cols = {
    {"Column1", QTABLE_STRING_TYPE, 10,}
   ,{"Column2", QTABLE_INT_TYPE,    10,}
   ,{"Column3", QTABLE_DOUBLE_TYPE, 10,}
  }
 while StopFlag==nil do
  if t_id==nil then Create ("Caption", rowNum, cols) end
    sleep (10)
   end
end -- main()
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Рекомендую сделать так:
Код
function OnStop (signal)
   if t_id then DestroyTable (t_id) end -- Завершение!
    StopFlag = true
  return 1000 -- Тайм-аут 1 сек вместо стандартных 5
end

function Create (caption, rowNum, cols)
  local rowNum = 2
  local cols = {
    {"Column1", QTABLE_STRING_TYPE, 10,}
   ,{"Column2", QTABLE_INT_TYPE,    10,}
   ,{"Column3", QTABLE_DOUBLE_TYPE, 10,}
  }
  t_id = AllocTable()
  for i = 1, #cols do         -- name       *    type       width
    assert (1==AddColumn (t_id,i,cols[i][1],true,cols[i][2],cols[i][3])
      ,string.format ("%2d %s %s %s", i, tostring(cols[i][1])
        ,tostring (cols[i][2]), tostring (cols[i][3])))
  end -- * false - all cells invisible
  assert (1 == CreateWindow (t_id))
  assert (SetWindowCaption (t_id, caption))
  local top, left, bottom, right = GetWindowRect (t_id)
  local totalWidth = right - left + 10 -- Эмпирика |
  local frameHeight = 60                      --"- |
  local rowHeight   = 20                      --"- |
  for i = 1, rowNum do
    local row = InsertRow (t_id, -1)
    assert (row == i)
    assert (SetCell (t_id, row, 1, "row".. i))
    for j = 2, #cols do
      local val = i * 10 + j
      assert (SetCell (t_id, row, j, tostring(val), val))
    end
  end
  assert (SetWindowPos (t_id, left, top
    ,totalWidth, frameHeight + rowHeight * rowNum))
end -- Cre ate ()

 function main()
  if t_id==nil then Create ("Caption", rowNum, cols) end
  while StopFlag==nil do  sleep (10) end
end -- main()
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
пардон, еще исправление:
Код
function OnStop (signal)
   message ("Destroying ".. t_id)
   if DestroyTable (t_id) then -- Завершение!
        message ("Destroying success ".. t_id)
      else
        message ("Destroying failed ".. t_id)
    end
    StopFlag = true
  return 1000 -- Тайм-аут 1 сек вместо стандартных 5
end

function Create (caption, rowNum, cols)
  t_id = AllocTable()
  for i = 1, #cols do         -- name       *    type       width
    assert (1==AddColumn (t_id,i,cols[i][1],true,cols[i][2],cols[i][3])
      ,string.format ("%2d %s %s %s", i, tostring(cols[i][1])
        ,tostring (cols[i][2]), tostring (cols[i][3])))
  end -- * false - all cells invisible
  assert (1 == CreateWindow (t_id))
  assert (SetWindowCaption (t_id, caption))
  local top, left, bottom, right = GetWindowRect (t_id)
  local totalWidth = right - left + 10 -- Эмпирика |
  local frameHeight = 60                      --"- |
  local rowHeight   = 20                      --"- |
  for i = 1, rowNum do
    local row = InsertRow (t_id, -1)
    assert (row == i)
    assert (SetCell (t_id, row, 1, "row".. i))
    for j = 2, #cols do
      local val = i * 10 + j
      assert (SetCell (t_id, row, j, tostring(val), val))
    end
  end
  assert (SetWindowPos (t_id, left, top
    ,totalWidth, frameHeight + rowHeight * rowNum))
  return t_id
end -- Cre ate ()

 function main()
  local rowNum = 2
  local cols = {
    {"Column1", QTABLE_STRING_TYPE, 10,}
   ,{"Column2", QTABLE_INT_TYPE,    10,}
   ,{"Column3", QTABLE_DOUBLE_TYPE, 10,}
  }
  t_id = Create ("Caption", rowNum, cols)
  while not IsWindowClosed (t_id) do
    sleep (10)
  end -- while
end -- main()
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Разобрался
Исправил скрипт так:
Код
function OnStop (signal)
   message ("Destroying ".. t_id)
   if DestroyTable (t_id) then -- Завершение!
        message ("Destroying success ".. t_id)
      else
        message ("Destroying failed ".. t_id)
    end
    StopFlag = true
  return 1000 -- Тайм-аут 1 сек вместо стандартных 5
end

function Create (caption, rowNum, cols)
  local t_id = AllocTable()
  for i = 1, #cols do         -- name       *    type       width
    assert (1==AddColumn (t_id,i,cols[i][1],true,cols[i][2],cols[i][3])
      ,string.format ("%2d %s %s %s", i, tostring(cols[i][1])
        ,tostring (cols[i][2]), tostring (cols[i][3])))
  end -- * false - all cells invisible
  assert (1 == CreateWindow (t_id))
  assert (SetWindowCaption (t_id, caption))
  local top, left, bottom, right = GetWindowRect (t_id)
  local totalWidth = right - left + 10 -- Эмпирика |
  local frameHeight = 60                      --"- |
  local rowHeight   = 20                      --"- |
  for i = 1, rowNum do
    local row = InsertRow (t_id, -1)
    assert (row == i)
    assert (SetCell (t_id, row, 1, "row".. i))
    for j = 2, #cols do
      local val = i * 10 + j
      assert (SetCell (t_id, row, j, tostring(val), val))
    end
  end
  assert (SetWindowPos (t_id, left, top
    ,totalWidth, frameHeight + rowHeight * rowNum))
  return t_id
end -- Cre ate ()

 function main()
  local rowNum = 2
  local cols = {
    {"Column1", QTABLE_STRING_TYPE, 10,}
   ,{"Column2", QTABLE_INT_TYPE,    10,}
   ,{"Column3", QTABLE_DOUBLE_TYPE, 10,}
  }
  t_id = Create ("Caption", rowNum, cols)
  while not IsWindowClosed (t_id) do
    sleep (10)
  end -- while
end -- main()
Все работает нормально.
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
Ростислав Дм. Кудряшов написал:
Версия Quik 12.5.0.20. Код скрипта
Код
   function  OnStop (signal)
  StopFlag  =   true 
   return   1000   -- Тайм-аут 1 сек вместо стандартных 5 
 end 

 function  Create (caption, rowNum, cols)
   local  t_id  =   AllocTable ()
   for  i  =   1 ,  # cols  do           -- name       *    type       width   
    assert ( 1  =  =  AddColumn  (t_id,i,cols[i][ 1 ], true ,cols[i][ 2 ],cols[i][ 3 ])
      ,string.format ( "%2d %s %s %s" , i, tostring(cols[i][ 1 ])
        ,tostring (cols[i][ 2 ]), tostring (cols[i][ 3 ])))
   end   -- * false - all cells invisible 
  assert ( 1   =  =   CreateWindow  (t_id))
  assert ( SetWindowCaption  (t_id, caption))
   local  top, left, bottom, right  =   GetWindowRect  (t_id)
   local  totalWidth  =  right  -  left  +   10   -- Эмпирика | 
   local  frameHeight  =   60                        --"- | 
   local  rowHeight    =   20                        --"- | 
   for  i  =   1 , rowNum  do 
     local  row  =   InsertRow  (t_id,  -  1 )
    assert (row  =  =  i)
    assert ( SetCell  (t_id, row,  1 ,  "row"  ..  i))
     for  j  =   2 ,  # cols  do 
       local  val  =  i  *   10   +  j
      assert ( SetCell  (t_id, row, j, tostring(val), val))
     end 
   end 
  assert ( SetWindowPos  (t_id, left, top
    ,totalWidth, frameHeight  +  rowHeight  *  rowNum))
   return  t_id
 end   -- Cre ate () 

  function   main ()
   local  rowNum  =   2 
   local  cols  =  {
    {"Column1", QTABLE_STRING_TYPE,  10 ,}
   ,{"Column2", QTABLE_INT_TYPE,     10 ,}
   ,{"Column3", QTABLE_DOUBLE_TYPE,  10 ,}
  }
   local  t_id  =  Create ( "Caption" , rowNum, cols)
   while   not   IsWindowClosed  (t_id)  do 
     if  StopFlag  then 
       message  ( "Destroying "  ..  t_id)
       if   DestroyTable  (t_id)  then   -- Завершение! 
         message  ( "Destroying success "  ..  t_id)
       else 
         message  ( "Destroying failed "  ..  t_id)
       end 
       break 
     end 
     sleep  ( 10 )
   end   -- while 
 end   -- main() 

  
---


не удалось повторить , скрипт закрывает окно.
что не так?
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
TGB написал:
1.  
Цитата
nikolz написал:
Полагаю, что не так.
    Зачем полагать, когда можно проверить. Переставьте DestroyTable в OnStop.

2.  
Цитата
nikolz написал:
Функция  DestroyTable  в данном примере вызывается в потоке Main.
   Вы точно знаете как устроена DestroyTable?
    Не точно, но скорее всего, это реализовано следующим образом.
    При том, что DestroyTable вызывается в main, она не лезет в таблицы QUIK, а создает коллбек закрытия таблицы, который обрабатывается  в потоке терминала, но он занят более интересным делом  :: : остановкой скрипта (удаляет поток main и перестает обрабатывать коллбеки, созданные в нем, так как исчезнет контекст их выполнения).
Что-то у Вас не то.  Колбек не создается в процессе исполнения. Колбек - это код функции , он создан при загрузке программы.
Если он вызывается в main то вызов это и есть исполнение.
Не работает getDataSourceInfo в индикаторе
 
Цитата
Nikolay написал:
Только учитывайте, что этот подход рассчитан на то, что будет вызван OnCalculate для индекса 1. Что в большинстве случаев верно, конечно. Но, судя по сему - не гарантировано. Но предпочитаю более надежный подход через инициализацию переменных в замыкании и проверке первого вызова для любого индекса.  
Можете доказать, что i может не быть равным 1 ?
Учитывая то, что при старте OnCallulate вызывается два раза. И i==1 будет обязательно.
Как на графике накапливаются данные параметров инструмента?, Как на графике накапливаются данные параметров инструмента?
 
Цитата
Digit Service написал:
Цитата
Egor Zaytsev написал:

На график должен быть добавлен соответствующий параметр, график должен быть открыт. Открыли график, данные начнут накапливаться локально.
Странно. А еще есть какой либо способ накапливания истории параметров кроме как открыть график и активным его держать весь день?

А если инструментов 10 или 50? Я правильно понял что нахождение всех этих 50 инструментов в Таблице торгов или Таблице параметров без открытого по каждому из них графика не приведет к обновлению и накоплению данных по необходимым параметрам инструментов? Я правильно понял что для того чтобы Квик сохранил параметры за день я должен в конце дня тапать и пройти по всем инструментам мышью и загрузить каждый инструмент на график то есть все руками прогрузить?

Почему Квик в настройках не позволяет это сделать и обновлять нарезки параметров (не цены и объема, а именно добавленных в таблицу параметров - средневзвешенной цены, открытого интереса, общего спроса) по всем необходимым таймфреймам исходя из Таблицы торгов или таблицы параметров автоматически?

Ну то есть я правильно понял, что сейчас если параметр не находится на активном графике но присутствует в Таблицах, то он вообще не обновляется и не накапливается таким образом?
Историю свечей можно получаю с биржи .
https://www.moex.com/a2193
Считывал их  за период с 2015 по н в. На тайме 1 мин это чуть больше 1 млн. свечей на инструмент.
Бесплатно данные в реальном времени придут с задержкой 15 минут  
Не работает getDataSourceInfo в индикаторе
 
Цитата
Андрей написал:
Пишу индикатор. Для целей его использования нужен sec_code.
Для его получения использую getDataSourceInfo, но она возвращает все значения пустыми, кроме интервала. его возвращает корректно.
Что делать? как получить sec_code?

function Init()
local info = getDataSourceInfo()
for key, val in pairs(info) do
   message("Индикатор запущен для: " .. tostring(key).."/"..tostring(val))
end
   return #Settings.line        -- Количество линий совпадает с числом элементов в массиве line
end
получаю его вот так уже ...надцать лет и без проблем:
---------------
Код
function OnCalculate(i)
if i==1 then
    tinfo=getDataSourceInfo();
    clas=tinfo.class_code;
    sec=tinfo.sec_code; 
     interval=tinfo.interval;
end
--.....
end

Как на графике накапливаются данные параметров инструмента?, Как на графике накапливаются данные параметров инструмента?
 
Все параметры, кроме истории свечей,  на компе существуют лишь для текущей торговой сессии.
Свечи накапливаются в каталоге arhve.
На сервере хранится лишь 3000 свечей
На компе свечи накапливаются пока не перезагрузите данные.
Чтобы параметры накапливались в течении сессии надо их указать в настройках .
DestroyTable (и Clear) закрывает скрипт вместо таблицы, Тема описана в Названии и в Тексте сообщения
 
Цитата
TGB написал:
Цитата
Ростислав Дм. Кудряшов написал:
В каком потоке  управления выполняется вызов функции DestroyTable()
   Работа с таблицами QUIK выполняется в служебном потоке, отличном от main. В том же, в котором выполняется OnStop. И пока выполняется  OnStop никакие операции с таблицами QUIK не возможны (поток работы с таблицами занят OnStop ). OnStop в любом случае завершает скрипт, поэтому DestroyTable не выполнена и созданная в скрипте таблица существует после завершения скрипта.
  Если что то надо делать с таблицами по кнопке завершить, то это надо делать в функции OnStop.
Полагаю, что не так.
--------------------
Поток, если не создается специально для функции, определяется местом вызова.
----------------------
Все колбеки ( в том числе ОnStop ) вызываются в основном потоке VMLua (т е в потоке терминала).
---------------------------
Функция  DestroyTable  в данном примере вызывается в потоке Main.
Неккоректная работа CreateDataSourse
 
Цитата
Nikolay написал:
Не думаю, что проблема в этом. Банально ошибка при вызове:

CreateDataSource (STRING class_code, STRING sec_code, NUMBER interval, [, STRING param])

Третий параметр - это число. "INTERVAL_H1" - это строка.

INTERVAL_H1 (без кавычек) - это константа = 60

Лучше использовать просто числа, а не константы из qlua.
Согласен.
слона то я и не приметил.
Код
while db==nil do db = CreateDataSource("TQBR", "SBER",INTERVAL_H1)  sleep(10); end


Неккоректная работа CreateDataSourse
 
Цитата
Serchk написал:
--Друзья, пишу функцию для рассчета ATR, возникли вопросы, подскажите пожалуйста.
--Создаю DB
local db = CreateDataSource("TQBR", "SBER", "INTERVAL_H1")
local a = db:Size()
--И переменная a при запуске постоянно возвращает nil значение
можете сделать так:
Код
while db==nil do db = CreateDataSource("TQBR", "SBER", "INTERVAL_H1")  sleep(10); end

OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Цитата
Александр М написал:
Цитата
nikolz написал:
 Александр М  ,
Если написать не можете, не важно по какой причине, верните человеку деньги и признайтесь, что не умеете.
Я выше представил полный минимальный код, который воспроизводит проблему с барами, с картинками результата. Зачем тут спорить, если есть открытый код и картинки, причем тут конечный скрипт?
Если вы так уверены в своем скрипте, то выложите или пришлите, я на нем проверю, воспроизводится проблема или нет.
Я вообще-то про скрипт, который вы продали Роману и который не работает.
-----------------------
Бары это или нет из Вашего теста не ясно, так как нет кода скрипта.
----------------------
Сделайте Роману работающий скрипт.
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Александр М,
Если написать не можете, не важно по какой причине, верните человеку деньги и признайтесь, что не умеете.
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Александр М,
Вы продали Роману не работающий скрипт. Вместо того, чтобы переписать его, Вы переводите стрелки на QUIK.
--------------------
Я написал Роману скрипт, который делает ровно тоже самое, что и Ваш и никуда не вываливается.
------------------------
Из беседы с романом предположу,
что Вы еще и ошибаетесь в самом алгоритме построения индикаторов с большим периодом на меньших интервалах.  
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Цитата
Александр М написал:
Цитата
nikolz написал:
   
Цитата
Александр М  написал:
 
Цитата
 nikolz   написал:
 
теперь добавим открытый интерес

 
ничего не ломается
  Проблема НЕ в индикаторе, который рисует линию с графика бОльшего таймфрейма. Вы неправильно поняли Романа.

Индикатору. у которого проблема не нужен другой график, он на текущем ТФ рассчитывает бары бОльшего ТФ и по ним считает МА. А сама проблема в функции SetValue, которая перерисовывает крайний час (с его начала) в текущем времени при любом изменении текущей цены, т.к. какого .... при обновлении ОИ видимо идет пересчет всего графика и подставляется номер бара начала часа из прошлого и дальше не обновляется. В коде ошибки нет, там все прозрачно, час сменился - номер бара запомнился. При нажатии ПРИМЕНИТЬ в настройках индикатора, все сразу становится нормально.
 Я все понzл.
Написал индикатор ровно  такой же, которому  не нужен другой график, он на текущем ТФ рассчитывает бары бОльшего ТФ и по ним считает МА.
и ничего не ломает.
Свой скрипт отправил Роману.  
Скрипт ничего не ломает, это ОИ ломает нумерацию баров в функции OnCalculate и это не лечится. у меня такие же красивые картинки, как у вас, достаточно нажать 1 раз ПРИМЕНИТЬ.

Вот картинки с номерами баров ДО ПРИМЕНИТЬ и ПОСЛЕ ПРИМЕНИТЬ. Там где 2 числа - это день сменился на графике.

Т.е. в данном примере OnCalculate вызвался на баре 3194, а потом сразу на 3449
Есл у вас скрипт не ломается то в чем проблема.
У Романа ваш скрипт не работает когда он добавляет график открытого интереса.
------------------------
Я ничего не понял из вашего рассказа про нумерацию.  У меня такой проблемы нет и не было.
-------------------
Так как проблема лишь у Вас то причина не в КВИКЕ, а в Вашем написании скрипта.  
Multiframe MA, Добавьте индикатор
 
Добавил параметры дня( открытие закрытие, локальные максимум и минимум дня)

Два варианта использования графического пакета IUP (Lua 5.4) в QUIKе
 
Корутина в луа - это функция, для которой создается отдельный state.  
Поэтому при выходе из корутины стейт не занимается другими функциями,
а следовательно состояние корутины сохраняется и ее выполнение можно продолжить там, где вышли.
---------------------  
Но так как корутина выполняется в потоке VMLua,
то она выполняется последовательно как и обычные функции луа.
Multiframe MA, Добавьте индикатор
 
Индикатор на Lua отображает на графике с интервалом 1 мин
три графика с интервалами 60,30 и 10 минут.  (интервалы можно настроить)
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 


OI ломает данные индикатора, OI ломает данные индикатора
 
Написал ровно такой же , но который ничего не ломает.
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Цитата
Цитата
Александр М написал:
Цитата
nikolz написал:
 
теперь добавим открытый интерес

 
ничего не ломается
Проблема НЕ в индикаторе, который рисует линию с графика бОльшего таймфрейма. Вы неправильно поняли Романа.

Индикатору. у которого проблема не нужен другой график, он на текущем ТФ рассчитывает бары бОльшего ТФ и по ним считает МА. А сама проблема в функции SetValue, которая перерисовывает крайний час (с его начала) в текущем времени при любом изменении текущей цены, т.к. какого .... при обновлении ОИ видимо идет пересчет всего графика и подставляется номер бара начала часа из прошлого и дальше не обновляется. В коде ошибки нет, там все прозрачно, час сменился - номер бара запомнился. При нажатии ПРИМЕНИТЬ в настройках индикатора, все сразу становится нормально.
Я все понzл.
Написал индикатор ровно  такой же, которому  не нужен другой график, он на текущем ТФ рассчитывает бары бОльшего ТФ и по ним считает МА.
и ничего не ломает.
Свой скрипт отправил Роману.  
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 

теперь добавим открытый интерес


ничего не ломается
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Вот результат тестового скрипта.  Индикатор может быть любой из встроенных в QUIK.

OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
 Возможно напишу скрипт,
который позволяет любой индикатор с большим интервалом отобразить
на графике цены с меньшим интервалом.
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Цитата
Roman Koledin написал:
ПРОСТО напишите бабки заплочу - дайте отрытый код  
Будет время ,  напишу , покажу здесь результат.  
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
пардон, не правильно понял.  
На меньшем интервале рисуется индикатор с большего интервала. Верно?
OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора, OI ломает данные индикатора
 
Сомневаюсь, что виноват QUIK.
Но без текста индикатора сложно сказать где ошибка автора.
Правильно понимаю, что Вы хотите на графике с интервалом 1 час отобразить мувинг с интервалом 1 минута?
Потом добавляете график OI с интервалом 1 минута на этот же график с интервалом 1 час?  
индикатор на Lua
 
Индикатор определяет максимум и минимум на заданном периоде и отображает среднее значение.
Алгоритм оптимизировал для ускорения вычислений.
Выкладываю для всех желающих:
Код
Settings = {Name = "*Kijun-sen",kijun_period = 6,}

function OnCalculate(i)
   Hi=H(i) or H1; Li=L(i) or L1; x1=x;
   if i1>i then
      ma=Hi; mi=Li; jma=i; jmi=i;
   end
   if Hi and Li then
      local j=i-Settings.kijun_period; if j<1 then j=1; end
      if j>jma or j>jmi then
         ma=Hi; mi=Li; jma=i; jmi=i;
         while i>j do
            Hi,Li=H(j),L(j)
            if Hi and Hi>ma then ma = Hi jma=j; end
            if Li and Li<mi then  mi =Li jmi=j;end
            j=j+1
         end
      else
         if Hi>ma then ma=Hi; jma=i; end
         if mi>Li then mi=Li; jmi=i; end
      end
      x=(ma + mi)/2;    H1,L1,i1=Hi,Li,i;
   end
return x1
end

function OnChangeSettings()
   i1=0;jma=0; jmi=0; H1=0; L1=0;ma=0;mi=0;
end

function Init()
OnChangeSettings()
Settings.line = {{ Name=Settings.Name, Color=RGB(32,255,128), Type=TYPE_LINE, Width = 2,}}
return #Settings.line  end
это мой вариант модификации этого алгоритма .  
Код
Settings = {Name = "*ind_nk",period = 6,}

function OnCalculate(i)
   Hi=H(i) or H1; Li=L(i) or L1;
   Oi=O(i) or O1; Ci=C(i) or C1;
   if i1>i then
      ma=Hi; mi=Li; jma=i; jmi=i;
   end
   if Hi and Li and i1~=i then

      local j=i-Settings.period; if j<1 then j=1; end
      if j>jma or j>jmi then
         ma=Hi; mi=Li; jma=i; jmi=i;
         while i>j do
            Hi,Li=H(j),L(j)
            if Hi and Hi>ma then ma = Hi jma=j; end
            if Li and Li<mi then  mi =Li jmi=j;end
            j=j+1
         end
      else
         if Hi>ma then ma=Hi; jma=i; end
         if mi>Li then mi=Li; jmi=i;
         end
         if x then
            local z=2*Li-Hi; if Li>x and Ci>Oi then mi=z; jmi=i; end
            z=2*Hi-Li; if x>Hi and Oi>Ci then ma=z; jma=i; end
         end
      end
      if ma and mi then x=(ma + mi)/2; end
      H1,L1,O1,C1,i1=Hi,Li,Oi,Ci,i;
   end
return x
end

function OnChangeSettings()
   i1=0;jma=0; jmi=0; H1=0; L1=0;ma=0;mi=0;
end

function Init()
OnChangeSettings()
Settings.line = {{ Name=Settings.Name, Color=RGB(255,255,255), Type=TYPE_LINE, Width = 2,}}
return #Settings.line  end
Если нравится, можете сказать "спасибо".
Ошибка при поиске пиков\впадин кастом индикатора
 
Оптимизировал алгоритм вычислений, чтобы считал быстрее.
Выкладываю для всех желающих:
Код
Settings = {Name = "*Kijun-sen",kijun_period = 6,}

function OnCalculate(i)
   Hi=H(i) or H1; Li=L(i) or L1; x1=x;
   if i1>i then
      ma=Hi; mi=Li; jma=i; jmi=i;
   end
   if Hi and Li then
      local j=i-Settings.kijun_period; if j<1 then j=1; end
      if j>jma or j>jmi then
         ma=Hi; mi=Li; jma=i; jmi=i;
         while i>j do
            Hi,Li=H(j),L(j)
            if Hi and Hi>ma then ma = Hi jma=j; end
            if Li and Li<mi then  mi =Li jmi=j;end
            j=j+1
         end
      else
         if Hi>ma then ma=Hi; jma=i; end
         if mi>Li then mi=Li; jmi=i; end
      end
      x=(ma + mi)/2;    H1,L1,i1=Hi,Li,i;
   end
return x1
end

function OnChangeSettings()
   i1=0;jma=0; jmi=0; H1=0; L1=0;ma=0;mi=0;
end

function Init()
OnChangeSettings()
Settings.line = {{ Name=Settings.Name, Color=RGB(32,255,128), Type=TYPE_LINE, Width = 2,}}
return #Settings.line  end
Если нравится, можете сказать "спасибо".
Ошибка при поиске пиков\впадин кастом индикатора
 
пардон,
последний вариант считает иначе, поэтому остается этот:
Код
Settings = {
   Name = "*Kijun-sen",
    kijun_period = 15,
   line = {{
       Name = "Kijun-sen",
       Color = RGB(255,255,255),
       Type = TYPE_LINE,
       Width = 2,
   }}
}

function Init()  return 1  end

function OnCalculate(i)
   local Hi,Li=H(i),L(i);
   if Hi and Li then
      local j=i-Settings.kijun_period; if j<1 then j=1; end
      max=Hi; min=Li;
      while i>j do
         Hi,Li=H(j),L(j)
         if Hi and Hi>max then max = Hi  end
         if Li and Li<min then  min =Li end
      j=j+1 end
      x=(max + min)/2;
   end
return x
end
Ошибка при поиске пиков\впадин кастом индикатора
 
Оптимизированный вариант обычный, считает тоже самое, но быстрее:
Код
Settings = {
   Name = "*Kijun-sen",
    kijun_period = 15,
   line = {{
       Name = "Kijun-sen",
       Color = RGB(255,255,255),
       Type = TYPE_LINE,
       Width = 2,
   }}
}

function Init()  return 1  end

function OnCalculate(i)
   local Hi,Li=H(i),L(i);
   if Hi and Li then
      if max==nil then max=Hi end
      if min==nil then min=Li end
      if Hi>max or min>Li then
      local j=i-Settings.kijun_period; if j<1 then j=1; end
         max=Hi; min=Li;
         while i>j do
            local Hj,Lj=H(j),L(j)
            if Hj and Hj>max then max = Hj  end
            if Lj and Lj<min then  min =Lj end
         j=j+1 end
      end
      x=(max + min)/2;
   end
return x;
end
Ошибка при поиске пиков\впадин кастом индикатора
 
Это вариант как в задании:
Код
Settings = {
   Name = "*Kijun-sen",
    kijun_period = 26,  -- Период Kijun-sen (можно изменить)
   line = {{
       Name = "Kijun-sen",
       Color = RGB(0,255,255),
       Type = TYPE_LINE,
       Width = 2,
   }}
}

function Init()  return 1 end

function OnCalculate(i)
   if H(i) and L(i) then
      local j=i-Settings.kijun_period; if j<1 then j=1; end
      max=H(i); min=L(i);
      while i>j do
         local H,L=H(j),L(j)
         if H and H>max then max = H  end
         if L and L<min then  min =L end
      j=j+1 end
      return (max + min)/2;
   end
end
Ошибка при поиске пиков\впадин кастом индикатора
 
попробуйте так (проверил)
Код
Settings = {
   Name = "*Kijun-sen",
    kijun_period = 26,  -- Период Kijun-sen (можно изменить)
   line = {{
       Name = "Kijun-sen",
       Color = RGB(0, 0, 255),
       Type = TYPE_LINE,
       Width = 2,
   }}
}

function Init()  return 1 end

function OnCalculate(i)
   high = H(i) low = L(i)
   if high and low then
      if i==1 then
         max = H(1)  min = L(1)
      else
      if i%Settings.kijun_period==0 then  max = high; min =low end
      if high > max then max = high  end
      if low < min then  min = low    end
   return (max + min)/2;
      end
   end
end
Ошибка при поиске пиков\впадин кастом индикатора
 
исправит ошибку надо так:
Код
Settings = {
   Name = "*Kijun-sen",
   kijun_period = 26,  -- Период Kijun-sen (можно изменить)
   line = {{
       Name = "Kijun-sen",
       Color = RGB(0, 0, 255),
       Type = TYPE_LINE,
       Width = 2,

   }}
}
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
TGB написал:
Цитата
nikolz написал:
попробуйте так:
  Вы проверяли то, что предлагаете?
1. В строке
Цитата
nikolz написал:
if i%Settings.kijun_period==0 then  max_high = H(i); min_low = L(i) end
ошибка, так как Settings.kijun_period = nil.
2. Вместо скользящей вами предлагается "прыгающая" :: . Начальные значения каждого периода берутся в качестве экстремумов. Но может быть вы предлагаете свой прыгающий индикатор?
-----------
   Ниже выложен код реализации индикатора Kijun-sen приблизительно в 3,5 раза более эффективный по времени выполнения, чем то, что выложил Roman Koledin:
Код
  Settings  =  {
   Name  =   "*Kijun-sen_opt" ,
   kijun_period  =   26 ,   -- Период Kijun-sen (можно изменить) 
   line  =  {{
       Name  =   "Kijun-sen_opt" ,
       Color  =   RGB ( 0 ,  0 ,  200 ),
       Type  =  TYPE_LINE,
       Width  =   2 
   }}
}

 function   Init ()   return   1   end 

 local  kijun_period  =  Settings.kijun_period

 function   OnChangeSettings ()
   kijun_period  =  Settings.kijun_period 
 end 
 --- 
 local  TT
 local  N_C  =   500 
 function   OnCalculate (index)
 -- -- Вычисление времени обработки свеч -- 
 -- if index == kijun_period + 1 then 
    -- TT = os.clock() 
 -- end 
 -- if index == N_C + kijun_period then 
    -- message('Kijun-sen. Время обработки ' .. N_C .. ' свечей (млс.) = ' .. (os.clock() - TT) * 1000) 
 -- end 
    if  index =  =  1   then 
      max_high  =  H( 1 )
      min_low  =  L( 1 )
    else 
      current_high  =  H(index)
      current_low  =  L(index)
       -------- 
       if  current_high  >  max_high  then    -- Пришел максимальный 
         max_high  =  current_high
       else 
          if  index  >  kijun_period  then 
             --  Ушел из скользящего периода максимальный -- 
             if  H(index  -  kijun_period)  >  =  max_high  then   -- поиск максимального 
               max_high  =  current_high
                for  j  =  index  -  kijun_period  +   1 , index  -   1   do 
                  current_high  =  H(j)
                   if  current_high  >  max_high  then  max_high  =  current_high  end 
                end 
             end 
          end 
       end 
       --- 
       if  current_low  <  min_low  then    -- Пришел минимальный 
         min_low  =  current_low
       else 
          if  index  >  kijun_period  then 
             --  Ушел из скользящего периода минимальный -- 
             if  L(index  -  kijun_period)  <  =  min_low  then   -- поиск минимального 
               min_low  =  current_low
                for  j  =  index  -  kijun_period  +   1 , index  -   1   do 
                  current_low  =  L(j)
                   if  current_low  <  min_low  then  min_low  =  current_low  end 
                end 
             end 
          end 
       end 
    end 
    return  (max_high  +  min_low) /  2 
 end 
  
нет не проверял. Да именно прыгающий. Я же написал - попробуйте это. Как другой вариант, который работает быстрее.
Ошибка при поиске пиков\впадин кастом индикатора
 
Цитата
Roman Koledin написал:
простите таже проблема можете помочь её исправить
вод код


Settings = {
   Name = "*Kijun-sen",
   line = {{
       Name = "Kijun-sen",
       Color = RGB(0, 0, 255),
       Type = TYPE_LINE,
       Width = 2
   }}
}

function Init()
   return 1
end

local kijun_period = 26  -- Период Kijun-sen (можно изменить)

function OnCalculate(index)
   -- Проверяем, достаточно ли данных для расчета
   if index < kijun_period - 1 then
       return nil
   end
   
   -- Инициализация переменных для экстремумов
   local max_high = H(index - kijun_period + 1)
   local min_low = L(index - kijun_period + 1)
   
   -- Поиск максимума и минимума за период
   for i = index - kijun_period + 2, index do
       local current_high = H(i)
       local current_low = L(i)
       
       if current_high > max_high then
           max_high = current_high
       end
       
       if current_low < min_low then
           min_low = current_low
       end
   end
   
   -- Расчет Kijun-sen
   return (max_high + min_low) / 2
end
попробуйте так:
Код
Settings = {
   Name = "*Kijun-sen",
   line = {{
       Name = "Kijun-sen",
       Color = RGB(0, 0, 255),
       Type = TYPE_LINE,
       Width = 2,
      kijun_period = 26  -- Период Kijun-sen (можно изменить)
   }}
}

function Init()  return 1 end

function OnCalculate(i)
   if i==1 then
      max_high = H(1)
       min_low = L(1)
   else
   if i%Settings.kijun_period==0 then  max_high = H(i); min_low = L(i) end
      current_high = H(i)
       current_low = L(i)
   -- Поиск максимума и минимума за период
      if current_high > max_high then max_high = current_high  end
      if current_low < min_low then  min_low = current_low     end
   -- Расчет Kijun-sen
   end
   return (max_high + min_low) / 2
end
помогите написать kijun-sen line lua QUIK
 
Цитата
Roman Koledin написал:
Спасибо за ответ ---- НО - Вот что квик сообщает ------- C:\QUIK_SBER\LuaIndicators\Kijun-sen.lua:24: attempt to call a nil value (global 'High')
https://forum.quik.ru/messages/forum17/message79562/topic9257/?result=reply#message79562
Скрипты от ИИ
 
Вот что ответил ИИ:
-------------------
Вы правы, в скрипте действительно есть ошибки. В языке Lua, который используется для индикаторов в торговых платформах (например, QUIK), для доступа к ценовым данным нужно использовать специальные функции:
  • High(i) → H(i)
  • Low(i) → L(i)
  • Open(i) → O(i)
  • Close(i) → C(i)

Исправленный код индикатора:

Settings = {
   Name = "*Kijun-sen",
   line = {{
       Name = "Kijun-sen",
       Color = RGB(0, 0, 255),
       Type = TYPE_LINE,
       Width = 2
   }}
}

function Init()
   return 1
end

local kijun_period = 26    -- Период Kijun-sen (можно изменить)

function OnCalculate(index)
   -- Проверяем, достаточно ли данных для расчета
   if index < kijun_period - 1 then
       return nil
   end
   
   -- Инициализация переменных для экстремумов
   local max_high = H(index - kijun_period + 1)
   local min_low = L(index - kijun_period + 1)
   
   -- Поиск максимума и минимума за период
   for i = index - kijun_period + 2, index do
       local current_high = H(i)
       local current_low = L(i)
       
       if current_high > max_high then
           max_high = current_high
       end
       
       if current_low < min_low then
           min_low = current_low
       end
   end
помогите написать kijun-sen line lua QUIK
 
https://forum.quik.ru/messages/forum17/message79543/topic9257/?result=reply#message79543
Скрипты от ИИ
 
Вариант индикатора kijun-sen line lua QUIK , который написал Ии ( не проверял).
Код
Settings = {
    Name = "*Kijun-sen",
    line = {{
        Name = "Kijun-sen",
        Color = RGB(0, 0, 255),
        Type = TYPE_LINE,
        Width = 2
    }}
}

function Init()
    return 1
end

local kijun_period = 26  -- Период Kijun-sen (можно изменить)

function OnCalculate(index)
    -- Проверяем, достаточно ли данных для расчета
    if index < kijun_period - 1 then
        return nil
    end
    
    -- Инициализация переменных для экстремумов
    local max_high = High(index - kijun_period + 1)
    local min_low = Low(index - kijun_period + 1)
    
    -- Поиск максимума и минимума за период
    for i = index - kijun_period + 2, index do
        local current_high = High(i)
        local current_low = Low(i)
        
        if current_high > max_high then
            max_high = current_high
        end
        
        if current_low < min_low then
            min_low = current_low
        end
    end
    
    -- Расчет Kijun-sen
    return (max_high + min_low) / 2
end
Скрипты от ИИ
 
ИИ делал мне подобный скрипт и на Lua. Но для разработки Ai агентов он просит загрузить torch- luajit либо пишет агента на основе Q-таблицы.
-----------------
Питон нем и прикольно, что я на нем особо не пишу и знаю его хуже, чем ИИ.
Скрипты от ИИ
 
В последней версии загрузчика ИИ сделал сжатие сохраняемых файлов, что обеспечивает экономию диска примерно  от 3 до 7 раз.  
Скрипты от ИИ
 
Цитата
Nikolay написал:
И даже в этом простом коде ошибка - код обработки файла конфигурации не соответствует структуре json.
ИИ просто сделал у него такое расширение. но читает его в питоне и все нормально обрабатывает.
Скрипты от ИИ
 
Сейчас отлаживаю с ИИ скрипт AI агента для торговли акциями.
Весь код как и в предыдущий полностью написал ИИ.
Полет нормальный.
Скрипты от ИИ
 
Добрый день,
Выкладываю работающий скрипт, который написал ИИ под моим руководством.
-------------------------------
Скрипт позволяет загружать историю с биржи MOEX.
-------------------------
Состоит из двух файлов.
---------------
config.json  
Код
{
    "instruments": [
        {
            "name": "SBER",
            "start_date": "2015-01-01",
            "decimal_places": 2,
            "intervals": [1, 10, 60, 24],
            "parameters": ["open", "high", "low", "close", "volume"],
            "board": "TQBR"
        },
        {
            "name": "GAZP",
            "start_date": "2015-01-01",
            "decimal_places": 2,
            "intervals": [1, 10, 60, 24],
            "parameters": ["open", "high", "low", "close", "volume"],
            "board": "TQBR"
        }
    ]
}
data_fetcher.py
Код
import os
import pandas as pd
import requests
import json
from datetime import datetime, timedelta

def load_config(config_file="config.json"):
    """
    Загружает конфигурацию из JSON файла

    Параметры:
    config_file (str): Путь к файлу конфигурации

    Возвращает:
    dict: Конфигурация
    """
    if not os.path.exists(config_file):
        print(f"Файл конфигурации {config_file} не найден")
        return None

    try:
        with open(config_file, 'r', encoding='utf-8') as f:
            config = json.load(f)
        return config
    except Exception as e:
        print(f"Ошибка при загрузке конфигурации: {e}")
        return None

def fetch_moex_data(ticker, start_date, end_date, interval=60):
    """
    Загружает данные с MOEX API для указанного тикера и временного периода

    Параметры:
    ticker (str): Тикер инструмента
    start_date (datetime): Начальная дата загрузки
    end_date (datetime): Конечная дата загрузки
    interval (int): Интервал свечей в минутах (по умолчанию 60 минут)

    Возвращает:
    pd.DataFrame: DataFrame с загруженными данными
    """
    data = []
    current_start = start_date
    print(f"Загрузка данных с MOEX для {ticker} (интервал: {interval} мин) с {start_date} по {end_date}...")

    while True:
        url = f"http://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/{ticker}/candles.json"
        params = {
            'from': current_start.strftime('%Y-%m-%d'),
            'till': end_date.strftime('%Y-%m-%d'),
            'interval': interval,
            'start': 0
        }

        try:
            response = requests.get(url, params=params)
            response.raise_for_status()  # Проверка на ошибки HTTP
            json_data = response.json()

            if 'candles' not in json_data or 'data' not in json_data['candles']:
                print("Нет данных в ответе API")
                break

            candles = pd.DataFrame(json_data['candles']['data'],
                                  columns=json_data['candles']['columns'])

            if len(candles) == 0:
                break

            data.append(candles)

            # Обновляем время для следующего запроса
            current_start = (pd.to_datetime(candles['end'].iloc[-1]) + timedelta(minutes=interval))

            if len(candles) < 500:  # Если получено меньше 500 записей, это последняя порция
                break

        except requests.exceptions.RequestException as e:
            print(f"Ошибка при запросе данных: {e}")
            break

    print(f"Загружено {len(data)} блоков данных")

    if not data:
        return pd.DataFrame()

    # Объединяем все блоки данных и удаляем дубликаты
    return pd.concat(data).drop_duplicates()

def process_raw_data(raw_data):
    """
    Обрабатывает сырые данные: разделяет begin на date и time, удаляет end

    Параметры:
    raw_data (pd.DataFrame): Сырые данные с MOEX

    Возвращает:
    pd.DataFrame: Обработанные данные
    """
    # Разделение begin на date и time
    raw_data['date'] = pd.to_datetime(raw_data['begin']).dt.date

    # Преобразование времени в формат без двоеточий (HHMMSS)
    raw_data['time'] = pd.to_datetime(raw_data['begin']).dt.strftime('%H%M%S')

    # Удаление ненужных столбцов
    columns_to_keep = ['date', 'time', 'open', 'high', 'low', 'close', 'volume']
    processed_data = raw_data[columns_to_keep].copy()

    # Сортировка по дате и времени
    processed_data = processed_data.sort_values(['date', 'time'])

    return processed_data

def get_last_available_date(ticker_dir):
    """
    Определяет последнюю дату, за которую есть данные в структуре каталогов

    Параметры:
    ticker_dir (str): Путь к каталогу тикера

    Возвращает:
    datetime.date: Последняя дата или None, если данных нет
    """
    last_date = None

    # Проходим по всем подкаталогам (годы)
    if not os.path.exists(ticker_dir):
        return None

    for year_dir in os.listdir(ticker_dir):
        year_path = os.path.join(ticker_dir, year_dir)
        if not os.path.isdir(year_path):
            continue

        # Проходим по месяцам
        for month_dir in os.listdir(year_path):
            month_path = os.path.join(year_path, month_dir)
            if not os.path.isdir(month_path):
                continue

            # Проходим по дням
            for day_dir in os.listdir(month_path):
                day_path = os.path.join(month_path, day_dir)
                if not os.path.isdir(day_path):
                    continue

                # Проверяем, что имя дня - это число (день месяца)
                if not day_dir.isdigit():
                    continue

                # Формируем дату: год, месяц, день
                try:
                    year = int(year_dir)
                    month = int(month_dir)
                    day = int(day_dir)
                    current_date = datetime(year, month, day).date()
                except:
                    continue

                # Сравниваем с последней датой
                if last_date is None or current_date > last_date:
                    last_date = current_date

    return last_date

def update_data_file(ticker, interval, output_dir, start_date, end_date):
    """
    Обновляет файлы данных, добавляя новые записи при необходимости

    Параметры:
    ticker (str): Тикер инструмента
    interval (int): Интервал свечей в минутах
    output_dir (str): Путь к каталогу для сохранения данных
    start_date (datetime): Начальная дата для загрузки
    end_date (datetime): Конечная дата для загрузки

    Возвращает:
    None
    """
    # Определяем последнюю дату, за которую есть данные
    last_date = get_last_available_date(output_dir)

    if last_date is None:
        # Данных нет, загружаем с начальной даты
        new_start_date = start_date
        print("Не найдено существующих данных. Загружаем все данные...")
    else:
        # Загружаем с последней даты (включительно)
        new_start_date = datetime.combine(last_date, datetime.min.time())
        print(f"Найдены данные до {last_date}. Загружаем новые данные начиная с этой даты...")

    # Загружаем данные с MOEX
    raw_data = fetch_moex_data(ticker, new_start_date, end_date, interval)

    if raw_data.empty:
        print("Нет новых данных для загрузки")
        return

    # Обрабатываем данные
    processed_data = process_raw_data(raw_data)

    # Сохраняем данные, разбивая по датам
    save_data_by_date(ticker, interval, output_dir, processed_data)

    print(f"Загружено и сохранено {len(processed_data)} записей")

def save_data_by_date(ticker, interval, output_dir, data):
    """
    Сохраняет данные с разбиением по датам в подкаталоги

    Параметры:
    ticker (str): Тикер инструмента
    interval (int): Интервал в минутах
    output_dir (str): Базовый каталог для сохранения
    data (pd.DataFrame): Данные для сохранения

    Возвращает:
    None
    """
    # Получаем имя интервала
    interval_name = get_interval_name(interval)

    # Группируем данные по датам
    grouped = data.groupby('date')

    for date, day_data in grouped:
        # Разбиваем дату на год, месяц, день
        year = date.year
        month = date.month
        day = date.day

        # Форматируем месяц и день с ведущими нулями
        month_str = f"{month:02d}"
        day_str = f"{day:02d}"

        # Формируем путь к каталогу для этой даты
        date_dir = os.path.join(output_dir, str(year), month_str, day_str)

        # Создаем каталог, если он не существует
        os.makedirs(date_dir, exist_ok=True)

        # Создаем подкаталог для интервала
        interval_dir = os.path.join(date_dir, interval_name)
        os.makedirs(interval_dir, exist_ok=True)

        # Удаляем столбец date перед сохранением
        day_data_to_save = day_data.drop(columns=['date'])

        # Сохраняем каждый параметр в отдельный файл
        for column in day_data_to_save.columns:
            file_path = os.path.join(interval_dir, column)

            # Сохраняем столбец без индекса и без заголовка
            day_data_to_save[column].to_csv(file_path, index=False, header=False)

            print(f"Сохранено {len(day_data_to_save[column])} значений параметра '{column}' за {date} в {file_path}")

def get_interval_name(interval):
    """
    Преобразует интервал в минутах в текстовое представление

    Параметры:
    interval (int): Интервал в минутах

    Возвращает:
    str: Текстовое представление интервала
    """
    if interval == 1:
        return "1min"
    elif interval == 10:
        return "10min"
    elif interval == 60:
        return "1hour"
    elif interval == 1440:
        return "1day"
    else:
        return f"{interval}min"

if __name__ == "__main__":
    # Загрузка конфигурации
    config = load_config()
    if not config:
        print("Не удалось загрузить конфигурацию. Выход...")
        exit(1)

    # Параметры загрузки
    end_date = datetime.now()

    print(f"Начало загрузки данных для тикеров: {', '.join([item['ticker'] for item in config['tickers']])}")
    print(f"Период: с {min([datetime.strptime(item['start_date'], '%Y-%m-%d') for item in config['tickers']])} по {end_date.strftime('%Y-%m-%d')}")
    print("-" * 50)

    # Обработка каждого тикера и интервала
    for ticker_config in config['tickers']:
        ticker = ticker_config['ticker']
        start_date_str = ticker_config['start_date']
        intervals = ticker_config['intervals']

        # Преобразование начальной даты из строки в datetime
        try:
            start_date = datetime.strptime(start_date_str, '%Y-%m-%d')
        except ValueError:
            print(f"Ошибка в формате даты для тикера {ticker}: {start_date_str}")
            continue

        print(f"\nОбработка тикера: {ticker} (начальная дата: {start_date_str})")
        print(f"Интервалы: {', '.join([get_interval_name(i) for i in intervals])}")

        # Формирование пути к каталогу для сохранения данных
        base_dir = "moex"
        ticker_dir = os.path.join(base_dir, ticker)

        # Обработка каждого интервала для текущего тикера
        for interval in intervals:
            print(f"\nОбработка интервала: {get_interval_name(interval)}")

            # Обновление файла данных
            update_data_file(ticker, interval, ticker_dir, start_date, end_date)

            # Проверка сохраненных данных
            print("\nПроверка сохраненных данных:")
            interval_name = get_interval_name(interval)

            # Проверяем наличие подкаталогов с датами
            if os.path.exists(ticker_dir):
                # Собираем все даты из структуры каталогов
                dates_found = []

                # Проходим по годам
                for year_dir in sorted(os.listdir(ticker_dir)):
                    year_path = os.path.join(ticker_dir, year_dir)
                    if not os.path.isdir(year_path):
                        continue

                    # Проходим по месяцам
                    for month_dir in sorted(os.listdir(year_path)):
                        month_path = os.path.join(year_path, month_dir)
                        if not os.path.isdir(month_path):
                            continue

                        # Проходим по дням
                        for day_dir in sorted(os.listdir(month_path)):
                            day_path = os.path.join(month_path, day_dir)
                            if not os.path.isdir(day_path):
                                continue

                            # Проверяем наличие подкаталога с интервалом
                            interval_path = os.path.join(day_path, interval_name)
                            if os.path.isdir(interval_path):
                                # Формируем дату для отображения
                                try:
                                    year = int(year_dir)
                                    month = int(month_dir)
                                    day = int(day_dir)
                                    date_str = f"{year:04d}-{month:02d}-{day:02d}"
                                    dates_found.append(date_str)
                                except:
                                    pass

                if dates_found:
                    print(f"Найдено {len(dates_found)} дат с данными:")
                    # Показываем последние 5 дат
                    for date_str in sorted(dates_found)[-5:]:
                        # Формируем путь к каталогу интервала
                        interval_path = os.path.join(ticker_dir, date_str.split('-')[0],
                                                    date_str.split('-')[1], date_str.split('-')[2],
                                                    interval_name)

                   #     if os.path.exists(interval_path):
                    #        print(f"  {date_str}:")

                            # Проверяем наличие файлов с параметрами
                    #        for param in ['time', 'open', 'high', 'low', 'close', 'volume']:
                    #            param_file = os.path.join(interval_path, param)
                    #            if os.path.exists(param_file):
                    #                # Читаем файл
                    #                param_data = pd.read_csv(param_file, header=None)
                    #                print(f"    {param}: {len(param_data)} значений")

                                    # Выводим последние 3 значения для проверки
                               #     if len(param_data) > 0:
                               #         print(f"      Последние 3 значения: {', '.join(map(str, param_data.tail(3).values.flatten()))}")
                    #    else:
                    #        print(f"  {date_str}: каталог интервала не найден")
                else:
                    print("Данные не найдены")
            else:
                print(f"Каталог тикера {ticker} не найден")

            print("-" * 30)

   #     print("-" * 50)

    print("\nЗагрузка данных завершена для всех инструментов и интервалов")
С питона на луа, памажити ), питон
 
Цитата
prugramzer написал:
Игорь Б, В принципе безразницы. Я луа считаю паскалем. Когдато на нем учился )
Прикольно. Это как  мото считать авто, а корову - лошадью.  
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 82 След.
Наверх