Баги QUIK 8.13

Страницы: Пред. 1 2
RSS
Баги QUIK 8.13
 
Roffild, Лапуль, я с раннего детства не перевариваю распальцованных дураков. Повторяю для особо одарённых: в кодах скулящих по любому вопросу неучей я ковыряться не намерен. А "гениальное решение", лапуль, надо УМЕТЬ видеть - бездарности способны разве что смотреть, как баран на новые ворота. :wink:  
 
Цитата
Roffild написал:
гениальное решение проблем
Код
local mypositions = {
  'SBER' = {
    'TQBR' = {
      aveprice = 123.23,
      amount = 1000,
      stopprice = 120.12,
      direction = 1,
      status = 1, -- active, no pending orders
      checkStop = function(self, price)
        if self.status == 1 then
          if self.direction > 0 then -- long
            if price <= stopprice then
              self:coverByMarket()
            end
          else if self.direction < 0 then -- short
            if price >= stopprice then
              self:coverByMarket()
            end
          end
        end
      end
    }
  },
  'GAZP' = {
    -- ...
  }
}

function OnAllTrade(at)
  -- find position in O(1) 
  local spos = mypositions[at.sec_code]
  if spos then
    local cpos = spos[at.class_code]
    if cpos then
      -- position exists
      cpos:checkStop(at.price)
    end
  end
end
 
Цитата
Владимир написал:
Roffild, Лапуль, я с раннего детства не перевариваю распальцованных дураков. Повторяю для особо одарённых: в кодах скулящих по любому вопросу неучей я ковыряться не намерен. А "гениальное решение", лапуль, надо УМЕТЬ видеть - бездарности способны разве что смотреть, как баран на новые ворота.  
Нельзя увидеть, чего нет. Покажи! Или ты даже тот код не осилил? Ах, да "в кодах скулящих по любому вопросу неучей я ковыряться не намерен"... не программист ты.

Цитата настоящего программиста: "Хватит болтать! Покажи мне код!"
 
Anton, как раз на создании mypositions твой код и нарвется на тот баг. OnAllTrade тут не поможет и вообще о других сделках.

Роль OnAllTrade выполняет getParamEx2("SPBFUT", v.sec_code, "BID").param_value в моем коде.
 
Roffild, Лапуль, кода своего я здесь приводил НЕМЕРЯНО! И кода РАБОТАЮЩЕГО, без скулежа про "плохие и непродуманные API". Покопайтесь в моих сообщениях, коль неймётся. И в третий раз повторяю: "В кодах скулящих по любому вопросу неучей я ковыряться не намерен". Сколько раз повторить, чтобы дошло?
 
Цитата
Владимир написал:
Roffild, Лапуль, кода своего я здесь приводил НЕМЕРЯНО! И кода РАБОТАЮЩЕГО, без скулежа про "плохие и непродуманные API". Покопайтесь в моих сообщениях, коль неймётся. И в третий раз повторяю: "В кодах скулящих по любому вопросу неучей я ковыряться не намерен". Сколько раз повторить, чтобы дошло?
Ну, не повторяй... Я вообще не понимаю, что тролль забыл в этой теме...
 
Roffild, Тролль эту тему создал, лапуль. :wink:  
 
Цитата
Владимир написал:
Roffild, Тролль эту тему создал, лапуль.  
А ты пытаешься его изгнать? В чём ТВОЯ миссия? Или смысл жизни? Даж интересно стало.
 
Roffild, Я же тыщу раз говорил, лапуль: я с детства не перевариваю распальцованных дураков и редко спускаю им их "поучения".
 
Владимир, и много уже спустил? Если не спускать "поучения", которые тебя даже не касаются, то жизнь теряет смысл? И можно при спуске не стать "распальцованным дураком", как они? И как это распознать?
 
Roffild, Почему же "меня не касаются"? Когда на форум приходит очередной придурок с гнутыми пальцами, ему очень полезно бывает отвесить пару щелчков по носу, иначе, как показывает опыт, у них окончательно крышу сносит, и они засирают всё словесным поносом на три мили вокруг. Как известно, без сопротивления говно, как и газ, заполняет любой объём.
 
