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

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

Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 14 След.
ParamRequest и CancelParamRequest в индикаторах, ACCESS VIOLATION
 
Цитата
TGB написал:
Зачем двойная последовательность вызов функции OnCalculate(index)?
  Это вопрос к поддержке.
  Что это за ноу-хау? Нельзя ли обойтись без повтора?
ParamRequest и CancelParamRequest в индикаторах, ACCESS VIOLATION
 
Цитата
Старатель написал:
При добавлении / удалении индикатора возникают ошибки:
Function OnChangeSettings: ACCESS VIOLATION at address 000007FC524B89CCACCESS VIOLATION at address 000007FC524B89CC
  Такое сообщение об ошибках - это ошибка QUIK независимо от текста кода скрипта, порождающего это сообщение.  Если есть ошибка при использовании интерфейсных функций QUIK, то должны выдаваться понятные большинству пользователям сообщения об его ошибке.

2.   QUIK 9.7  Qlua 5.4
Индикатор:
Код
Settings={}
Settings.Name = "minimal"
function Init()
   return 1
end
local ind = {}
function OnCalculate(index)
  if not ind[index] then 
     ind[index] = 100
  else
     ind[index] = ind[index] + 100
  end  
  return ind[index]
end

Зачем двойная последовательность вызов функции OnCalculate(index)?:
1) index:  1, 2, 3  ….
2) index:  1, 2, 3  ….
И это, похоже, происходит в любых индикаторах.
Добавляйте в любой график, меняете, например, толщину линии и убеждайтесь.
Кривые шибки в QLua
 
Цитата
Старатель написал:
Вероятность возникновения nil не исключает, но значительно снижает.
 Это хорошее решение, если при возникновение nil не возникает других последствий и не нарушается последующее функционирование скрипта.
Кривые шибки в QLua
 
Цитата
TGB написал:
при неявных преобразованиях строк в число будет вызываться прежняя (потокоопасная) функция.
  Например, в выражении:    i = 6 + '100'   ---  (результат число 106)  будет вызвана прежняя функция tonumber.
  -----
  Существующая схема встраивания Lua в QUIK давно (я это наблюдаю с мая 2020г., а началось гораздо раньше) создает много проблем пользователям и разработчикам QLua. Само по себе, использование Lua это, с учетом IT-квалификации большинства пользователей QUIK, хорошее решение, но идея, запуска колбеков в скриптах пользователя в отдельном потоке, плохая. В этой схеме параллелизма выполнения в скрипте пользователя, при использовании только Lua, все равно нет, но есть почти все сложные проблемы многопоточного программирования, создающие нестабильность работы скриптов, даже если пользователь об этом не знает.  Кому это надо?
  В своем комментарии https://forum.quik.ru/messages/forum10/message64087/topic5823/#message64087
в п.3 я написал, как надо бы встраивать Lua в QUIK с тем, чтобы проблем многопоточности скриптов не было. Это, конечно, не отменяет проблем интерфеса скриптов с QUIK.
Кривые шибки в QLua
 
Цитата
Старатель написал:
виновник однозначно - tonumber. Но тут надо отметить, что у меня трудится много скриптов в нескольких квиках, а ошибка за неполный день возникла пока только в одном.
    Не факт, что обнаруженная вами сложная ошибка (синхронизации) относится только к tonumber. Существующая реализация разработчиком Lua стандартных C-функций Lua (5.4.1) архитектурно не учитывает многопоточность использования Lua. Для выполнения любых операций в таких функциях с элементами, хранящимися в lua_State, надо было сделать доступным только API-C, но этого не сделано.  Выяснять потокобезопасность каждой такой функции, анализируя ее исходники это, конечно, не решение.
---------
 Когда обсуждаемая ошибка будет устранена разработчиком QUIK неизвестно. Поэтому конкретную проблему с tonumber вы, наверное, могли бы решить следующим образом:
написать в каком-нибуть своем C-пакете собственную, но потокобезопасную функцию tonumber_с, аналогичную tonumber, и в начальном запуске сриптов выполнять перегрузку tonumber = tonumber_с.   Здесь, правда, существует засада: возможно, при неявных преобразованиях строк в число будет вызываться прежняя (потокоопасная) функция.
Lua 5.4
 
Цитата
s_mike@rambler.ru написал:
Проблема в том, что loadbuffer  выдает ошибку
 -----
Цитата
TGB написал:
То ваша функция forLua_xx_test  работает в 5.4 в QUIK 9.5.0.42
Это я проверил 15 минут назад.  Почему у вас не работает непонятно.
Lua 5.4
 
Цитата
s_mike@rambler.ru написал:
Может, кто то пальцем сможет указать направление в пустыне?

Если ваш код Имя_dll.dll оформлен следующим образом (Имя_dll и Имя_пакета_dll это идинтификаторы в латинской кодировке):
Код
.........................

static int forLua_xx_test(lua_State* L)    //  Ваша функция ---
{

   ............
}
 
//=== Регистрация реализованных в dll функций, чтобы они стали "видимы" для Lua ================================//
static struct luaL_Reg ls_lib[] = {
   { "xx_test", forLua_xx_test },
   { NULL, NULL }
};

