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

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

Страницы: Пред. 1 ... 15 16 17 18 19 20 21 22 23 24 25 След.
Подкиньте идею
 
Вариант 1. in memory database. Самая простая - sqlite3
Вариант 2. Библиотеки обмена:
раз - StaticVar от swerg https://quik2dde.ru/viewtopic.php?id=61
два - luashare от toxa https://quik2dde.ru/viewtopic.php?id=306

Вариант 3 - файлы. Но взаимные блокировки будет проблемой.

Вариант 4 - socket. Да, поднять свой socket server и обмениваться.

Вариант 5. Named Pipes. пишем библиотку клиента и сервера.
Утечка памяти, Происходит утечка памяти
 
Есть такая "особенность":
Вызов С функции форсирует более агрессивный режим работы сборщика мусора. Если код содержит много циклов с формированием локальных переменных, то мусор неохотно убирается.

Конструкция такого вида помогает, вместо прямого вызова сборщика.
       _G.SearchItems('money_limits', 0, 0, empty_func, "currcode")
Сравнение вещественных чисел., (55.3 < 55.3) - верно!
 
А зачем при вызове round(55.3, -2) параметр округления -2, если он 2.
Сравнение вещественных чисел., (55.3 < 55.3) - верно!
 
Ну да, в динамически типизированных языках, можно после округления привести в строку, обрезать до нужной длины, а потом обратно в число.
Сравнение вещественных чисел., (55.3 < 55.3) - верно!
 
Возьмите типовую функцию округления
Код
---@param num number
---@param idp any
local function round(num, idp)
    if num then
        local mult = 10^(idp or 0)
        if num >= 0 then
            return math.floor(num * mult + 0.5) / mult
        else
            return math.ceil(num * mult - 0.5) / mult
        end
    else
        return num
    end
end

И используйте

round(round(price/options.price_step, scale) * options.price_step, scale) > price1
Сравнение вещественных чисел., (55.3 < 55.3) - верно!
 
Обычно, все же, применяют округление к итоговому результату.
У Вас math.ceil(price/options.price_step) * options.price_step есть результат работы с вещественными числами. Его и надо привести к нужной точности, а потом уже сравнивать.
Status это работает ?
 
Владимир, Вы опять смешиваете язык и его синтаксис с поведением терминала. Даже не терминала, а особенностям потока данных, получаемого от ядра биржи.
Статус, биржа отдает, либо брокера на серверной части "режет" его.

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

Но язык здесь причем.

Что касается tonumber(GetCell(T,p1,0).value), то чтобы ответить надо понять из какого поля получаются данные. Если из колонки типа "строка", то и не будет работать, т.к. у него value нет.
Цитата
BOOLEAN SetCell(NUMBER t_id, NUMBER key, NUMBER code, STRING text, NUMBER value)                        
Функция задает значение для ячейки в строке с ключом «key», кодом  колонки «code» в таблице «t_id». Параметр «text» задает строковое  представление значение параметра «value». Параметр «value»  необязательный и по умолчанию равен «0». Для столбцов со строковыми  типами данных параметр «value» не задается. Если параметр «value» не  задан для ячеек всех остальных типов, то по столбцам, содержащим такие  ячейки, не будет корректно работать сортировка, фильтрация и условное  форматирование (см. Приложение 2). Функция возвращает «true» в случае  успешного завершения, иначе – «false».
Как сделать пересылку сообщений от скриптов на смартфон?
 
Цитата
Andy написал:
Бота создал, токен вписал
Попробовал запустить тестовый скрипт, теперь другая ошибка:
Подскажите пожалуйста что дальше?
Чтобы не засорять форум, напишите мне в личные сообщения.
Как сделать пересылку сообщений от скриптов на смартфон?
 
В сообщении написано же, что нужен валидный токен.
Необходимо сначала создать бота в телеграме, узнать его токен, вписать его в настройки: файл settings.ini.
Как сделать пересылку сообщений от скриптов на смартфон?
 