Владимир, спасибо, что поделился с нами своей гопно-туалетной философией окружающего нас токсичного мира. Я больше не стану тебя отвлекать от миссии очищения этого форума. Да, обойдет бан тебя стороной в этом опасном деле...
 
21. Попытался обойти баг isConnected()==1 через OnAllTrade(). Щаз! Это же кривой QLua!
OnAllTrade() НЕ вызывается, если "Таблица обезличенных сделок" НЕ открыта. И если ТОЗ случайно закрыть, то OnAllTrade() НЕ вызывается. Квику пофиг даже на галку в Настройках. QLua не может даже о статусе ТОЗ сообщить.

Код
---@class roffild
---@field LAST_TIME_ANONYMIZED_DEAL qluaDateTime Время последней обезличенной сделки
---@field ISTRADINGALLOWED_SECONDS number Секунд в ожидании обезличиной сделки (по умолчанию = 3)
local roffild = {
    LAST_TIME_ANONYMIZED_DEAL = os.sysdate(),
    ISTRADINGALLOWED_SECONDS = 3,
}

roffild.LAST_TIME_ANONYMIZED_DEAL.hour = 0 -- для начальной разницы времени

---Функция должна вызываться в `OnAllTrade()`, когда она переопределена.
function roffild.OnAllTrade(alltrade)
    ---@type qluaDateTime
    roffild.LAST_TIME_ANONYMIZED_DEAL = alltrade.datetime
end

function OnAllTrade(alltrade)
    roffild.OnAllTrade(alltrade)
end

---`isConnected() == 1` ещё ДО ввода PIN при Двухфакторной аутентификации. Обход бага через `OnAllTrade()`. \
--- \
---**ЗАВИСИТ от интенсивности "Таблица обезличенных сделок".**
---@param seconds? number Секунд в ожидании обезличиной сделки (по умолчанию = 3 = `ISTRADINGALLOWED_SECONDS`)
---@return boolean
function roffild.isTradingAllowed(seconds)
    return (isConnected() == 1
        and (os.time(os.sysdate()) - os.time(roffild.LAST_TIME_ANONYMIZED_DEAL)) <= (seconds or roffild.ISTRADINGALLOWED_SECONDS))
end
 
Цитата
Roffild написал:
OnAllTrade() НЕ вызывается, если "Таблица обезличенных сделок" НЕ открыта
Или не создан тиковый датасорец по инструменту, или не открыт тиковый график по инструменту. Но это закажет только один инструмент. Подписка на ВСЕ инструменты в цикле с целью заказать ТОС целиком работает плохо, потому что на каждой итерации идет перезаказ ТОС, а подписаться на все разом нельзя. Поэтому в нынешних реалиях:
1) ТОС должна быть всегда открыта, заказ данных должен быть настроен руками
2) юзер должен быть проинструктирован никогда ТОС не закрывать и особо не щелкать по тиковым графикам во избежание автоматической отписки от чего-нибудь
3) сам скрипт подписываться на тики не должен во избежание автоматической отписки при его завершении
4) юзер должен периодически поглядывать в настройках, что все галки на месте или
4.1) перед запуском квика некая внешняя софтина должна заглядывать в info.ini и фиксить подписки в случае чего.

По-хорошему нужны функции SubscribeAllTrades/UnsubscribeAllTrades с возможностью подписаться на ВСЕ за один вызов. Но арка почему-то не хочет этого делать. Либо нужно реализовать вариант, предложенный неоднократно: фильтры устанавливаются автоматически при любой подписке, как сейчас, а сбрасываются только из диалога заказа данных. Тоже не хочет.
 
Anton, Хоспидя, как сложно-то!..   :smile:

Предлагаю схему попроще:
1) ТОС должна быть всегда закрыта
2) юзер должен быть проинструктирован никогда ТОС не открывать, ибо она ему нафиг не нужна.
3) сам скрипт подписываться ни на что не должен во избежание любых потенциальных глюков.
4) юзер волен делать всё, что ему заблагорассудится, если он запустил скрипт с началом торгов и остановит его перед выключением компа.
4.1) Все "некие внешние софтины" - поганой метлой!
 