extern "C" LUALIB_API int luaopen_Имя_dll>(lua_State *L) {   // !!!  luaopen_<Имя пакета>
   lua_newtable(L);
   luaL_setfuncs(L, ls_lib, 0);
   lua_pushvalue(L, -1);
   lua_setglobal(L, "Имя_пакета_dll");  // !!!  lua_setglobal(L, "<Имя пакета>");
   return 0;
}
 


А вызов в QLua:
Код
require('Имя_dll')

message("result=" .. tostring(Имя_пакета_dll.xx_test("message('hello world!!',3)")))


То ваша функция forLua_xx_test  работает в 5.4 в QUIK 9.5.0.42
Кривые шибки в QLua
 
Цитата
nikolz написал:
для особо тупых:
 1) вы так и не научились выделять фрагменты текста?
 2) объясняю:  мусорщик Lua не является потокобезопасным, и при его запуске на любом lua_State, он может обрабатывать и все остальные lua_State запущенного скрипта. Таким образом оба потока могут писать в одну и туже область памяти.
-----------------------------------
 
Цитата
nikolz написал:
Что такое (нативный) Lua ?
  Читайте:
Цитата
TGB написал:
однопоточный (нативный) Lua
Кривые шибки в QLua
 
Цитата
s_mike@rambler.ru написал:
Все что вы пишете в п3 очереди и прочие слипы можно сделать средствами луа без каких либо затруднений
  У меня все это сделано.
Ключевым п.3 является:
Цитата
TGB написал:
Существует вариант построения архитектуры встраивания Lua в QUIK, в которой можно использовать однопоточный (нативный) Lua :
и
Цитата
TGB написал:
Подключение новых версий Lua станет в описанной выше архитектуре рутинной задачей. Исчезнут все проблемы, вызванные текущей многопоточностью QLua.
Кривые шибки в QLua
 
Цитата
Старатель написал:
Думал такие ошибки возникают только в QUIK 9. Но нет, сегодня в QUIK 8.13 случилась аналогичная ошибка.QUIK clients support, надо что-то делать. Не хочется все места с tonumber параноидально обкладывать проверкой на nil.

      Этот комментарий пишу, в основном,  для разработчика QUIK.

1. При открытии библиотеки base_funcs (Lua 5.4.1), в которой находится tonumber, все ее функции помечаются как С-функции. Это означает, что в программе Lua они выполняются в скобках:
lua_unlock(L);    Запуск C-функции;    lua_lock(L);
    Такие функции могут выполняться параллельно с исполнением  QLua-кода. Однако любые операции с использованием в них L, должны выполняться в синхронизирующих скобках:
 lua_lock(L);    Выполнение операций в L;     lua_unlock(L);
     При просмотре исходника функции tonumber (с учетом вызываемых в ней функций), я обнаружил, что в этой функции есть как минимум один фрагмент с использованием операций в L без синхронизирующих скобок (мои комментарии помечены в исходнике символами #####):
Код
//   ####  lua_stringtonumber вызывается в tonumber  (luaB_tonumber)
LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
  size_t sz = luaO_str2num(s, s2v(L->top));   //  ##### ? используется L без синхрони-зирующих скобок
  if (sz != 0)
    api_incr_top(L);                                      //  ##### ? используется L без синхронизирующих скобок
  return sz;
}

    Возможно, что-то я упустил, но пусть это проверит разработчик QUIK.
    ----------
2. Есть общая проблема в реализации стандартных функций Lua для многопоточного использования, описанная в моем комментарии: https://forum.quik.ru/messages/forum10/message57243/topic6555/#message57243
-------
3. Существует вариант построения архитектуры встраивания Lua в QUIK, в которой можно использовать однопоточный (нативный) Lua :
1)    вместо регистрации функций обратного вызова, регистрация соответствующих очередей событий (возможно, с теми же именами);  
2)    вместо sleep, использование служебной функции ожидания либо истечения интервала времени (как в sleep), либо появления данных в очередях событий (с выдачей списка непустых очередей);
3) добавление функции чтения очередей событий (их параметров);
4) реализация функций интерфейса c QUIK в виде отдельного пакета dll, подключаемого в Lua.
      Подключение новых версий Lua станет в описанной выше архитектуре рутинной задачей. Исчезнут все проблемы, вызванные текущей многопоточностью QLua.
Отладка QUIK 8.13
 
Если бы вы это не написали:
Цитата
Владимир написал:
Тут как бы пару порядков по скорости не набежало!
 то мне комментировать было бы нечего.
 А так у меня есть предложение как ускорить то, что у вас уже есть.
    Не надо обрабатывать OnTrade. Четвертьсекундный обработчик - ничего не ищет, а просто забирает только вновь появившиеся заявки из таблицы orders а далее как у вас описано но без обработки вашего стека.
Отладка QUIK 8.13
 
Цитата
Владимир написал:
И одно это уже даёт порядок по скорости.
   Интересно где этот порядок по скорости?
   Сначала, по колбеку вы заносите данные колбека в свой стек, а затем, наверное, по какому-то таймеру обрабатываете свой стек. И где в таком случае порядок по скорости?
Отладка QUIK 8.13
 
Цитата
Владимир написал:
А меня не устраивает, что таблица пухнет.
  Хотите вы это или нет таблица все равно пухнет  :smile:
Отладка QUIK 8.13
 