как обычно:
require('luaPipe')

Есть же пример, тестовый скрипт.
Как сделать пересылку сообщений от скриптов на смартфон?
 
На этом форуме https://forum.quik.ru/forum10/topic561/
и на Smart-Labe и MFD выкладывались такого рода утилиты. Даже с открытым кодом.
Вопросы Новичка
 
Я для себя не отключал его. Привык жить без глобальных переменных. Неучтенная глобальная - это повод проверить.

добавить параметр -d при вызове luacheck
добавить в файл .luacheckrc
allow_defined = true

Также по другим сообщениям https://luacheck.readthedocs.io/en/stable/warnings.html

Часть из них можно добавить в список исключений ignore
В принципе, все есть в документации https://luacheck.readthedocs.io/en/stable/index.html
Вопросы Новичка
 
Я использую luacheck (по мне самый лучший). В VS Code он не сложно подключается. Но и сами плагины lua для VS Code тоже умеют отлавливать простые ошибки.
Если используете всеми любимый Notepad ++, то для него надо искать плагины, поддерживающие проверку синтаксиса. Или запускать в командной строке luacheck с проверяемым скриптом, что, конечно, не так удобно.
Вопросы Новичка
 
Если у Вас не синтаксическая ошибка, а логическая, то, конечно, ошибки не будет при компиляции.
Такие ошибки ловятся дебагом. Но для индикатора, лучше делать print-debug. Т.е. выводить значения в некий поток (файл лога) и смотреть на данные.

Типовая ошибка в индикаторах связана с дырявыми массивами данных. Т.е. не заполнены данные для каждого индекса.
Если индекса нет, т.е. дырка на графике, это не повод пропустить данные в массиве.

А чтобы Квик не умирал от бесконечного потока сообщений об ошибке, лучше завернуть критическую секцию в pcall и перехватывать текст ошибки, выводя его все один раз для одного и того же сообщения.
как определить окончательный расчет индикатора, при создании или редактировании индикатор рассчитывается несколько раз
 
Цитата
Александр написал:
Ещё вопрос по функции SetValue. Она не работает по последней формирующейся свече?
Для последнего индекса происходит возврат данных из функции OnCalculate. Эти данные устанавливаются на график.
Так что даже если вы используете функцию, все равно произойдет переопределение.
Вопросы Новичка
 
Добавляете индикатор в доступные скрипты lua и запускаете. Будет ошибка.
А лучше пользоваться линтерами, чтобы легче было.
FIFO (англ. First In, First Out – ), Вопрос
 
Это методика учета. Никаких проблем реализовать FIFO, LIFO, по средней нет.
Вопрос для чего. Обычно ее используют для исчисления прибыли. Собственно, если я правильно помню эту картинку, то это сетка заявок (сделок), где как раз фин.рез так и считают.
При этом брокер может считать совсем по-другому.

А с токи зрения баланса инструмента - нет разницы. Одни все одинаковые.
Перехват события
 
Вы можете прочитать дату экспирации в свойствах инструмента. Используя свой календарь, заменить инструмент даже раньше или позже чем это предложит терминал.
Заявка по минимуму последней свечи
 
Вот Вам документация и примеры

http://luaq.ru/CreateDataSource.html
Заявка по минимуму последней свечи
 
Подписываетесь на поток данных один раз

   local ds, err = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL);
   if not ds then        действия при ошибке
   end

Далее можете в бесконечном основном цикле просто тыкать в поток и проверять изменился ли ds:Size(). Для этого, естественно нужны переменная, где хранится прошлое значение. Можете ее глобальной сделать, можно через замыкаение все сделать, можно через класс, как угодно.

Если интервал минута, то индекс и будет увеличиваться раз минуту при наличии сделок, не раньше. Это же индекс временного интервала. Пока новый не наступил, чего ему увеличиваться.
Заявка по минимуму последней свечи
 