Цитата
Владимир написал:
никогда ТОС не открывать, ибо она ему нафиг не нужна.
можно и квик никогда не открывать, чего мелочиться-то.

Цитата
Владимир написал:
если он запустил скрипт с началом торгов и остановит его перед выключением компа
значит, он проснулся по будильнику к началу торгов и далеко не отойдет до закрытия. Не завидую ему.
 
Anton, Квик торгует, денюшку приносит, а ТОС нет.

Я просыпаюсь в любое удобное для себя время, обычно уже после начала торгов на СПб и до на Мосбирже, запускаю пару Квиков (иногда аместе, иногда вразнобой), свободно ухожу куда надо если надо, выключаю комп, когда спать ложусь или когда посчитаю нужным, иногда уже после закрытия биржи, могу вообще не выключать. Куда уж свободнее? Только вот автоматическую сверку с портфелем брокера никак руки не дойдут сделать.
 
Цитата
Владимир написал:
Квик торгует, денюшку приносит, а ТОС нет.
Не везде так, а кое-где даже совершенно наоборот.

Цитата
Владимир написал:
удобное для себя время
Для меня любое заранее назначенное время - неудобное. Тксть солнце всходит и заходит по веленью моему.
 
Anton, Не зааю как там "не везде", а у меня именно так. :smile:

А кто говорил про "заранее назначенное время"? Я вот совершенно без понятия, когда я его завтра включу и когда выключу. Ах, да - завтра торгов нет. Ну, сегодня был без понятия, выключил минуту назад.
 
Цитата
Владимир написал:
Anton, Хоспидя, как сложно-то!..   ::

Предлагаю схему попроще:

4) юзер волен делать всё, что ему заблагорассудится, если он запустил скрипт с началом торгов и остановит его перед выключением компа.

а нахрена мне твой скрипт  или комп останавливать  ?  Знаю что сейчас начнешь на меня ругаться , но  мне так удобнее  и это ближе  к  моему желаемому  желанию типа :  "" включил  и забыл !!!  ""  Что уж тут греха таить - скрипт конечно вылетает иногда  или по очередно  с Квиком , но  и я не на всегда  свой комп  покинул  . к тому же  автозапуск и авто .старт и без меня нормально с перезапуском справляются.
 
БорисД, Что, и ты не выдержал, опять сюда влез? :smile:

Да знаю я, что ты лентяй ещё больший, чем я. Ну, не выключай. А мне комп тоже жалко - пусть отдохнёт от этой биржи. Может быть, глючить будет меньше в качестве благодарности. :smile:  
 
Цитата
Владимир написал:
БорисД, Что, и ты не выдержал, опять сюда влез? ::

Да знаю я, что ты лентяй ещё больший, чем я. Ну, не выключай. А мне комп тоже жалко - пусть отдохнёт от этой биржи. Может быть, глючить будет меньше в качестве благодарности. ::  
да  залез сюда  глядя на тебя. И лишь по той причине что видел воочую наши эксперименты отследить  20 тыс. инструментов одновременнно твоим скриптом.

Нет , Володь  - я не конченный лентяй  , просто  работы много и постоянно следить  за  роботом не имею такой возможности ,  Квик на автозапуске а твой скрипт  в нем всегда запущен  и  если я с ним не эксперементирую то и проблем  с ним не имею .  Еще раз напомню что цель моя получить робота по типу : - включил и забыл  и контролируй его  по мере наличия такой возможности.  Я не могу  уверять  здесь народ что он у меня  за последние 2 недели не глючил ( вернее он или Квик )  но  когда я заглядываю на свой сервак то не видел чтобы за последние 2 недели   он не глючил , но тут  твой файл логов  не совсем полный и не все  ситуации фиксирует ,

 Кстати про 20 тыс. тикеров  - когда мы вместе за этим наблюдали на твоем  не самом сильном по железу ноуте . то мы все таки дождались  глюков   и давай  новый релиз сначало  доделывай и потом на моем серваке запустим его на Финаме на 20 тыс. тикеров отслеживание и принятие решений по сделкам .... твой  новый робот ведь гораздо тяжелее  получится  и  мне любопытно  сможет ли мой сервак вытягивать его на все отслеживаемые и торгуемые в Финаме инструменты ?    
 