Цитата
Владимир написал:
А таблица с течением времени только пухнет, данные там тоже недостоверные, да ещё и всё более затратный поиск. Нафиг нужно такое счастье?
    Ну и пусть таблица пухнет. Вы знаете, что данные в ней более недостоверные, чем колбеки? Откуда все более затратный поиск в ней, если можно обрабатывать только вновь поступившие ее элементы (между циклами ее обработки)?
    Я не утверждаю, что заявки и сделки надо обрабатывать именно предлагаемым мною способом. Это, всего-навсего, альтернативный и вполне работающий вариант, избавляющий от обработки промежуточных колбеков. В принципе, чем меньше разных колбеков вы используете (при этом решая свои задачи), тем потенциально надежнее ваш скрипт.
Отладка QUIK 8.13
 
Заинтриговали:
Цитата
Владимир написал:
Я несколько раз писал здесь, почему я использую именно OnTrade и крайне редко заглядываю в orders, повторяться лень, так что если интересно, покопайтесь в моих сообщениях.
  Из того, что вы писали я это не понял. Поэтому, пожалуйста, объясните, чем вам не подходят данные из таблиц orders (Заявки) и trades (Сделки), если вы будете их проверять с некоторой периодичностью. В этих таблицах хранятся не какие-то «прерывания», а  выполненные биржей операции (выставленные заявки и выполненные сделки).  Или вам интересно «кувыркаться» с «сырыми» «прерываниями - колбеками», которые то приходят, то не приходят?
Отладка QUIK 8.13
 
Цитата
Владимир написал:
Коротко: я считаю этот вариант самым оптимальным.
 А что же жалуетесь на нестабильность  :smile: ?
Отладка QUIK 8.13
 
1.
Цитата
Владимир написал:
Вот полный код моего обработчика:Код
function OnTrade(n)
local i;
i=a[0][7][0]+1; -- новый размер стека сделок из прерывания
a[0][7][0]=i; -- записываем изменение
a[0][7][i]={}; -- заводим новый элемент стека
a[0][7][i][0]=n.trans_id; -- ID транзакции
a[0][7][i][1]=n.order_num; -- ID заявки
a[0][7][i][2]=n.trade_num; -- ID сделки
a[0][7][i][3]=n.sec_code; -- ID тикера
a[0][7][i][4]="B"; -- по умолчанию это покупка
if bit.band(n.flags,4)~=0 then a[0][7][i][4]="S";end;
a[0][7][i][5]=n.qty; -- объём сделки в лотах
a[0][7][i][6]=n.price; -- цена сделки
end;
  Зачем вы заводите новый элемент стека, когда можно было сделать так:
Код
function OnTrade(n)
local i;
i=a[0][7][0]+1;   -- новый размер стека сделок из прерывания
a[0][7][0]= i;   -- записываем изменение
a[0][7][i]= n;   -- записываем таблицу из OnTrade
end;

Вы любите писать длинные и неэффективные программы  :smile: ?
-----
 Вместо непонятных числовых индексов можно бы было использовать более содержательные текстовые ключи, например: «Тикер», «История сделок» и т.д. Читабельность вашей программы улучшилась бы, а ее эффективность практически не изменилась. Если насчет эффективности у вас есть сомнения,  то проведите эксперименты.
----
 Зачем вы вообще «обрабатываете» OnTrade, когда можно бы было периодически (по таймеру) просматривать таблицы  orders (Заявки) и trades (Сделки), в которых отображается готовые состояния по выполнению ващих транзакций ?
--------------------------------------
2. Зачем вы наезжаете на swerg?
 Он действительно сообщил существенную информацию (мне, например, она была неизвестна) и за это ему спасибо.
Отладка QUIK 8.13
 
Цитата
TGB написал:
4. В файле   lvm.с  после строки:  StkId ra;  /* instruction's A register */   добавить:    
int const Период_переключения_State = 1000;  
if (++L->Счетчик_для_переключения_State > Период_переключения_State) {    
    L->Счетчик_для_переключения_State = 0;    
    //  ! Имитация вызова "пустой" C-функции  --      
    ProtectNT((lua_unlock(L), lua_lock(L)));  
}
    Строка:  ProtectNT((lua_unlock(L), lua_lock(L)));  ошибочна (выяснилось при длительном, недельном тестировании) и ее  следует заменить
    на строку:  savestate(L, ci), lua_unlock(L), lua_lock(L), updatetrap(ci);
Отладка QUIK 8.13
 
Цитата
Владимир написал:
nikolz , Так что же такое "длинный цикл"? Гугл тоже не знает: по запросу выдаёт ссылки на менструальый цикл. Но что бы это ни было, лапуль, он спрашивал: "Где вы увидели МОЙ код с длинным циклом?", а Вы привели его цитату про блокировку потоковв QUIK выполнением длинного цикла ПОЛЬЗОВАТЕЛЬСКОЙ ПРОГРАММЫ.
  Длинный цикл на «чистом» Lua - это сленг данной ветки, обозначающий долго выполняющийся фрагмент скрипта, в котором нет вызовов C-функций. Например, sleep  это С-функция. С -функциями являются функции из стандартного пакета Lua и многие функции из подключаемых C-пакетов.
 Простейшим примером длинного  цикла на «чистом»  Lua может быть следующий фрагмент кода:
for   i = 1, 5000000000 do    end  
 Если вы вставите этот цикл в свой скрипт сразу после function   main (), то увидите, что пока этот цикл исполняется, ваш терминал полностью «подвиснет» и вы не сможете  даже остановить свой скрипт.
 Приведенный пример, конечно, искусственный, но кто запрещает пользователю написать содержательный фрагмент кода без использования C-функций и исполняющийся достаточно долго.
 Такое «подвисание» QUIK, по-хорошему, надо бы устранить, но, с учетом того что такие ситуации, наверное, редкие, а их устранение – правка сложной виртуальной машины Lua разработчиком QUIK,  то я все больше склоняюсь к тому, что это тот случай, когда можно оставить это как есть.
--------------
   Вы точно отметил: nikolz досих пор не понял, что у меня ник TGB, а не «пользователь».
Отладка QUIK 8.13
 
Цитата
nikolz написал:
Рассуждая о "чистом" луа Вы полезли  в функции СИ , которые исполняют этот чистый луа, вместо того, чтобы  написать грамотно свой длинный цикл.
  Где вы увидели мой код с длинным циклом?
  Вы филосов  :smile: ? И готовы комментировать критически все, что угодно, не разбираясь в комментируемом лишь бы накропать свой очередной безумный текст?  Вы, что, до сих не поняли, что в комментируемых вами моих последних сообщениях данной ветки я выступаю не как пользователь, лично со своей проблемой, а обращаю внимание на общую, системную ошибку текущей реализации QUIK?
Отладка QUIK 8.13
 
Код приведенный в моем сообщении 174: https://forum.quik.ru/messages/forum10/message63195/topic6356/#message63195
был проверен мною давно для Lua 5.3.5.

  Для Lua 5.4.1 аналогичный код (но есть отличие), проверенный мною недавно и устраняющий блокировку потоков в QUIK выполнением  длинного цикла пользовательской программы на «чистом» Lua, следующий:
1. В файле   lstate.h  после строки:  volatile l_signalT hookmask;
    добавить: int Счетчик_для_переключения_State;
2. В файле   lstate.с  после строки:  L->errfunc = 0;
   добавить:  L->Счетчик_для_переключения_State = 0;
3. В файле   lstate.с:
    -  после строки:  L1->ci = ci;
   добавить:  L1->Счетчик_для_переключения_State = 0;
    -  после строки:   L->oldpc = 0;
добавить: L->Счетчик_для_переключения_State = 0;
4. В файле   lvm.с  после строки:  StkId ra;  /* instruction's A register */
  добавить:  
   int const Период_переключения_State = 1000;
   if (++L->Счетчик_для_переключения_State > Период_переключения_State) {
       L->Счетчик_для_переключения_State = 0;
       //  ! Имитация вызова "пустой" C-функции  --
       ProtectNT((lua_unlock(L), lua_lock(L)));
   }
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Цитата
Владимир написал:
TGB , Важная доработка!  
 Согласен  :smile: .  Наверное, закрывающая тему данной ветки.
Вопрос по луа 5.4
 
Цитата
s_mike@rambler.ru написал:
5.4.1 я не смог найти, если подскажете где , будет здорово.
  Здесь:  https://www.lua.org/ftp/
[BUG] Повышенная загрузка CPU при большом количестве функций в скрипте
 
Цитата
TGB написал:
2. В своем комментарии 167 и повторно в 190 я предлагаю вообще при обработке колбеков оставить мусорщик в покое. Он в соответствии с параметрами, заданными по умолчанию (а может быть и пользователем) сможет автоматически собирать мусор как-нибудь сам. Зачем весь гемморой, перечисленный в пункте1? И мне интересен ответ разработчика QUIK.
  И все таки, похоже,  разработчик реагирует на наши бурные обсуждения.
  Я увидел что в QUIK 9.5.0.42 при обработке колбеков мусорщик не останавливается.
Обмен сообщениями приложений , скриптов на Lua, Python ,С
 
Цитата
nikolz написал:
 1. Я вынужден согласиться с позицией Владимира, со следующими уточнениями:
1) С его рекомендациями начинающим разрабатывать робота, я, почти полностью, согласен.
2) Если же у кого то есть наработки на языках отличных от QLua, то ему, наверное, следует оценить затраты на перенос своих разработок на QLua и на реализацию интерфейса своих программ с QUIK.
---
2. При том, что вы активно используете IT-терминологию, у меня нет ощущения, что вы «экстра программист»  :smile: .
  На этом форуме, я думаю, что подавляющее большинство посетителей интересует, как можно заработать на фондовом рынке, а не «танцы» с потоками и потенциальной программной эффективностью. Вы «попали» не на тот форум  :smile:  ?.
Отладка QUIK 8.13
 
Цитата
Старатель написал:
пример написан криво. Отдать 100% CPU под два оператора - такое себе.Реальный пример есть?
  Ну, если вам этот пример не  нравится, то ждите дальше.
Отладка QUIK 8.13
 
Цитата
Владимир написал:
TGB , Специальный сервер на бирже с прямыми каналами доступа к торгам тоже не поможет - Квик, батенька! Да ещё и Луа. А, ну да - ещё не дочитал до конца.
  Согласен.