Цитата
Сергей написал:
Если я правильно понимаю мне в моём случае нужно писать так, да?
DS,Error = CreateDataSource('QJSIM', 'SBER', INTERVAL_H1);
local Last = math.max -- что-то там, что даст мне индекс последней полученной свечи
local Price = DS:L(Last);
message('Price: '..Price);
Если задача получить последний бар (текущий), то это ds:Size()
Заявка по минимуму последней свечи
 
ds:Size() - это текущий бар.
Но новый бар появляется только по совершению сделки.
Допустим минутный бар. Он может быть уже по факту завершенным, т.е. уже началась новая минута. Но т.к. еще нет сделок в новом интервале, то нового бара (увеличения индекса) еще не будет.

Если алгоритм требует простого увеличения номера бара, то можно просто контролировать увеличение номера при получении ds:Size().
А если алгоритм требует совершения действий именно при наступлении нового временного интервала, то надо контролировать время сервера и время бара.
Заявка по минимуму последней свечи
 
У объекта ds есть метод Size(), который вернет последний индекс бара. При этом закрытый он или нет надо проверять по времени. В большинстве случаев ds:Size() - это послдений текущий бар.
Т.е. закрытый будет ds:Size().

А 1 - это будет первый бар. В Квике, в отличии от MT, нумерация от 1.

Также важно отметить, что получать поток данных через CreateDataSource надо делать один раз, сохранив его в переменную.

Все методы объекта ds описаны в документации к языку.
Отладка QUIK 8.11
 
А зачем перешли на lua 5.4.1? Опять библиотеки перекомпилировать, скрипты перекомпилировать.
Что такого важного увидели в этом релизе, что надо было переходить. При этом, что текущий релиз 5.4.2.
Неприятность таблицы "Клиентский портфель", Вопрос "совсем новичка":
 
А зачем два раза получать строку через getItem?
Строку проще получить один раз, проверить что она не пустая, т.к. такое бывает и потом уже из нее получать данные, сверив, что она по нужному инструменту, счету.
Кто как решает вопрос с заявками/сделками?
 
Владимир, на самом деле, действительно на грани, как минимум непонимания.

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

Теперь Вы просто собираете все. При этом все это обсуждалось на этом форуме уже много много лет, предложены разные варианты решений.


Я Вам могу еще одну особенность дать - в таблице trades (это там где сделки хранятся, она же по колбеку OnTrade), номер транзакции появляется не всегда сразу. Он может быть 0, а потом меняется на корректный.
Изменение цены стоп-ордера через график
 
Все зависит от алгоритма. Если предполагается один ордер, то его можно отловить просто.
Надо писать комментарий в ордер, тогда при перетаскивании он сохранится. Далее надо ввести некую задержку ожидания появления нового ордера - это самый "тонкий" момент, т.к. все зависит от сервера брокера, канала связи.

В колбеке ловите момент, что старый ордер был снят, хотя можно и не ловить, т.к. если Вы снимаете ордер через скрипт, то это итак известно. Остальное - это внешнее воздействие.
Теперь просто ждете пока не появится новый ордер с тем же комментарием, а если не появился через введенную задержку - выполняете какие-то действия, например, перевыставляете.
Получение подтаблицы в отдельную таблицк
 
Если это не массив, то необходимо использовать другой итератор pairs. ipairs только для непрерывных массивов.

for i,tab_data in pairs(ind) do
Возможно ли в OnTransReply получение номера снимаемой/передвигаемой заявки?, при использовании Move/Kill order
 
Цитата
Владимир написал:
Roman Azarov, И что делать? А по OnOrder это дело ловится? Если верить описанию, при любом изменении параметров заявки эта штуковина должна бы вызываться (именно по ней вкупе с OnTrade я и собираюсь отслеживать состояние торгов).
Делать что? Колбеком OnOrder Вы можете отследить изменение параметров ордера, только не забывайте, что он приходит не один раз.
Если же при снятии была ошибка, то она придет только в OnTransReply, OnOrder не будет вызван. Так что надо либо контролировать транзакцию, либо опрашивать ордер, проверяя его состояние.
Возможно ли в OnTransReply получение номера снимаемой/передвигаемой заявки?, при использовании Move/Kill order
 