БорисД, Так ведь у нас УЖЕ от 20 тысяч тикеров остались рожки, да ножки - менее 9000, насколько я помню. Всё остальное УЖЕ ушло в класс "говно", а ещё не вечер. А с говном должен работать уже не боевой скрипт, а именно тест, запускаемый уж никак не чаще, чем раз в неделю и очень лёгкий сам по себе: его задача всего лишь проверить, не появилось ли среди этого говна что-то интересное.

Боевой, конечно, намного тяжелее, но... денег-то у тебя хватит, чтобы загрузить его на полную мощность? :smile: Да чо там "на полную" - хотя бы на 10%.
 
Владимир, нет конечно  , и даже на 10  % и даже  видимо на 1 %   на боевом  не хватит у меня денег. .  Но  тестовый робот  по  20 тысячам тикеров  тоже ресурс компа  сьедает почти на уровне боевого  -  но любопытство требует удовлетворения  опробовать возможности следить  твоим скриптом  сразу за всеми  существующими и торгуемыми  нашими российскими брокерами  инструментами на всех инструментах  , рынках и  биржах к которым они предосталяют доступ  своим трейдерам.
  И  предчуствую твой вопрос : "  а зачем тебе это надо ?  ""  , сразу отвечу что это просто любопытство и ни чего более. чем проверка возможностей скрипта  для  бытового компьютера.  
 
БорисД, Не, "опробовать возможности следить сразу за всеми  существующими и торгуемыми  нашими российскими брокерами  инструментами на всех инструментах, рынках и  биржах к которым они предосталяют доступ  своим трейдерам" можешь чем угодно, токо не моим скриптом. Ты прям как Старатель - загадить мой распрекрасный скрипт всяким говном и смотреть, что случится.  :smile:

Ну или классика:
Купили как-то суровым сибирским лесорубам японскую бензопилу.
Собрались в кружок лесорубы, решили ее испытать. Завели, подсунули ей деревце.
— Вжик! — сказала японская пила.
— У,  * ! — сказали лесорубы.
Подсунули ей деревце потолще.
— Вж-ж-жик! — сказала пила.
— У,  * ! — сказали лесорубы.
Подсунули ей толстенный кедр.
— Вж-ж-ж-ж-ж-ж-ж-жик! — сказала пила.
— Ууух,  * ! — сказали лесорубы.
Подсунули ей железный лом.
— КРЯК! — сказала пила.
— Ага,  * ! — укоризненно сказали суровые сибирские лесорубы. И пошли валить лес топорами.
 
Владимир,  :lol:  :lol:

не-а , я  толстенный  кедр может и попробую , но  про ломики я  зараннее  знаю  результат.  :lol:  :lol:  :lol:  
 
Пункты 10 и 20.
Код
---@class roffild
---@field ISTRADINGALLOWED_SECONDS number Секунд в ожидании обезличиной сделки (по умолчанию = 3)
local roffild = {
    ISTRADINGALLOWED_SECONDS = 3,
}