Отладка QUIK 8.13
 
Цитата
Старатель написал:
TGB , как я понял, проблемы-то и нет вовсе. Или что вам продемонстрировала реальная жизнь?
 Читайте:
Цитата
TGB написал:
2) Последний случай бурного обсуждения системной ошибки QLua, устраняемой моим предложением  https://forum.quik.ru/forum10/topic7303/  . Причем этот случай далеко не первый.
Отладка QUIK 8.13
 
Цитата
nikolz написал:
Так что HFT робот вполне  реально, но должен быть в дата центре.
  Дата центр вам не поможет. Вам надо арендовать для вашего QUIK специальный сервер на бирже с прямыми каналами доступа к торгам.
  Но и это вам не поможет при использовании стандартного рабочего места QUIK, так как API взаимодействия QLua с QUIK выполняется в среде Lua, в которой автоматическое управление памятью, и в произвольные моменты времени может запускаться сборка мусора. Сборка мусора может вносить заметные задержки (не исключено миллисекундные) при взаимодействии вашей программы с QUIK. Вы, конечно, можете отключить сборку мусора, но тогда флаг вам в руки :smile: . Попробуйте.
----------
  Вообще, надо заниматься тем, о чем есть хоть какое-то понятие.  HFT роботы не "манна небесная" и о проблемах их использования (как технических так и алгоритмических) достаточно информации в интернете.
Отладка QUIK 8.13
 
Цитата
TGB написал:
Мое предложение от  22.04.2021 15:59:54 https://forum.quik.ru/messages/forum10/message55019/topic6356/#message55019
 Добавлю:
1) Я уже тогда написал, что вариант предлагаемого решения проверен мною на моем стенде имитации QLua (исключая его API).
2) Последний случай бурного обсуждения системной ошибки QLua, устраняемой моим предложением https://forum.quik.ru/forum10/topic7303/ . Причем этот случай далеко не первый.
Отладка QUIK 8.13
 
Цитата
nikolz написал:
Таких проблем не существует, если делать как у меня.
 Я написал свое предложение не про вас, не для вас и даже не для, конкретно, себя. Это про системную ошибку в QLua.
Цитата
nikolz написал:
Можно делать HFT, чего раньше даже не думал
 Ну, вы фантазер.  HFT в QUIK  :smile: ? Это диагноз.
Отладка QUIK 8.13
 
Цитата
Roman Azarov написал:
Данные пожелания еще не были рассмотрены. Как только появится какая-то новая информация, мы сообщим об этом в данной ветке форума.
Мое предложение от  22.04.2021 15:59:54
https://forum.quik.ru/messages/forum10/message55019/topic6356/#message55019
Прошел год.
-----------------
 Напомню описание ситуации и вариант ее устранения.
---
 Бывают ситуации зависания в QLua, когда основной поток обслуживания колбеков всех скриптов пользователя, а также таблиц QUIK (это не таблицы Lua), блокируется выполнением  длинного цикла пользовательской программы на «чистом» Lua, в котором нет ни вызова seep ни вызова дру-гих C-функций.
Это может порождать ошибки, которые для многих пользователей QLua (использующих несколько запускаемых скриптов)  являются неожиданными и труднообъяснимыми. Блокируются выполнения колбеков всех скриптов из-за выполнения длинного цикла пользовательской программы на «чистом» Lua в каком-то из запущенных пользователем скриптов.  При этом зависает рабочее место QUIK. Это системная ошибка QLua.
----
  Есть простой вариант реализации пожелания (далее список изменений, реализующих этот вариант в тексте исходников QLua ):
1. В файле   lstate.h  после строки:  lu_byte allowhook;
добавить: int Счетчик_для_переключения_State;
2. В файле   lstate.с  после строки:  L->errfunc = 0;
добавить:  L->Счетчик_для_переключения_State = 0;
3. В файле   lstate.с  после строки:  L1->stacksize = BASIC_STACK_SIZE;
добавить:  L1->Счетчик_для_переключения_State = 0;
4. В файле   lvm.с  после строки:  StkId ra;
добавить:  
if (++L->Счетчик_для_переключения_State > 1000) {   //  1000  надо задать кон-стантой  
 L->Счетчик_для_переключения_State = 0;
 lua_unlock(L); lua_lock(L);
}
-----------------------
В чем проблема реализации этого пожелания?
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир-Лапуля написал:
Лапуль
 Опять адрес форума перепутали :smile: ?
Сохранение результатов работы скрипта в файл
 