Цитата
Roman Azarov написал:
Юрий Балашов, добрый день!

В ответе на транзакцию снятия заявки (KILL_ORDER) номер снимаемой заявки  не  приходит.
В ответе на транзакцию передвижения заявки (MOVE_ORDERS) приходит только номер  новой  заявки.

Также, заметим, что данный ответ идет от Торговой Системы, а не от терминала.
Все же при удачном снятии номер заполнен в поле order_num, по крайней мере на вашем тестовом контуре.

OnTransReply sec_code SRZ0 result_msg: Заявка 1953471058887603012 снята. Неисполненный остаток: 1. status: 3 trans_id: 64469037 order_num: 1953471058887603012 price: 0 qty: nil account  client_code SPBFUT0018n firmid nil brokerref
Возможно ли в OnTransReply получение номера снимаемой/передвигаемой заявки?, при использовании Move/Kill order
 
Вопрос был понятен. Не понятна проблема. При подаче транзакции мы знаем номер модифицируемого ордера и номер поданной транзакции.
Т.е. есть структура {trans_id, order_num}  


Ели транзакция прошла успешно, то номер снимаемого ордера заполнен в ответе транзакции.
Если возникла ошибка то он не заполнен. Но у Вас есть структура, где по номеру транзакции есть номер ордера по которому возникла ошибка.
Возможно ли в OnTransReply получение номера снимаемой/передвигаемой заявки?, при использовании Move/Kill order
 
Если задача перехватить ответ для отправленной транзакции, то это лучше делать по номеру транзакции, который был передан. Номер транзакции тоже известен при ее подаче, а ответ этот номер содержит.
Возможно ли в OnTransReply получение номера снимаемой/передвигаемой заявки?, при использовании Move/Kill order
 
Чтобы снять ордер надо знать его номер, а если он известен, то зачем его получать в колбеке?
Изменения в работе с колбеками LUA в новой версии
 
А с чего вообще что-то должно поменяться для "наблюдателя" скрипта? С его точки зрения каким был колбек таким и остался. На то он и колбек, назание само за себя говорит.

Не думаю что пойдут на изменение синтаксиса. Я бы больше ожидал стабильности и предсказуемости в вызовах. Сейчас только несколько колбеков типа подключения-отключения-ответ транзакции можно использовать.
Остальные не вызывают доверия и надежней баз них. А то когда у тебя колблек от событий прошедших часы назад прилетает после перезапуска терминала, то проще не смотреть на них.
Обсудим диалог на Lua?
 
Здесь я с Владимиром согласен, не очень понятно зачем вносить лишние сущности в виде сторонних библиотек, если почти все что надо от скрипта можно сделать на qlua.
Да, нельзя показать картинки, не очень удобно выводить многострочный текст и т.д., но бантики не имеют отношения к тому что надо от интерфейса скрипта.

Писали же как-то программы раньше. Даже некое подобие 3-х мерного изображения выводили до Open GL. И ничего, научная работа велась.


Если уж интерфейс такой сложный, что он должен определять поведение скрипта, то проще написать весь скрипт на плюсах (QScalp), зачем мучить LUA, да еще VCLua на турбо паскале, которое притянет за собой
свои зависимости и проблемы синхронизации. Не говоря уже про то, что она, мягко говоря, устарела.
Обсудим диалог на Lua?
 
Владимир, а в чем, собственно, проблема?

И команды и переключатели, и поля ввода, горячие клавиши прекрасно делаются на qlua. Просто к таблице надо подойти как к объекту, наполнив его методами, обратными вызовами.
Я бы даже сказал, что надо написать свой DSL. Тогда, вызывая конструктор окна с настройками, получим уже готовый объект. В частности, у меня окно рисуется через таблицу настроек, все остальное уже заложено в объект. Надо добавить переключатель или что-то другое - одна строка таблице настроек.


