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
Пользователь
Сообщений: Регистрация: 04.10.2021
25.11.2021 19:30:11
Цитата
Владимир написал: , Лапуль, я с раннего детства не перевариваю распальцованных дураков. Повторяю для особо одарённых: в кодах скулящих по любому вопросу неучей я ковыряться не намерен. А "гениальное решение", лапуль, надо УМЕТЬ видеть - бездарности способны разве что смотреть, как баран на новые ворота.
Нельзя увидеть, чего нет. Покажи! Или ты даже тот код не осилил? Ах, да "в кодах скулящих по любому вопросу неучей я ковыряться не намерен"... не программист ты.
Цитата настоящего программиста: "Хватит болтать! Покажи мне код!"
Пользователь
Сообщений: Регистрация: 04.10.2021
25.11.2021 19:38:24
Anton, как раз на создании mypositions твой код и нарвется на тот баг. OnAllTrade тут не поможет и вообще о других сделках.
Роль OnAllTrade выполняет getParamEx2("SPBFUT", v.sec_code, "BID").param_value в моем коде.
Пользователь
Сообщений: Регистрация: 25.09.2020
25.11.2021 19:58:04
Roffild, Лапуль, кода своего я здесь приводил НЕМЕРЯНО! И кода РАБОТАЮЩЕГО, без скулежа про "плохие и непродуманные API". Покопайтесь в моих сообщениях, коль неймётся. И в третий раз повторяю: "В кодах скулящих по любому вопросу неучей я ковыряться не намерен". Сколько раз повторить, чтобы дошло?
Пользователь
Сообщений: Регистрация: 04.10.2021
25.11.2021 20:02:19
Цитата
Владимир написал: , Лапуль, кода своего я здесь приводил НЕМЕРЯНО! И кода РАБОТАЮЩЕГО, без скулежа про "плохие и непродуманные API". Покопайтесь в моих сообщениях, коль неймётся. И в третий раз повторяю: "В кодах скулящих по любому вопросу неучей я ковыряться не намерен". Сколько раз повторить, чтобы дошло?
Ну, не повторяй... Я вообще не понимаю, что тролль забыл в этой теме...
Владимир написал: , Тролль эту тему создал, лапуль.
А ты пытаешься его изгнать? В чём ТВОЯ миссия? Или смысл жизни? Даж интересно стало.
Пользователь
Сообщений: Регистрация: 25.09.2020
25.11.2021 20:32:55
Roffild, Я же тыщу раз говорил, лапуль: я с детства не перевариваю распальцованных дураков и редко спускаю им их "поучения".
Пользователь
Сообщений: Регистрация: 04.10.2021
25.11.2021 21:45:25
Владимир, и много уже спустил? Если не спускать "поучения", которые тебя даже не касаются, то жизнь теряет смысл? И можно при спуске не стать "распальцованным дураком", как они? И как это распознать?
Пользователь
Сообщений: Регистрация: 25.09.2020
25.11.2021 23:04:24
Roffild, Почему же "меня не касаются"? Когда на форум приходит очередной придурок с гнутыми пальцами, ему очень полезно бывает отвесить пару щелчков по носу, иначе, как показывает опыт, у них окончательно крышу сносит, и они засирают всё словесным поносом на три мили вокруг. Как известно, без сопротивления говно, как и газ, заполняет любой объём.
Пользователь
Сообщений: Регистрация: 04.10.2021
26.11.2021 10:00:02
Владимир, спасибо, что поделился с нами своей гопно-туалетной философией окружающего нас токсичного мира. Я больше не стану тебя отвлекать от миссии очищения этого форума. Да, обойдет бан тебя стороной в этом опасном деле...
Пользователь
Сообщений: Регистрация: 04.10.2021
03.12.2021 16:42:26
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
Пользователь
Сообщений: Регистрация: 21.08.2015
03.12.2021 18:17:17
Цитата
Roffild написал: OnAllTrade() НЕ вызывается, если "Таблица обезличенных сделок" НЕ открыта
Или не создан тиковый датасорец по инструменту, или не открыт тиковый график по инструменту. Но это закажет только один инструмент. Подписка на ВСЕ инструменты в цикле с целью заказать ТОС целиком работает плохо, потому что на каждой итерации идет перезаказ ТОС, а подписаться на все разом нельзя. Поэтому в нынешних реалиях: 1) ТОС должна быть всегда открыта, заказ данных должен быть настроен руками 2) юзер должен быть проинструктирован никогда ТОС не закрывать и особо не щелкать по тиковым графикам во избежание автоматической отписки от чего-нибудь 3) сам скрипт подписываться на тики не должен во избежание автоматической отписки при его завершении 4) юзер должен периодически поглядывать в настройках, что все галки на месте или 4.1) перед запуском квика некая внешняя софтина должна заглядывать в info.ini и фиксить подписки в случае чего.
По-хорошему нужны функции SubscribeAllTrades/UnsubscribeAllTrades с возможностью подписаться на ВСЕ за один вызов. Но арка почему-то не хочет этого делать. Либо нужно реализовать вариант, предложенный неоднократно: фильтры устанавливаются автоматически при любой подписке, как сейчас, а сбрасываются только из диалога заказа данных. Тоже не хочет.
Предлагаю схему попроще: 1) ТОС должна быть всегда закрыта 2) юзер должен быть проинструктирован никогда ТОС не открывать, ибо она ему нафиг не нужна. 3) сам скрипт подписываться ни на что не должен во избежание любых потенциальных глюков. 4) юзер волен делать всё, что ему заблагорассудится, если он запустил скрипт с началом торгов и остановит его перед выключением компа. 4.1) Все "некие внешние софтины" - поганой метлой!
Пользователь
Сообщений: Регистрация: 21.08.2015
03.12.2021 18:55:51
Цитата
Владимир написал: никогда ТОС не открывать, ибо она ему нафиг не нужна.
можно и квик никогда не открывать, чего мелочиться-то.
Цитата
Владимир написал: если он запустил скрипт с началом торгов и остановит его перед выключением компа
значит, он проснулся по будильнику к началу торгов и далеко не отойдет до закрытия. Не завидую ему.
Я просыпаюсь в любое удобное для себя время, обычно уже после начала торгов на СПб и до на Мосбирже, запускаю пару Квиков (иногда аместе, иногда вразнобой), свободно ухожу куда надо если надо, выключаю комп, когда спать ложусь или когда посчитаю нужным, иногда уже после закрытия биржи, могу вообще не выключать. Куда уж свободнее? Только вот автоматическую сверку с портфелем брокера никак руки не дойдут сделать.
Пользователь
Сообщений: Регистрация: 21.08.2015
03.12.2021 21:34:12
Цитата
Владимир написал: Квик торгует, денюшку приносит, а ТОС нет.
Для меня любое заранее назначенное время - неудобное. Тксть солнце всходит и заходит по веленью моему.
Пользователь
Сообщений: Регистрация: 25.09.2020
04.12.2021 00:27:07
Anton, Не зааю как там "не везде", а у меня именно так.
А кто говорил про "заранее назначенное время"? Я вот совершенно без понятия, когда я его завтра включу и когда выключу. Ах, да - завтра торгов нет. Ну, сегодня был без понятия, выключил минуту назад.
4) юзер волен делать всё, что ему заблагорассудится, если он запустил скрипт с началом торгов и остановит его перед выключением компа.
а нахрена мне твой скрипт или комп останавливать ? Знаю что сейчас начнешь на меня ругаться , но мне так удобнее и это ближе к моему желаемому желанию типа : "" включил и забыл !!! "" Что уж тут греха таить - скрипт конечно вылетает иногда или по очередно с Квиком , но и я не на всегда свой комп покинул . к тому же автозапуск и авто .старт и без меня нормально с перезапуском справляются.
Да знаю я, что ты лентяй ещё больший, чем я. Ну, не выключай. А мне комп тоже жалко - пусть отдохнёт от этой биржи. Может быть, глючить будет меньше в качестве благодарности.
Пользователь
Сообщений: Регистрация: 14.10.2021
05.12.2021 05:59:07
Цитата
Владимир написал: , Что, и ты не выдержал, опять сюда влез? ::
Да знаю я, что ты лентяй ещё больший, чем я. Ну, не выключай. А мне комп тоже жалко - пусть отдохнёт от этой биржи. Может быть, глючить будет меньше в качестве благодарности. ::
да залез сюда глядя на тебя. И лишь по той причине что видел воочую наши эксперименты отследить 20 тыс. инструментов одновременнно твоим скриптом.
Нет , Володь - я не конченный лентяй , просто работы много и постоянно следить за роботом не имею такой возможности , Квик на автозапуске а твой скрипт в нем всегда запущен и если я с ним не эксперементирую то и проблем с ним не имею . Еще раз напомню что цель моя получить робота по типу : - включил и забыл и контролируй его по мере наличия такой возможности. Я не могу уверять здесь народ что он у меня за последние 2 недели не глючил ( вернее он или Квик ) но когда я заглядываю на свой сервак то не видел чтобы за последние 2 недели он не глючил , но тут твой файл логов не совсем полный и не все ситуации фиксирует ,
Кстати про 20 тыс. тикеров - когда мы вместе за этим наблюдали на твоем не самом сильном по железу ноуте . то мы все таки дождались глюков и давай новый релиз сначало доделывай и потом на моем серваке запустим его на Финаме на 20 тыс. тикеров отслеживание и принятие решений по сделкам .... твой новый робот ведь гораздо тяжелее получится и мне любопытно сможет ли мой сервак вытягивать его на все отслеживаемые и торгуемые в Финаме инструменты ?
Пользователь
Сообщений: Регистрация: 25.09.2020
05.12.2021 11:08:06
БорисД, Так ведь у нас УЖЕ от 20 тысяч тикеров остались рожки, да ножки - менее 9000, насколько я помню. Всё остальное УЖЕ ушло в класс "говно", а ещё не вечер. А с говном должен работать уже не боевой скрипт, а именно тест, запускаемый уж никак не чаще, чем раз в неделю и очень лёгкий сам по себе: его задача всего лишь проверить, не появилось ли среди этого говна что-то интересное.
Боевой, конечно, намного тяжелее, но... денег-то у тебя хватит, чтобы загрузить его на полную мощность? Да чо там "на полную" - хотя бы на 10%.
Пользователь
Сообщений: Регистрация: 14.10.2021
05.12.2021 18:01:17
Владимир, нет конечно , и даже на 10 % и даже видимо на 1 % на боевом не хватит у меня денег. . Но тестовый робот по 20 тысячам тикеров тоже ресурс компа сьедает почти на уровне боевого - но любопытство требует удовлетворения опробовать возможности следить твоим скриптом сразу за всеми существующими и торгуемыми нашими российскими брокерами инструментами на всех инструментах , рынках и биржах к которым они предосталяют доступ своим трейдерам. И предчуствую твой вопрос : " а зачем тебе это надо ? "" , сразу отвечу что это просто любопытство и ни чего более. чем проверка возможностей скрипта для бытового компьютера.
Пользователь
Сообщений: Регистрация: 25.09.2020
05.12.2021 18:25:34
БорисД, Не, "опробовать возможности следить сразу за всеми существующими и торгуемыми нашими российскими брокерами инструментами на всех инструментах, рынках и биржах к которым они предосталяют доступ своим трейдерам" можешь чем угодно, токо не моим скриптом. Ты прям как Старатель - загадить мой распрекрасный скрипт всяким говном и смотреть, что случится.
Ну или классика: Купили как-то суровым сибирским лесорубам японскую бензопилу. Собрались в кружок лесорубы, решили ее испытать. Завели, подсунули ей деревце. — Вжик! — сказала японская пила. — У, * ! — сказали лесорубы. Подсунули ей деревце потолще. — Вж-ж-жик! — сказала пила. — У, * ! — сказали лесорубы. Подсунули ей толстенный кедр. — Вж-ж-ж-ж-ж-ж-ж-жик! — сказала пила. — Ууух, * ! — сказали лесорубы. Подсунули ей железный лом. — КРЯК! — сказала пила. — Ага, * ! — укоризненно сказали суровые сибирские лесорубы. И пошли валить лес топорами.
не-а , я толстенный кедр может и попробую , но про ломики я зараннее знаю результат.
Пользователь
Сообщений: Регистрация: 04.10.2021
06.12.2021 11:56:53
Пункты 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. Эту функцию ДОЛЖНЫ создать программисты Квика, а не заставлять искать хаки в их тв...
После ожидаю обвинение во "взломе Квика, подрывающее безопасность и стабильность Российской биржи" :D
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2021 12:21:50
Да, так можно проверять. Собственно уже сколько лет так и проверяется.
Но необходимо учитывать еще, что есть настройка "Получать данные раз в секунд".
Если там установлено не 0, то необходимо это учитывать. Впрочем, параметр у Вас есть для этого.
Также еще необходимо учитывать, что SERVERTIME не всегда возвращается в виде 8-и символов.
Пользователь
Сообщений: Регистрация: 04.10.2021
13.12.2021 16:52:23
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
Пользователь
Сообщений: Регистрация: 04.10.2021
17.12.2021 09:51:02
23. Интерфейс: "Редактор настроек графика" вообще не знает, что индикатор привязан к другому Инструменту, который при Добавлении можно указать. Узнать и изменить Инструмент через Редактор невозможно.
Пользователь
Сообщений: Регистрация: 04.10.2021
23.12.2021 13:09:20
24. У Тёмной темы главное меню плохо дружит со стрелками на клавиатуре.
Пользователь
Сообщений: Регистрация: 04.10.2021
09.02.2022 17:19:32
Похоже стандартный 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
На картинке: белый - мой зеленый - стандартный
Пользователь
Сообщений: Регистрация: 04.10.2021
09.02.2022 17:34:44
МТ5 согласен с моим вариантом:
Пользователь
Сообщений: Регистрация: 05.08.2021
22.04.2022 14:56:30
Здравствуйте.
Цитата
Roffild написал: 18. В "Менеджере окон" нужна смена порядкового номера окна, потому что меню "Окна-Колонками" расставляет по этому порядку.
19. И редактирование размеров окна добавьте в "Менеджере окон". Можно в отдельном диалоге сделать по двойному клику.
Касательно пункта 19. Мы рассмотрели Ваше пожелание. По итогам его анализа сообщаем Вам, что пожелание отклонено по причине того, что оно не соответствует нашим представлениям о путях дальнейшего развития ПО.