Цитата
TGB написал:
(а всех переменных)
Описка. Читать: (а не всех переменных)
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
просто безумная сложность!   Я говорил про сложность СТРУКТУРЫ данных, ЛОГИЧЕСКОЙ структуры, и предельная сложность такой структуры называется "граф общего вида" (если учесть, что узлами такого графа могут быть не только атомарные элементы, но и субграфы, а его рёбра также могут быть нагружены произвольной информацией, при этом количество рёбер по разным измерениям может быть переменным, в т.ч. нулевым.
  Особой сложности нет.
  Практически любая безумность, которую вы сможете написать на Lua, будет сереализована и десереализована моими сложными функциями сереализации.
  Но, на самом деле, для целей сохранения и восстановления состояний функций, требуемых (а всех переменных) для продолжения функционирования моего скрипта после перезапуска, я вполне обхожусь простыми функциями сереализации, выложенными здесь.
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
НУ ЗА КАКИМ ХЕРОМ нужно "сохранять и восстанавливать ВСЁ окружение"? Это же ИДИОТИЗМ! Нужно делать только то, что нужно, и ничего, кроме этого.
  В моем комментарии не написано, что в моих боевых скриптах сохраняется все окружение.
  Там написано:
Цитата
TGB написал:
Это проверено на сохранении и восстановлении всего окружения (таблица _G) моих разных скриптов и, кстати, выполняется быстро.
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
это Ваши комплексы, не мои
 А это на что похоже (много повторений да еще крупным шрифтом самое-самое)?:
Цитата
Владимир написал:
структура моих сохраняемых и восстанавливаемых данных НАМНОГО сложнее, и эта задача В ПРИНЦИПЕ не решаема такими функциями.
 Да ладно вам, какие технологические сложности могут быть при построении торговых роботов? Статегия торгов это действительно проблема. Но эффективность стратегии торгов, конечно, определяется не ее сложностью. Стратегия может быть сложной, но не прибыльной, а может быть простой и прибыльной.
  Судя по фрагментам кодов вашего скрипта, структура данных в нем представлена в виде давно известной многомерной матрицы размерности N < 1000, с числовыми индексами, в которой вы храните свой граф. Или это не так?  Что, кроме  table, boolean, number, string, являются эле-ментами вашего графа? Если у вас что-то более монструозное, то было бы интересно узнать: зачем это сделано? Все-таки, надо стремиться к простоте.  
  Но даже, если вы построили что-то монструозное, и корнем этого является таблица, то у меня есть более сложные функции сереализации (их я вам не предлагаю, понимая вашу реакцию на это  :smile: ), которые, скорее всего, смогут сереализовать и десереализовать вашу монструозность. Это проверено на сохранении и восстановлении всего окружения (таблица _G) моих разных скриптов и, кстати, выполняется быстро.
   У меня нет цели что-то вам навязывать.  Мне просто интересно: у вас что-то более сложное, чем служебная таблица окружения скрипта _G, в которой хранятся все глобаль-ные переменные работающего скрипта и многое другое?
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
TGB , Я не вижу смысла в этих функциях - зачем же мне их тестировать?
  Вам лично они, наверное, пока не нужны, так ка вы что то сделали свое. Но вы голословно, вместо того чтобы проверить, утверждаете, что эти функции не работают. У вас что, такой принцип: обгаживать все чужое, чтобы на этом фоне самому выглядеть "молодцом"? Возникает такое ощущение, что вы считаете что весь форум посвящен только вашему непревзойденному" скрипту. На форуме на самом деле есть и другие пользователи и гости.
-----
 Кстати, начальную проверку функций можно выполнить за 2-3 минуты (это меньше, чем написание пяти строк текста комментария)
Например, для начала вы могли бы посмотреть готовый вариант:
1. Перед запуском проверок, в функции tbl_to_string  заменить  GetLocalTimeMls()  на стандартную os.time().  
2. Код проверки простой таблицы (под кодом функций)
Код
   local tbl =  {
                       ['Тикер'] = 'SBER'
           , [{ 1, 2, 3}] = { 'QUIK'}
           , TOBR =  {6, 8, 4, {1, 2, 3 }}
           , 'Сохранение таблицы'
           , ok = true
                    }
-- Сохранение таблицы --
  local str = tbl_to_string (tbl)  
  message ( str )   -- в str строковый образ таблицы  ---
 -- Восстановление таблицы ---
   local tbl1 = string_to_tbl (str)   --- в tbl1 восстановленная таблица 

 3.  Далее можно, экспериментировать, меняя таблицу tbl
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
Но если снова начнёте пороть чушь, ничего хорошего я Вам не гарантирую.
   Ну, вы неугономные  :smile: . Но только в написании длинных голословных текстов. Это вместо того, чтобы потестировать предложенные мною функции и найти таблицу (с довольно слабыми ограничениями, заданными в их описании), которую эти функции не смогут обработать.
Сохранение результатов работы скрипта в файл
 
Владимир,
если вы не против, мне  хотелось бы закончить наш с вами «батлз» миром.  Наверное, для этого достаточно не комментировать друг друга.
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир-Лапуля написал:
Лапуль
   Опять промахнулись с форумом  :smile: ?
Сохранение результатов работы скрипта в файл
 
1.  
Цитата
Владимир написал:
Лапуль
    Вы, похоже, сильно ошиблись форумом. Напомню, здесь, все-таки, форум по программированию, а не гей-клуб.   Зачем вы подставляетесь? Ведь кто-нибуть может начать обращаться к вам по кликухе Владимир-Лапуля, с тем, чтобы не перепутать с другими Владимирами.

2.
Цитата
Владимир написал:
я и сам по себе хороший алгоритмист, и как таковой, знаю совершенно точно
  Алгоритмист вы посредственный, если не понимаете, что с определенными ограничениями (а я их описал в комментариях к своему коду) отдельная таблица (и вы до сих пор не поняли это) может быть сереализована. Покажите мне таблицу произвольной вложенности, в которой в качестве ключей-индексов и их значений используются :
         1) ключи и значения : table, boolean, number, string;
         2) все элементы таблицы (ключи и значения) типа table должны быть уникальными (в пределах таблицы).
  И которая не будет обработана предложенными мной кодами. А без этого все написанное вами бла-бла.