Как к этому подойти - ну явно не надо писать простыню в main. Придется использовать очереди событий, сообщений и др. Также не советую использовать номера колонок, строк как идентификатор ячейки - это затрудняет модификацию окна. Часто просят переставить местами что-то. Это не должно приводить к переписыванию всего кода. Надо просто в одном месте поменять описание поля (колонки) таблицы.
Добавление Индикаторов.
 
Ну код индикатора не оптимален. Это влияет на производительность, особенно если запущено на склейке графика, с очень большим количеством баров.
Добавление Индикаторов.
 
Вот исправленное. Прогнал через линтер, помимо кавычек еще вместо минус было тире.
Явно хранили текст в Word или в чем-то подобном.

Код
Settings = {
    Name = "*StohRSI",
    round = "off",
    Period = 5,
    Per_K = 9,
    PeriodSO = 5,
    Shift = 3,
    VType = "Close", --Open, High, Low, Close, Volume, Median, Typical, Weighted, Difference
    line = {
           {Name = "RSI", Type = TYPE_LINE, Color = RGB(255, 255, 128)},
           {Name = "SO", Type = TYPE_LINE, Color = RGB(255, 0, 0)},
           {Name = "Sign", Type = TYPE_LINE, Color = RGB(128, 255, 128)},
           {Name = "line 20", Type = TYPE_LINE, Color = RGB(0, 128, 255)},
           {Name = "line 80", Type = TYPE_LINE, Color = RGB(0, 128, 255)}
           }
    }

    function Init()
       func = RSI()
       return #Settings.line
    end

    function OnCalculate(Index)
       if not CandleExist(Index) then
           return nil
       end
       return func(Index, Settings)
    end

    function RSI() --Relative Strength I("RSI")
       local Up = {}
       local Down = {}
       local val_Up = {}
       local val_Down = {}
       local K_MA1=MA()
       local K_MA2=MA()
       local D_MA=MA()
       local proSO={}
       local Out = {}
    return function (I, Fsettings, ds)
    local Fsettings=(Fsettings or {})
    local P = (Fsettings.Period or 14)
    local PK = (Fsettings.Per_K or 5)
    local PerSO = (Fsettings.PeriodSO or 5)
    local S = (Fsettings.Shift or 3)
    local PD = (Fsettings.Period_D or 3)
    local VT = (Fsettings.VType or "Close")
    local R = (Fsettings.round or "off")
    local MD = (Fsettings.Metod_D or "SMA")
    local M = (Fsettings.Metod or "SMA")
    if I <=PerSO then
       Up[I] = 0
       Down[I] = 0
    end
    if I>PerSO then
       local Val = Value(I,"T",ds)
       local ValPrev = Value(I-1,VT,ds)
       if ValPrev < Val then
           Up[I] = Val - ValPrev
       else
           Up[I] = 0
       end
       if ValPrev > Val then
           Down[I] = ValPrev - Val
       else
           Down[I] = 0
       end
       if (I == P) or (I == P+1) then
           local sumU = 0
           local sumD = 0
           for i = I-P+1, I do
               sumU = sumU + Up[i]
               sumD = sumD + Down[i]
           end
           val_Up[I] = sumU/P
           val_Down[I] = sumD/P
       end
       if I > P+1 then
           val_Up[I] = (val_Up[I-1] * (P-1) + Up[I]) / P
           val_Down[I] = (val_Down[I-1] * (P-1) + Down[I]) / P
           Out[I] = 100 / (1 + (val_Down[I] / val_Up[I]))
       end
    end
       if I > PK*2 then
           RsiOut=D_MA(I,{Period=PK, Metod = M, VType="Any", round=R}, Out)
       end
        _,_,proSO[I]= MaxMin(I,5,ds,3)
       if I>=(PK+3-1) then
       SignSO=D_MA(I, {Period=3, Metod = "SMA", VType="Any", round="off"}, proSO)
       end
           return rounding(RsiOut, 4),rounding(proSO[I], 4),rounding(SignSO, 4),rounding(Out[I], 4)
       end
    end

    -------------------------------------------------------
    -------------------------------------------------------
    function MA() --Moving Average ("MA")
    local t_SMA = F_SMA()
    local t_EMA = F_EMA()
    return function(I, Fsettings, ds)
       local Out = nil
       local Fsettings=(Fsettings or {})
       local P = (Fsettings.Period or 9)
       local M = (Fsettings.Metod or "EMA")
       local VT = (Fsettings.VType or "Close")
       local R = (Fsettings.round or "off")
       if M == "SMA" then
           Out = t_SMA(I, P, VT, ds, R)
       elseif M == "EMA" then
           Out = t_EMA(I, P, VT, ds, R)
       else
           Out = nil
       end
       return rounding(Out, R)
    end
    end
    ------------------------------------------------------
    function MaxMin(ind,Pk,ds,Sk)
       if ind < Pk+Sk then
           return nil
       else
      local suCM=0
      local suMM=0
            for i = ind - Sk+1, ind do
                MAX = Value(i-Pk+1,"High",ds)
                MIN = Value(i-Pk+1,"Low",ds)
            for k = 0, Pk-1 do
                MAX=math.max(MAX,Value(i-k,"High",ds))
                MIN=math.min(MIN,Value(i-k,"Low",ds))
            end
       --message('тран:'..OutWR,1)
           suCM=suCM+(Value(i, "Close", ds)-MIN)
           suMM=suMM+(MAX-MIN)
           end
       local TenKu=(MAX+MIN)/2
       local OutWR=100*(Value(ind,"Close", ds)-MIN)/(MAX-MIN)
       local proKol =100*suCM/suMM
       local wpr = ((MAX - Value(ind,"Close", ds)) / (MAX - MIN)) * (-100)
           return rounding(TenKu, 6),rounding(OutWR, 6),rounding(proKol, 6)
    end
    end
    ------------------------------------------------------------------
    function F_SMA()
    return function (I, Period, VType, ds, R)
    local Out = nil
       if I >= Period then
           local sum = 0
           for i = I-Period+1, I do
               sum = sum +Value(i, VType, ds)
           end
           Out = sum/Period
       end
       return rounding(Out,R)
    end
    end
    ---------------------------------------------------------
    function F_EMA()
    local EMA_TMP={}
    return function(I, Period, VType, ds, R)
    local Out = nil
       if I == 1 then
           EMA_TMP[I]=rounding(Value(I, VType, ds),R)
       else
           EMA_TMP[I]=rounding((EMA_TMP[I-1]*(Period-1)+2*Value(I, VType, ds)) / (Period+1),R)

       end

       if I >= Period then
           Out = EMA_TMP[I]
       end
       return rounding(Out,R)
    end
    end
    -------------------------------------------------------
    function Value(I,VType,ds)
    local Out = nil
    VType=(VType and string.upper(string.sub(VType,1,1))) or "A"
       if VType == "O" then        --Open
           Out = (O and O(I)) or (ds and ds:O(I))
       elseif VType == "H" then     --High
           Out = (H and H(I)) or (ds and ds:H(I))
       elseif VType == "L" then    --Low
           Out = (L and L(I)) or (ds and ds:L(I))
       elseif VType == "C" then    --Close
           Out = (C and C(I)) or (ds and ds:C(I))
       elseif VType == "V" then    --Volume
           Out = (V and V(I)) or (ds and ds:V(I))
       elseif VType == "M" then    --Median
           Out = ((Value(I,"H",ds) + Value(I,"L",ds)) / 2)
       elseif VType == "T" then    --Typical
           Out = ((Value(I,"M",ds) * 2 + Value(I,"C",ds))/3)
       elseif VType == "W" then    --Weighted
           Out = ((Value(I,"T",ds) * 3 + Value(I,"O",ds))/4)
       elseif VType == "D" then    --Difference
           Out = (Value(I,"H",ds) - Value(I,"L",ds))
       elseif VType == "A" then    --Any
           if ds then Out = ds[I] else Out = nil end
       end
    return Out
    end

    function rounding(num, round)
    if round and string.upper(round)== "ON" then round=0 end
    if num and tonumber(round) then
       local mult = 10^round
       if num >= 0 then return math.floor(num * mult + 0.5) / mult
       else return math.ceil(num * mult - 0.5) / mult end
    else return num end
    end