---`isConnected() == 1` ещё ДО ввода PIN при Двухфакторной аутентификации.
---Обход бага через `getInfoParam("LASTRECORDTIME")`.
---@param seconds? number Секунд для ожидания (по умолчанию = 3 = `ISTRADINGALLOWED_SECONDS`)
---@return boolean
function roffild.isTradingAllowed(seconds)
    if isConnected() == 1 then
        local lastrecordtime = getInfoParam("LASTRECORDTIME")
        local servertime = getInfoParam("SERVERTIME") -- время с часовым поясом сервера (секунды локальные)
        if
            not (lastrecordtime == nil or lastrecordtime == "")
            and not (servertime == nil or servertime == "")
        then
            -- convertDateOrTimeToUnix из-за ":" не работает
            local fixlastrecordtime = os.sysdate()
            fixlastrecordtime.hour = tonumber(string.sub(lastrecordtime, 0, -7))
            fixlastrecordtime.min = tonumber(string.sub(lastrecordtime, -5, -4))
            fixlastrecordtime.sec = tonumber(string.sub(lastrecordtime, -2))
            if -- clearing
                fixlastrecordtime.hour < 7
                or (fixlastrecordtime.hour == 14 and fixlastrecordtime.min < 5)
                or (fixlastrecordtime.hour == 18 and fixlastrecordtime.min >= 45)
                or (fixlastrecordtime.hour == 19 and fixlastrecordtime.min < 5)
                or (fixlastrecordtime.hour == 23 and fixlastrecordtime.min >= 50)
            then
                return false
            end
            local fixservertime = os.sysdate()
            fixservertime.hour = tonumber(string.sub(servertime, 0, -7))
            fixservertime.min = tonumber(string.sub(servertime, -5, -4))
            fixservertime.sec = tonumber(string.sub(servertime, -2))
            return (math.abs(os.time(fixservertime) - os.time(fixlastrecordtime)) <=
                (seconds or roffild.ISTRADINGALLOWED_SECONDS))
        end
    end
    return false
end

return roffild


Ееееееее!.. Я смог создать 100% определитель статуса глобальной торговли!
Функция прошла проверки Двухфакторной аутентификации, выходного дня, смены часового пояса и clearing.
Эту функцию ДОЛЖНЫ создать программисты Квика, а не заставлять искать хаки в их тв...

Теперь это часть моей библиотеки, которая облегчает боль и страдания от QLua.

После эпичной чуши про безопасность ожидаю обвинение во "взломе Квика, подрывающее безопасность и стабильность Российской биржи" :D
 
Да, так можно проверять. Собственно уже сколько лет так и проверяется.

Но необходимо учитывать еще, что есть настройка "Получать данные раз в секунд".

Если там установлено не 0, то необходимо это учитывать. Впрочем, параметр у Вас есть для этого.

Также еще необходимо учитывать, что SERVERTIME не всегда возвращается в виде 8-и символов.
 
22. Доработки по индикаторам. Какой вообще смысл в OnChangeSettings? В МТ5 просто перегружают индикатор с новыми настройками. В Квике тоже нужен перегруз индикатора и Init() всегда вернет нужное количество линий. Перегруз для связанного графика уже есть.

Нужны Settings.hideline, чтобы пользователь не мог изменить им параметры. Вот пример модифицированного индикатора: когда пользователь задает количество линий Settings.Count и параметры только для первой, но применяются параметры для всех остальных линий.
Код
Settings = {
    Name = "Levels_TEST",
    Step = 50,
    Count = 10,
    IsBoolean = false, -- БАГ: В настройках этот тип не меняется!
    line = {}, -- БАГ: без этой строки индикатор не появляется в списке!

    hideline = {}, -- В настройках не отображаются
}

Settings.line = {
    {
        Name = "Line1",
        Type = TYPE_POINT,
        Color = RGB(55, 55, 55),
        Width = 2
    }
}

function Init()
    -- Можно вынести этот код за Init() и результат будет тот же.
    LINES = Settings.Count
    Settings.hideline = {} -- сброс, чтобы актуальные параметры сгенерировать

    for x = 2, LINES, 1 do
        Settings.hideline[x] = { -- LineERROR: здесь line[x] было (ошибка ниже)
            Name = "Line" .. tostring(x),
            Type = Settings.line[1].Type,
            Color = Settings.line[1].Color,
            Width = Settings.line[1].Width
    }
    end
    LINES = #Settings.line + #Settings.hideline
    -- А какой смысл возвращать другое значение?
    -- В МТ5 тут статус Инит, который может быть ошибкой.
    -- Но, количество линий? Где логика?
    -- Если превысить, то добавятся линии с случайным цветом...
    return LINES
end