3. Что вы так убиваетесь? В конце концов, вы меня затмили по количеству выложенного вами текста, наверное, в 20 раз, с чем вас точно можно поздравить  :smile: .  Да и концовка дискуссии, наверное, будет за вами  :smile: .  И, все-таки, зацените  :smile: , в моих текстах нет ни одного грубого слова, не считая ваших цитат, и почти все они по делу.
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
И кто Вам сказал, что я злюсь? Я всего лишь сказал, что Ваше беспомощное дерьмо НИКОГДА оно не сделает из того, что требуется. И это просто медицинский факт.
 Исходя из написанного вами выше, повторно, совершенно ясно, что вы опять не понимаете то, что я подробно объяснил в своем комментарии: https://forum.quik.ru/messages/forum10/message62929/topic7277/#message62929
 В этом комментарии написано все очень просто. Прочитайте этот комментарий внимательно несколько раз и, надеюсь, что ваше мнение изменится :)
Сохранение результатов работы скрипта в файл
 
Цитата
TGB написал:
Ну и пусть.
 Я так примирительно  :smile: а вы:
Цитата
Владимир написал:
Так на кой мне (или кому бы то ни было) Ваше беспомощное дерьмо? НИКОГДА оно не сделает из того, что требуется. НИКОГДА!
 Нужно или не нужно это каждый решает для себя.
 Что вы так «выпрыгиваете из штанов» и злитесь? Но я на вас не обижаюсь  :smile: .
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
В ПРИНЦИПЕ неспособна это сделать! Хотя бы по той простой причине, что она не знает и не может знать, что и как сохранять, в каком виде, как и куда это всё восстанавливать. Она не будет работать НИКОГДА!
  Я нигде не писал, что сереализация знает что и как сохранять. Вы скопировав функции tbl_to_string(t, i) и string_to_tbl (str_tbl) смогли бы заменить весь ваш код по сохранению и при необходимости восстановления вашего графа двумя строками. У меня это работает в нескольких местах, начиная с 2019г. Так что вы неправы насчет НИКОГДА. Но, наверное, вам милее ваш код сохранения состояния выполнения вашего скрипта. Ну и пусть.
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
Любому дебилу понятно, что исходная и сохраняемая структура - это РАЗНЫЕ структуры. Или не любому?
 Не согласен. Это понятно не всякому дебилу и поэтому поясню подробнее :smile: :
Цитата
TGB написал:
F:write(tbl_to_string( , ' '))   --- Одна строка
Таблица преобразовалась в строку и записалась в файл. Результат: строка в файле.
Цитата
TGB написал:
  = string_to_tbl ( )  --- Одна строка
Строка считана из файла и преобразована в таблицу.  Результат: таблица.
Итого:  1) <Таблица>  ->  <Строка>
           2) <Строка>  ->  <Таблица>
Сохранение результатов работы скрипта в файл
 
Упустил:
Цитата
Владимир написал:
И с этой задачей Ваша "сереализация" не справится НИКОГДА!
 Справится. Попробуйте.  
 -- Сохранение вашей таблицы --
  F:write(tbl_to_string(<Ваша таблица>, ' '))   --- Одна строка
 -- Восстановление таблицы ---
  <Ваша таблица> = string_to_tbl (<Чтение из файла вашей таблицы>)  --- Одна строка
 -- Восстановление таблицы ---
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
Здесь, кстати, вообще сказано, что нужно сохранять таблицу, созданную по AllocTable, т.е. таблицу Квика, а не таблицу Lua
 Читайте внимательно:
Цитата
Дмитрий написал:
Правильно тогда мой вопрос будет звучать как: Результатом работы скрипта получается таблица как ТИП ДАННЫХ, которую нужно сохранить в файл.
 Из контекста можно понять, что пользователя, наверное, интересует таблица Lua
----------
 Вы не ответили на мой вопрос:
Цитата
TGB написал:
Зачем элементарный код вы представляете как ваше открытие  ?
 У меня есть сильное подозрение, что ваше сообщение было написано чтобы в нем появилась фраза :smile: :
Цитата
Владимир написал:
Мой скрипт каждые 5 минут записывает дамп текущего состояния - так это целый граф, а не какая-то сраная таблица!
------
Сохранение результатов работы скрипта в файл
 
Цитата
Владимир написал:
TGB , Зачем просто, когда можно сложно?  На код просто смотреть страшно (и я не собираюсь этого делать). Программа пишется в 5 секунд, и она в 100500 раз проще, чем в этом "простом варианте". ЗА КАКИМ ХРЕНОМ нужна эта долбаная "конвертация таблицы в строку"? Заняться больше нечем?
  Я предложил функции сереализации и десереализации не для вашего элементарного случая, когда массив вложен в другой массив (с индексами 1… n). Хотя и ваш случай будет обработан этими функциями.  Вопрос, заданный в ветке: как сохранить, а потом восстановить таблицу, а не по работе с числовыми индексами  таблицы-массива.