Одновременная работа двух Торговых систем с одним инструментом, подкиньте идей
 
Владимир, это же написано в документации к расширению языка от разработчика, документ Использование Lua в Рабочем месте QUIK https://arqatech.com/upload/iblock/194/quik_lua.zip
Простая схема передачи данных через очередь из колбека в дополнительный поток скрипта.
Одновременная работа двух Торговых систем с одним инструментом, подкиньте идей
 
Хранить надо не потому что инструменты или алгоритмы разные, а потому, что при рестарте скрипта (а это нормальное, очень частое явление) надо восстановить и актуализировать свое состояние.
Это просто некий state. Выключите скрипт (или Квик упал) - потеряете.
Одновременная работа двух Торговых систем с одним инструментом, подкиньте идей
 
Да, такое просят иногда сделать.
К примеру, один алгоритм торгует один тайм-фрейм, другой - второй.
На длительном периоде работы, фин рез "как-бы" сходится.
Такая задача обязательно требует хранения текущего состояния каждого алгоритма, т.к. чтение данных таблиц Квика уже не даст результат. Впрочем, это стоит итак делать.
Также не лишним будет помечать сделки комментарием, чтобы понимать, что это сделка этого алгоритма.

Такая задача имеет и проблемы. Т.к. позицию мы можем получить только из сделок, то важно, чтобы не было перерывов в работе, т.к. Квик удаляет сделки на следующие сутки.
Код
т.е. придерживаться правила - один скрипт - один инструмент?
Это никак не соотносится с вопросом. Ведь можно сделать один скрипт на 100 разных инструментов, торгующих одним и тем же алгоритмом, или разными.
Предложение к разработчикам
 