function OnChangeSettings()
    -- Юзер сменил Settings.Count ?
    Init()
    -- Function OnChangeSettings: LineERROR: attempt to index a nil value (field 'line')

    -- ИЗМЕНЕНИЙ НЕТ! Линии не добавились и не покрасились.
    -- Очередная наспех сделанная кривая функция...
end

function OnCalculate(index)
    local start = O(index)
    if start == nil then
        return nil
    end
    if MINSTEP == nil then
        local info = getDataSourceInfo()
        MINSTEP = getSecurityInfo(info.class_code, info.sec_code).min_price_step
        FIRST = (math.tointeger(LINES / 2) + 1) * Settings.Step * MINSTEP
    end
    local result = {}
    start = start - ((math.tointeger(math.ceil(start / MINSTEP)) % Settings.Step) * MINSTEP) + FIRST
    for x = 1, LINES, 1 do
        table.insert(result, start - (x * Settings.Step * MINSTEP))
    end
    return table.unpack(result)
end
 
23. Интерфейс: "Редактор настроек графика" вообще не знает, что индикатор привязан к другому Инструменту, который при Добавлении можно указать. Узнать и изменить Инструмент через Редактор невозможно.
 
24. У Тёмной темы главное меню плохо дружит со стрелками на клавиатуре.
 
Похоже стандартный MoneyFlowIndex считается особым способом...

ВТБ ао
MoneyFlowIndex оба 6 периода
Дата: 2021.12.16 20:45 (5 минутки)
Расхождении не только там...

Мой вариант:
Код
Settings = {
    Name = "Tester",
    Step = 0,
    line = {}
}

LINES = 1

for x = 1, LINES, 1 do
    Settings.line[x] = {
        Name = "Line" .. tostring(x),
        Type = TYPE_LINE,
        Color = RGB(255, 255, 255),
        Width = 1
    }
end

function Init()
    LINES = #Settings.line
    return LINES
end

function OnCalculate(index)
    local start = O(index)
    if start == nil then
        return nil
    end
    return indicMoneyFlowIndex(indicToDataSource(), 6, Size()-index)
end

---Money Flow Index
---@param datasource fnCreateDataSourceReturn DataSource
---@param period number Период
---@param shift number Сдвиг в барах
---@return number
function indicMoneyFlowIndex(datasource, period, shift)
    if shift == nil then
        shift = 0
    end
    local stop = datasource.Size() - shift
    local start = stop - period
    if start < 1 or stop < 1 then
        return nil
    end
    local pos = 0.0
    local neg = 0.0
    local last = (datasource.H(start) + datasource.L(start) + datasource.C(start)) / 3.0
    for x = start+1, stop, 1 do
        local tp = (datasource.H(x) + datasource.L(x) + datasource.C(x)) / 3.0
        if tp >= last then
            pos = pos + (tp * datasource.V(x))
        else
            neg = neg + (tp * datasource.V(x))
        end
        last = tp
    end
    if neg ~= 0.0 then
        return 100.0 - (100.0 / (1.0 + (pos / neg)))
    else
        return 100.0
    end
end

---DataSource for Indicator
---@return fnCreateDataSourceReturn
function indicToDataSource()
    return {["O"] = O, ["H"] = H, ["L"] = L, ["C"] = C, ["V"] = V, ["T"] = T, ["Size"] = Size}
end

На картинке:
белый - мой
зеленый - стандартный
 
 
МТ5 согласен с моим вариантом:
 
 
Здравствуйте.
Цитата
Roffild написал:
18. В "Менеджере окон" нужна смена порядкового номера окна, потому что меню "Окна-Колонками" расставляет по этому порядку.

19. И редактирование размеров окна добавьте в "Менеджере окон". Можно в отдельном диалоге сделать по двойному клику.
Касательно пункта 19. Мы рассмотрели Ваше пожелание. По итогам его анализа сообщаем Вам, что  пожелание отклонено по причине того, что оно не соответствует нашим  представлениям о путях дальнейшего развития ПО.
Страницы: Пред. 1 2
Читают тему
Наверх