1. Ваш код не обработает, например, даже элементарную таблицу:
t = { [‘Тикер’] = 'SBER'}. Тем более, не обработает таблицу произвольной вло-женности, в которых индексами-ключами могут быть таблицы.
      В вашем коде нет функции восстановления таблицы  :smile:
2. Зачем элементарный код вы представляете как ваше открытие :smile: ?
Сохранение результатов работы скрипта в файл
 
Код
-----  Конвертация таблицы в строку (сереализация) ------
-- Преобразование таблицы без ее метатаблицы (ключи и значения : table, boolean, number, string) в текстовое представление
-- в соответствии с синтаксисом языка lua  ---
----    Можно использовать для сохранения таблиц в текстовом виде, с возможностью последующего восстановления
--      со следующими ! ограничениями:
--       1) ключи и значения : table, boolean, number, string;
--       2) все элементы таблицы (ключи и значения) типа table должны быть уникальными (в пределах таблицы).
------  Параметры: 1) t  -  таблица (обрабатываются все вложения );  
--                          2) i  -  начальная строка формирования отступа при выводе вложений (например, " ");  если i = '', то строки таблицы выводятся без отступов  
-- Результат (! два): 1) строка (тремя звездочками помечены проблемные места);  2)  количество записей, которые  нельзя представить в текстовом виде
-- с последующим восстановлением  ----
---------
local function tbl_to_string(t, i)
  if type(t) ~= "table" then
        return nil
  end
  i = i or ' '
  local key_tbl_stateOS= "--таблица: "
  local tab = "\t"
  if i == '' then tab ='' end
  local ltime_str =GetLocalTimeMls()
  local tbl = {}  ---   для результата  ----
  local no_unpack =0
   -----------
  local function dump(t, i, seen)      ---------
       if seen then
       if seen[t] then
          return seen[t]
       end
tbl[#tbl +1] = " { -- " .. tostring(t) .. "\n"
else
    seen={} --  просмотренные --
    tbl[#tbl +1] = "{" .. key_tbl_stateOS .. string.format("%.0f", ltime_str) .. " -- время создания \n"
end
       seen[t] = tostring (t)
if debug.getmetatable ( t )  then  no_unpack = no_unpack + 1;   tbl [#tbl +1] = i .. ' --- *** У таблицы ' .. tostring(t) .. ' есть метатаблица, которая в функции tbl_to_string не обрабатывается \n' end
local bracket = true  -- скобка  (начало) ---
--
       for k,v in next, t do
       if type(k) == "table" then
                   if bracket then  tbl [#tbl +1] = i .. " [\n"; bracket = false else tbl [#tbl +1] = i .. ", [\n" end
   if  dump(k, i .. tab, seen) then
                   tbl [#tbl +1] = "*** -> " .. tostring (k) .. '\n'
   no_unpack = no_unpack + 1
end
tbl [#tbl +1] = i .. " ] = "
else
                   if bracket then  tbl [#tbl +1] = i .. " [ "; bracket = false else tbl [#tbl +1] = i .. ", [ " end
if type(k) == "function"  or type(k) == "userdata" or type(k) == "thread"  then
  tbl [#tbl +1] = "*** " .. type(k)
  no_unpack = no_unpack + 1
   end
   if type(k) == "string"  then
           tbl [#tbl +1] = "'".. tostring(k) .. "'"
   else
                       tbl [#tbl +1] = tostring(k)
       end
tbl [#tbl +1] = " ] = "
               end

               if type(v) == "table" then
if  seen[v] then
           tbl [#tbl +1] = "*** -> " .. tostring(v) .. '\n'
   no_unpack = no_unpack + 1
else
                       dump(v, i .. tab, seen)  ---
   end
else
   if type(v) == "function"  or type(v) == "userdata" or type(v) == "thread" then
   no_unpack = no_unpack +1
tbl [#tbl +1] = "*** " .. tostring(v) .. '\n'
else
   if type(v) == "string"  then
        tbl [#tbl +1]= '"' .. v .. '" \n'
   else
                            tbl [#tbl +1] = tostring(v) .. "\n"
   end
end
end
       end
--
tbl[#tbl +1] = i .. " } \n"
   end
---------------------
   dump(t,i)
tbl[#tbl] = i .. "}".. key_tbl_stateOS .. string.format("%.0f", ltime_str) .. "\n" --- !!! заменяется последняя фугурная скобка ---
return  table.concat ( tbl), no_unpack    ----- Результат: 1) строка ;  2)  количество значений, не представимых в текстовом виде  ----
end
-----
---- Преобразование сереализованной таблицы (строки) в таблицу Lua (десереализация)  --------------------
--- Результат:  таблица  Lua   ------
function string_to_tbl (str_tbl)
--    message (" string_to_tbl ", "return " ..  str_tbl )
   if str_tbl:find("{") == nil then return nil end  ---  если в строке str_tbl нет {
local tbl , err_tbl = load ("return " ..  str_tbl )         ----    assert (load_OS ( "retur " .. 4))   -- $$$$
   if  err_tbl ~= nil  then
message (" string_to_tbl ", "!!! Ошибка в синтаксисе таблицы:  "  .. str_tbl)  --- err_tbl)
return nil
end
return  tbl()
end
----
Страницы: Пред. 1 2 3 4 5 6 7 8 9 10 11 ... 14 След.
Наверх