Вы, как обычно, не изучив язык, начинаете осуждать. Про goto во всех руководствах по языку сказано, что он не работает в блоках (намек - есть область видимости переменных).
ФУНКЦИОНАЛЬНОСТЬ программы не влияет на сложность. Кода больше, да. А вот сложность алгоритма - это вопрос методики, либо сам алгоритм, как таковой сложный.

Не умеете без goto, пишите с ним. Но я уже забыл когда последний раз его использовал, лет 25 назад возможно.

внутрь блока if, while - серьезно?
На демо сервере junior quik не передается таблица firms при смене пользователя
 
Ну да, я поэтому и спросил про другой способ. Проверим как это будет жить.

В целом, ответы типовые - все к брокеру. Может, все же, мы вернемся к вопросу старта Квика и к понятию "Я все с сервера загрузил после очистки таблиц". Тогда и вопросы все отпадут. А то ведь у своего брокера я могу еще спросить, а чужого уже никак.
isConnected и пара неприятных моментов
 
Все же волновая функция - это про вероятность. У нас же есть пакеты данных и, теоретически, каждый пакет обладает информацией, что он несет. Как накладная на груз.
Поэтому мы могли бы понимать, что последнее, что мы получили - это такие-то данные. Либо мы просто ждали бы пакет с таким типом данных, фильтруя другие. Да, мы не знаем последние ли это данные, справедливо. Но и понятие "последние" не применимо здесь. я бы назвал их текущие. Но они бы были не обезличенные.
Также пакет мог бы нести данные о смысле этих данных - справочник, очистка таблицы, заполнение таблицы, информация о цене сделки и т.д., и, скорее всего, несет. Часть этого есть в колбеках, но явно недостаточная.

А вот с точки зрения времени - да, у нас полная неопределенность. Но, как мне кажется, обладай бы мы полной информацией о смысле полученных данных, ошибках сервера (читай больше колбеков) в данный момент - это было бы не столь критично.


В соседней ветке написал про открытие рынка с утра, когда вдруг позиция становится 0, а тут же опять корректная. Т.е. явно идет либо очистка данных (был вызван CleanUp), чтобы далее получить новые, либо некий пакет данных, содержащий неполную, либо "технологическую" информацию, а скрипт в этот момент времени измерил состояние. Я к сожалению не выводил в лог полную таблицу future_client_holding, так бы было ясно что-то: пустая она, неполная и т.д.  
Предложение к разработчикам
 
А зачем "рекомендованное", если есть книга от автора языка.
Купите или "купите" уже книгу Роберту Иерузалимски "Программирование на языке lua", если уж на сайте языка никак не получается.

В ней есть все, чтобы начать писать на lua.
А вот даже примеры решения заданий из книги https://github.com/bobeff/playground/tree/master/programming-in-lua
На демо сервере junior quik не передается таблица firms при смене пользователя
 
В продолжении вопрос:
Если у клиента подключен счет для срочной секции (в том числе единый счет) можно ли утверждать, что таблица futures_client_limits всегда заполнена (по аналогии с  money_limits для фондовой секции)?
На демо сервере junior quik не передается таблица firms при смене пользователя
 
Подниму вопрос. Терминал работает круглые сутки, не выключаясь. У одного брокера регулярно утром происходит какая-то...

[INFO  2020-10-23 08:15:17] :           OnDisconnected
[INFO  2020-10-23 10:00:05] :           OnCleanUp
[INFO  2020-10-23 10:00:11] :           OnConnected flag true

После OnConnected проверяем позицию по инструменту - она 0.
И через несколько секунд уже корректная.

Раз уж мы поняли, что актуальность данных мы не можем получить:

Я вижу колбек OnCleanUp (судя по описанию и времени это смена сессии), но только потом OnConnected. Как-то странно для смены сессии. По какому признаку мне понять, что пока рано идти и смотреть позицию в таблице futures_client_holding?

Кроме идеи дождаться первого OnFuturesClientHolding в голову ничего не приходит.
debugview - где его взять и как им пользоваться?
 
Отладка - это хорошо. Но писать тесты на свой код лучше и надежней.
Там где без отладочной информации не обойтись методика "print debug" помогает (я предпочитаю лог файлы). Если Вы пишите скрипты для себя, то, конечно, можете и отлаживать, а если для внешних клиентов, то как Вы будете у них отлаживать?

А если уже сравнивать с MT, то там отладка идет на исторических данных. Но и странно было бы ожидать отладку в реальном времени. Остановите поток данных?
Я не говорю, что если бы отладка была в Квике, то это не надо, но ее ценность не так велика. Плюс никто не мешает написать wrapper функций Квика и подкидывать данные из файлов для эмуляции потока, запуская на чистом lua. Тогда тесты станут еще более предсказуемыми.
Как узнать текущие чистые позиции?
 
Не проверять в клиринг. Т.е. надо проверить статус сессии и контролировать позицию только в торговое время.
Плюс, если Вы делаете это из колбека OnFuturesClientHolding, то он дергается по любому поводу, связанному с изменением в таблице (вар. маржа и т.д.). А позиция та же самая. В клиринг особенно.
Т.е. это не самый удачный колбек, в плане получения только позиции.
Предложение к разработчикам
 
Не ясно только одно: что мешает прямо сейчас писать на с/с++ используя lua-api?

Вот, для примера, неплохая библиотека обертка методов Квика - https://github.com/elelel/qluacpp
Пишите на здоровье.

Как все это время другим удается писать на чистом lua, загадка, наверно.
Надеюсь разработчики даже не будут рассматривать это пожелание.
Страницы: Пред. 1 ... 15 16 17 18 19 20 21 22 23 24 25 След.
Наверх