Написание автономного бота

Страницы: 1 2 3 След.
RSS
Написание автономного бота
 
Добрый день.

Столкнулся со проблемой написания бота, который бы работал автономно без контроля со стороны человека.
Документ "Использование Lua в Рабочем месте QUIK" предлагает нам целых три подхода написания скриптов.
Первый "Вся необходимая логика описывается в области <BODY>" для торговых ботов не подходит.
Рссмотрим 2 и 3 подходы на примере простейшей, казалось бы, задачи: определение текущих открытых позиций.

2. Вся необходимая логика описывается в функции с предопределенным именем main().
Код
local LIMIT_KIND = 0
local pos = {}
local run = true

function OnStop()
  run = false
end

local function go()
  local s = ""
  for sec_code, bal in pairs(pos) do
    s = s .. sec_code .. ": " .. bal .. "\n"
  end
  message(s)
end

local function getPosition()
  for i = 0, getNumberOf("depo_limits")-1 do
    local limit = getItem("depo_limits", i)
    if limit.limit_kind == LIMIT_KIND then
      pos[limit.sec_code] = limit.currentbal
    end
  end
  for i = 0, getNumberOf("futures_client_holding")-1 do
    local limit = getItem("futures_client_holding", i)
    if limit.type == 0 then
      pos[limit.sec_code] = limit.totalnet
    end
  end
end

function main()
  while isConnected() ~= 1 and run do sleep(100) end
  while getNumberOf("depo_limits") == 0 and run do
    -- Таблица "позиции по инструментам" не может быть пустой, в ней должна быть хотя бы одна запись
    -- Но точное количество записей в таблице не известно, поэтому такой подход работает некорректно
    sleep(100)
  end
  -- С таблицей futures_client_holding сложней, она может быть пустой или не пустой... -- Что делать в этом случае?
  if run then
    getPosition()
    go()
  end
end

3. Событийная модель.
Код
local LIMIT_KIND = 0
local pos = {}
local run = true

function OnStop()
  run = false
end

local function go()
  local s = ""
  for sec_code, bal in pairs(pos) do
    s = s .. sec_code .. ": " .. bal .. "\n"
  end
  message(s)
end

local function getPosition()
  for i = 0, getNumberOf("depo_limits")-1 do
    local limit = getItem("depo_limits", i)
    if limit.limit_kind == LIMIT_KIND then
      pos[limit.sec_code] = limit.currentbal
    end
  end
  for i = 0, getNumberOf("futures_client_holding")-1 do
    local limit = getItem("futures_client_holding", i)
    if limit.type == 0 then
      pos[limit.sec_code] = limit.totalnet
    end
  end
end

function main()
  if isConnected() == 1 and getNumberOf("depo_limits") ~= 0 then
    getPosition()
  else
    while isConnected() ~= 1 and run do sleep(100) end
    while not get_position and run do sleep(100) end -- Когда уже можно считать, что ВСЕ позиции загружены?
  end
  if run then go() end
end

function OnDepoLimit(limit)
  if limit.limit_kind == LIMIT_KIND then
    pos[limit.sec_code] = limit.currentbal
    get_position = true  -- ???
  end
end

function OnFuturesClientHolding(limit)
  -- Этот колбек вобще может не прийти, т.к. позиций на срочном рынке может и не быть
  if limit.type == 0 then
    pos[limit.sec_code] = limit.totalnet
  end
end

Оба скрипта корректно работают, будучи запущенными, когда клиент подключён к серверу и все позиции загружены.
Т.е., нужен контороль со стороны человека, чтобы убедиться, что скрипт определил текущие позиции правильно, и бот может торговать.

Ув. разработчики., могли бы вы оказать поддержку в доработке скрипта, чтобы он корректно работал в любой штатной* ситуации?
* Здесть имеется ввиду, что ТС биржи и сервер брокера работают штатно, без сбоев.
 
Цитата
Mixa написал:
Ув. разработчики., могли бы вы оказать поддержку в доработке скрипта,
К сожалению мы не можем предоставить подобную помощь т.к. разработка скриптов не является нашей задачей.
Мы можем помочь в устранении ошибки если она случается.
 
Sergey Gorokhov,
Согласно Регламента работы по обращениям клиентов по проблемам в коде
Код
Для получения корректного ответа необходимо ёмкое описание проблемы с примером кода, который не работает или работает неправильно. В этом случае мы оказываем всяческую поддержку пользователям.
я предоставил пример кода и ёмкое описание проблемы.

Цитата
Sergey Gorokhov написал:
Мы можем помочь в устранении ошибки если она случается.
Так и есть. Скрипт может не правильно определить текущие позиции. В чём моя ошибка?
 
Цитата
Mixa написал:
я предоставил пример кода и ёмкое описание проблемы.
нет, Вы не представили ёмкое описание проблемы
Исходя из описания не понятно что именно не работает, только просьба выполнить работу.
Цитата
Mixa написал:
Так и есть. Скрипт может не правильно определить текущие позиции. В чём моя ошибка?

Вот это уже похоже на "описание проблемы".
Вопрос в том, что подразумевается под "не правильно"?
Не правильно это как? есть конкретный пример?
 
Mixa, дело в том, что иногда таблица с позициями не успевает загрузиться, а скрипт уже работает, этот момент надо просто учесть в работе скрипта
Делаю вот так
Код
function FuturesClientHolding() -- Первоначальное заполнение позиций по срочному рынку
  local n=0
  while (n<try_count)and(getNumberOf('FUTURES_CLIENT_HOLDING')==0) do -- Ждем заполнения таблицы "Позиции по клиентским счетам (фьючерсы)"
    sleep(100)
    n=n+1
  end
  if getNumberOf('FUTURES_CLIENT_HOLDING')>0 then -- Таблица "Позиции по клиентским счетам (фьючерсы)" заполнена
    for i=0,getNumberOf('FUTURES_CLIENT_HOLDING')-1 do
      local tbl=getItem('FUTURES_CLIENT_HOLDING', i)
      if(type(tbl)=="table")and(tbl['firmid']==firmid)and(tbl['trdaccid']==account)and(tbl['sec_code']==sec_code)and(tbl['type']==0)then
        holding["TOTALNET"]  = tbl['totalnet']  -- Текушие позиции
        holding["OPENBUYS"]  = tbl['openbuys']  -- Активная покупка
        holding["OPENSELLS"] = tbl['opensells'] -- Активная продажа
        return true
      end
    end
  end
  -- Таблица "Позиции по клиентским счетам (фьючерсы)" пустая, либо в ней отсутствует искомый инструмент
  holding["TOTALNET"]  = 0
  holding["OPENBUYS"]  = 0
  holding["OPENSELLS"] = 0
  return false
end
В дальнейшем обновляю позиции через колбек OnFuturesClientHolding
 
Цитата
BlaZed написал:
if getNumberOf('FUTURES_CLIENT_HOLDING')>0 then -- Таблица "Позиции по клиентским счетам (фьючерсы)" заполнена
ПОЛНОСТЬЮ заполнена?
А если getNumberOf = 0?
 
Цитата
BlaZed написал:
if getNumberOf('FUTURES_CLIENT_HOLDING')>0 then -- Таблица "Позиции по клиентским счетам (фьючерсы)" заполнена
ПОЛНОСТЬЮ заполнена?
А если getNumberOf('FUTURES_CLIENT_HOLDING') = 0?
 
Sergey Gorokhov,
В скрипте go() - это функция, когда бот определил все текущие позиции и может начать торговлю.

Цитата
Sergey Gorokhov написал:
есть конкретный пример?
Например, подключение к серверу в разгар торгов.

Цитата
Sergey Gorokhov написал:
что подразумевается под "не правильно"?
Получены не все открытые позиции.
 
Цитата
Mixa написал:
ПОЛНОСТЬЮ заполнена?
Да
Цитата
Mixa написал:
А если getNumberOf('FUTURES_CLIENT_HOLDING') = 0?
Значит либо таблица еще не загрузилась, либо таблица пустая и позиции нулевые.
Оба варианта учтены в алгоритме.
 
Цитата
BlaZed написал:
Значит либо таблица еще не загрузилась, либо таблица пустая и позиции нулевые.
Это принципиально разные состояния. Во втором случае бот может торговать, в первом - нет.

Цитата
BlaZed написал:
Цитата
Mixa написал:
ПОЛНОСТЬЮ заполнена?
Да
Не всегда.
Вот добавил ваш код в скрипт
Код
local LIMIT_KIND = 0
local pos = {}
local run = true

function OnStop()
  run = false
end

local function go()
  local s = ""
  for sec_code, bal in pairs(pos) do
    s = s .. sec_code .. ": " .. bal .. "\n"
  end
  message(s)
  while run do sleep(100) end  -- Чтобы скрипт стартовал при запуске QUIK
end

local function DepoLimit()
  while getNumberOf("depo_limits") == 0 do
    -- Таблица "позиции по инструментам" не может быть пустой, в ней должна быть хотя бы одна запись
    -- Но точное количество записей в таблице не известно, поэтому такой подход работает некорректно
    sleep(100)
    if not run then return false end
  end
  for i = 0, getNumberOf("depo_limits")-1 do
    local limit = getItem("depo_limits", i)
    if limit.limit_kind == LIMIT_KIND then
      pos[limit.sec_code] = limit.currentbal
    end
  end
  return true
end

local function FuturesClientHolding(try_count)
  -- Первоначальное заполнение позиций по срочному рынку
  local n = 0
  -- Сколько ставить циклов try_count? 100 хватит? На самом деле - не важно.
  -- try_count решает только одну задачу - не зависнуть в цикле, если таблица пустая по причине полного отсутствия позиций
  while n < try_count and getNumberOf("futures_client_holding") == 0 do  -- Ждем заполнения таблицы "Позиции по клиентским счетам (фьючерсы)"
    sleep(100)
    n = n + 1
    if not run then return false end
  end
  if getNumberOf("futures_client_holding") > 0 then
    -- Таблица "Позиции по клиентским счетам (фьючерсы)" заполнена ??????
    for i = 0, getNumberOf("futures_client_holding")-1 do
      local limit = getItem("futures_client_holding", i)
      if limit.type == 0 then
        pos[limit.sec_code] = limit.totalnet
      end
    end
    return true
  end
  return false  -- Таблица "Позиции по клиентским счетам (фьючерсы)" пустая
end

function main()
  while isConnected() ~= 1 and run do sleep(100) end
  while run do
    if not DepoLimit() then break end
    if FuturesClientHolding(100) then
      break
    else
      message("либо таблица еще не загрузилась, либо таблица пустая и позиции нулевые", 3)
      -- И что с этим делать теперь?
      -- Когда можно будет go() запустить?
    end
  end
  if run then
    go()
  end
end
В таблице было "depo_limits" - 16 позиций, в "futures_client_holding" - 8
Очистил кеш терминала для чистоты эксперимента, запустил QUIK, скрипт.
Подключился к серверу, скрипт показал всего 2 позиции: одну на валютной секции, другую - на срочке. На самом деле, тут как повезёт: могут все позиции загрузиться, а может только часть.
 
После подключения к серверу, на загрузку данных требуется время и тут ничего не поделать.
Какого-либо маркера о полной загрузке данных НЕ существует. Спрашивать как его сделать в этом вопросе бесполезно, т.к. надежных способов нет.
Самый верный вариант ждать пока нужные скрипту данные появятся в колбеке, если не появились значит ничего не делать.
Альтернатива, то же самое ждать, но в цикле раз в период.
 
Цитата
Sergey Gorokhov написал:
Какого-либо маркера о полной загрузке данных НЕ существует. Спрашивать как его сделать в этом вопросе бесполезно, т.к. надежных способов нет.
Так сделайте надежный способ. В чем проблема? Эта задача не кажется невыполнимой.

Цитата
Sergey Gorokhov написал:
Самый верный вариант ждать пока нужные скрипту данные появятся в колбеке, если не появились значит ничего не делать.
Что это за рекомендация такая? Как скрипт узнает сколько колбеков ждать и ждать ли вообще?
А если OnFuturesClientHolding не будет? "Ничего не делать"?
 
Цитата
Mixa написал:
Так сделайте надежный способ. В чем проблема? Эта задача не кажется невыполнимой.
Этому вопросу уже больше 10 лет и никто так и не предложил надежного способа.

Цитата
Mixa написал:
Что это за рекомендация такая? Как скрипт узнает сколько колбеков ждать и ждать ли вообще?А если OnFuturesClientHolding не будет? "Ничего не делать"?

Вот именно, и сервер тоже этого не знает и не может знать.
Кто скажет серверу будут ли FuturesClientHolding или нет? Биржа? Брокер? А им от куда знать?
 
Цитата
Sergey Gorokhov написал:
Этому вопросу уже больше 10 лет и никто так и не предложил надежного способа.
Да ладно! Посчитать количество записей в таблице на сервере и отправить число клиенту. В чем проблема?

Цитата
Sergey Gorokhov написал:
сервер тоже этого не знает
Как это не знает?!! Лимиты грузятся с сервера!

Цитата
Sergey Gorokhov написал:
Кто скажет серверу
Сам пусть считает!
 
Цитата
Mixa написал:
Да ладно! Посчитать количество записей в таблице на сервере и отправить число клиенту. В чем проблема?
Допустим, момент Х данных на сервере еще нет. Что должен подсчитать сервер?
Вы подключаетесь и сервер присылает Вам 0.
Ваш скрипт думает что данных нет и прекращает работу
И тут вдруг в момент Y данные на сервере появляются.
Как быть?


Цитата
Mixa написал:
Как это не знает?!! Лимиты грузятся с сервера!
Конкретно FuturesClientHolding  грузятся НЕ с сервера, а с биржи.

Цитата
Mixa написал:
Сам пусть считает!
Что считает?
 
Sergey Gorokhov, предложу свое решение.
На фондовой (и валютной) секции есть определённая процедура загрузки лимитов брокером на сервер. По окончании этой процедуры сервер должен отправить клиенту соответсвующее уведомление.
Когда клиент подключается к серверу, тот в первую очередь отправляет клиенту данные по лимитам и в конце - признак, что процедура загрузки лимитов (на сервер) завершена.
Таким образом можно гарантировать, что стартовые лимиты на начало торговой сессии загружены. Текущие лимиты скрипт сможет посчитать сам на основании этих данных и сделок.
Тогда скрипт будет ждать вполне определенный сигнал, а не "то, не зная что". И начинает торговлю только после получения уведомления "лимиты загружены".

Цитата
Sergey Gorokhov написал:
FuturesClientHolding  грузятся НЕ с сервера, а с биржи.
В биржевом шлюзе нет уведомления об окончании загрузки данных?
Думаю на срочной секции осуществим аналогичный вариант.

Sergey Gorokhov, как считаете, рабочий вариант?
 
Цитата
Mixa написал:
признак, что процедура загрузки лимитов (на сервер) завершена.
Это уже касается фондовых лимитов а не срочных? т.к. срочные лимиты НЕ грузятся на сервер. Они ТРАНСЛИРУЮТСЯ с биржи.
Разница в технологии колоссальная.
Как правило брокера грузят фондовые лимиты на сервер задолго до старта всех торговых шлюзов, когда они даже не запущены.
Так что когда пользователь подключается к серверу, фондовые лимиты уже точно на сервере есть.
Иное считается аварийной ситуацией.
Другой вопрос в том что сервер не будет транслировать фондовые лимиты по тем инструментам которые отсутствуют, либо у пользователя нет прав.
Например если пользователь подключился к серверу до старта шлюза, лимитов он не увидит, хотя на сервере они есть.
И сервер не будет транслировать никакой признак о наличии таких лимитов т.к. не знает появятся инструменты или нет, может биржа их исключила из торговли.
Получается опять диссонанс, на сервере лимит есть, он не знает можно ли давать его пользователю, пользователь подключился лимит не видит. А потом когда шлюз запустят лимит вдруг появился.

Вам уже было сказано что надежных способов не существует, тема разжевывалась сотни раз, на все предложенные пользователями варианты всегда найдется НО которое делает решение не надежным.
Мы можем и дальше продолжить диалог и Вы опять что то предложите и мы опять сообщим что есть ситуации делающее решение не надежным
Вариант которые уже сейчас решает вопрос уже был предложен
Ждите колбек или смотрите в цикле.
Данные появились - хорошо работаем
Данные не появились - сидим ждем дальше.

Цитата
Mixa написал:
В биржевом шлюзе нет уведомления об окончании загрузки данных?
Биржевой протокол не является тайной
http://ftp.moex.com/pub/ClientsAPI/Spectra/CGate/prod/docs/p2gate_ru.pdf
 
Цитата
Sergey Gorokhov написал:
Цитата
Mixa написал:
В биржевом шлюзе нет уведомления об окончании загрузки данных?
Биржевой протокол не является тайной
http://ftp.moex.com/pub/ClientsAPI/Spectra/CGate/prod/docs/p2gate_ru.pdf
sys_events, не?
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Sergey Gorokhov написал:
Данные не появились - сидим ждем дальше.
Дерьмо, а не вариант. Все ваши надуманные отговорки - разговор в пользу бедных.

Цитата
Sergey Gorokhov написал:
Это уже касается фондовых лимитов а не срочных?
Обсуждаются все лимиты, не только срочные.

Цитата
Sergey Gorokhov написал:
срочные лимиты НЕ грузятся на сервер. Они ТРАНСЛИРУЮТСЯ с биржи.
sys_events не решит вопрос?

Цитата
Sergey Gorokhov написал:
Так что когда пользователь подключается к серверу, фондовые лимиты уже точно на сервере есть.
Да плевать, что там есть на сервере. Скрипт работает на КЛИЕНТЕ, ему нужен сигнал, что на КЛИЕНТА ЗАГРУЖЕНЫ ВСЕ лимиты.

Цитата
Sergey Gorokhov написал:
Например если пользователь подключился к серверу до старта шлюза, лимитов он не увидит, хотя на сервере они есть.
И сервер не будет транслировать никакой признак о наличии таких лимитов т.к. не знает появятся инструменты или нет, может биржа их исключила из торговли.
Получается опять диссонанс, на сервере лимит есть, он не знает можно ли давать его пользователю, пользователь подключился лимит не видит.
И в чем по-вашему будет "решение не надежным"?

Цитата
Sergey Gorokhov написал:
А потом когда шлюз запустят лимит вдруг появился.
А вслед за лимитами - уведомление "лимиты загружены". Отдельно для каждой секции после запуска шлюза.
Таким образом, в какое бы время не подключился клиент, уведомление "лимиты загружены" должно быть отправлено после лимитов.
 
Цитата
Mixa написал:
sys_events не решит вопрос?
А разве там есть признак окончания загрузки данных на клиента которым в данном случае является QUIK?
Там есть "session_data_ready", в описании которого сказано о том что это признак окончания загрузки данных в торговую систему.
Это не то же самое что загрузка на клиента.
Цитата
Mixa написал:
И в чем по-вашему будет "решение не надежным"?

Вопрос не понятен, был приведен конкретный пример не надежного срабатывания.
Если есть ситуации когда предложенное решение выдаст неверный результат значит решение не надежное.
А такие ситуации поверьте будут всегда.
Цитата
Mixa написал:
А вслед за лимитами - уведомление "лимиты загружены".
Из этого следует что Вы все таки готовы ждать данные.
И чем тогда это отличается от предложенного варианта с ожиданием данных?
На наш взгляд вообще ничем. Тогда что мешает этим уже сейчас пользоваться?

Вы предлагаете, делать цикл который будет ловить признак окончания загрузки лимитов.
Мы предлагаем, делать цикл который будет ловить появление именно нужных скрипту лимитов.
Каждый скрипт, знает чем будет торговать, а значит знает какие лимиты ему нужны, не так ли?
Зачем скрипту ждать не нужных ему лимитов не понятно.
 
Цитата
Sergey Gorokhov написал:
А разве там есть признак окончания загрузки данных на клиента которым в данном случае является QUIK?
Я не сильно в этом разбираюсь. Но там есть:
Цитата
Уведомление в sys_events приходит ПОСЛЕ всех данных, в частности это означает, что в режиме получения данных on-line внешняя система получит сначала сами новые данные, например, инструменты, назначенные в новую сессию или перенесенные в новую сессию многодневные заявки, а уже потом – уведомление в sys_events.


Цитата
Sergey Gorokhov написал:
И чем тогда это отличается от предложенного варианта с ожиданием данных?
Как я уже писал: "таблица еще не загрузилась" и "таблица пустая и позиции нулевые" - это принципиально разные состояния.
Есть большая разница ожидания
Код
while getNumberOf(TableName) <= N do
-- где N - неизвестное число лимитов
и
Код
while isLimitsLoaded(class_code) do
-- где isLimitsLoaded - функция, возвращающая признак (true/false) загрузки данных
В первом случае, не известно, сколько лимитов ждать и ждать ли вообще. Во втором случае скрипт будет ждать вполне определенный признак.


Цитата
Sergey Gorokhov написал:
Каждый скрипт, знает чем будет торговать, а значит знает какие лимиты ему нужны, не так ли?
Знает. Допустим скрипт торгует КОРЗИНОЙ бумаг A, B, C.
Ждать "появление именно нужных скрипту лимитов" по бумагам A, B и C?
Если их не будет, что скрипту ждать? А если все-таки будут?
Напишите такой
Цитата
Sergey Gorokhov написал:
цикл который будет ловить появление именно нужных скрипту лимитов


Цитата
Sergey Gorokhov написал:
Цитата
Mixa написал:
И в чем по-вашему будет "решение не надежным"?
Вопрос не понятен, был приведен конкретный пример не надежного срабатывания.
Если есть ситуации когда предложенное решение выдаст неверный результат значит решение не надежное.
И вам задан конкретный вопрос.
Допустим, у нас есть функция isLimitsLoaded.
В чем по-вашему ожидание сигнала while isLimitsLoaded(class_code) do будет "не надежным"?
Какой именно "неверный результат" выдаст "предложенное решение"?
 
Цитата
Mixa написал:
Если их не будет, что скрипту ждать?
Если не будет значит ждать пока появятся.
Можно добавить какое-либо условие выхода из ожидания, например по времени.
Вариантов масса.
Главное определиться с условиями.


Цитата
Mixa написал:
Допустим, у нас есть функция isLimitsLoaded. В чем по-вашему ожидание сигнала while isLimitsLoaded(class_code) do будет "не надежным"? Какой именно "неверный результат" выдаст "предложенное решение"?
В приведенной Вами цитате, речь выше была не про фьючерсные позиции, а про фондовые.
Так что и ответ будет про фондовые.
Как быть если брокер в течении дня грузит позиции?
Пример, сервер подняли без лимитов.
Подняли шлюзы.
Брокер начинает грузить позиции, будет он их грузить пачками или все сразу ему самому решать.
В результате сервер не знает сколько позиций брокер будет грузить. Не знает окончился процесс или нет. Вдруг брокеру через час захочется загрузить еще?
Допустим брокер загрузил пачку, isLimitsLoaded вернет true, а именно Ваши лимиты брокер не загрузил, а загрузит их чуть позже.
Ваш код в этой ситуации примет решение что лимитов нет (нулевые) а на самом деле они будут позже.

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

Хорошо, допустим с фьючерсными позициями.
Там ситуация другая, они начинают транслироваться после запуска шлюза.
И транслируются сразу все что есть на бирже.
Если лимита нет на бирже, значит при isLimitsLoaded = true мы действительно можем судить о том что его нет, а не то что он не загружен.
Но задачу целиком это опять же не решит.
Вы пишите "таблица еще не загрузилась" и "таблица пустая и позиции нулевые"
На самом деле есть три состояния "таблица еще не загрузилась" и "таблица пустая" и "позиции нулевые"
Допустим первые два способа функция поможет отличить, но третий точно нет, ибо на стороне брокера есть транзакция на корректировку входящей позиции срочного рынка.
А значит, Вам легко может приехать строка содержащая 0, а потом через некоторое время нормальное значение.
Как быть?

ИТОГО, функция isLimitsLoaded никак не решает проблему с фондовыми и валютными лимитами.
Зато частично решает со срочными. Целесообразно ли ее вводить в условиях ненадежности и того что она хоть что то будет показывать только на одном рынке?
 
Цитата
Sergey Gorokhov написал:
Если не будет значит ждать пока появятся.
Вы сами-то понимаете, что пишите? Если по бумагам, которыми скрипт торгует, позиции не открыты, то лимиты не появятся. Чего ждать-то?

Цитата
Sergey Gorokhov написал:
Вариантов масса.
Главное определиться с условиями.
Напишите хоть один вариант, который по вашему мнению, будет НЕ МЕНЕЕ НАДЕЖНЫМ, чем предложенный мной.
Условия указаны: скрипт должен определить начальные лимиты по корзине бумаг, в т.ч. по тем, по которым позиции не открыты (=0), прежде чем запустится алгоритм торговли.

Цитата
Sergey Gorokhov написал:
Как быть если брокер в течении дня грузит позиции?
Цитата
Sergey Gorokhov написал:
Брокер начинает грузить позиции, будет он их грузить пачками или все сразу ему самому решать.
В результате сервер не знает сколько позиций брокер будет грузить. Не знает окончился процесс или нет. Вдруг брокеру через час захочется загрузить еще?
Т.е., на начало торговой сессии лимитов нет, а потом вдруг в течение дня в произвольный момент времени они появляются?
Если вы скинете мне документ, описывающий процедуру загрузки лимитов, то я смогу ответить более конструктивно.
Пока я вижу это так: если брокер вдруг станет грузить лимиты не перед открытием сессии, а когда ему "захочется", то к черту такого брокера.

Цитата
Sergey Gorokhov написал:
на стороне брокера есть транзакция на корректировку входящей позиции срочного рынка.
А значит, Вам легко может приехать строка содержащая 0, а потом через некоторое время нормальное значение.
Все же это не обычный случай и просто так не делается.
И решение, предложенное мной, никак не ухудшает ситуацию в таких нестандартных случаях по сравнению с вашим вариантом, код которого вы так и не осмелились показать.

Цитата
Sergey Gorokhov написал:
Как быть?
Для фиксации изменений лимитов использовать колбеки. Это не противоречит моему предложению.

Цитата
Sergey Gorokhov написал:
Целесообразно ли ее вводить в условиях ненадежности
ИТОГО, функция isLimitsLoaded решает проблему с фондовыми, валютными и срочными лимитами в той мере, в которой предназначено ее использование.
В остальных нестандартных ситуациях, хоть я и не видел ваш код, но уверен, что он будет не более надежен, чем мое предложение.
 
Mixa, пойми главное: ты можешь сейчас здесь спорить до посинения хоть два года - ничего не изменится. (см. комментарий про 10 лет)
Пока сам не сделаешь как тебе надо, опираясь лишь на те средства, какие есть.

На что потратить следующие два года твоей жизни - решать тебе.
 
Цитата
Mixa написал:
Напишите хоть один вариант, который по вашему мнению, будет НЕ МЕНЕЕ НАДЕЖНЫМ, чем предложенный мной. Условия указаны: скрипт должен определить начальные лимиты по корзине бумаг, в т.ч. по тем, по которым позиции не открыты (=0), прежде чем запустится алгоритм торговли.

Вам прямым текстом было сказано что надежного варианта нет.
Цитата
Sergey Gorokhov написал:
Спрашивать как его сделать в этом вопросе бесполезно, т.к. надежных способов нет.

Любой вариант НЕ надежен.
Есть только два пути:
1) Придумывать новый НЕ надежный вариант и наткнуться на новые проблемы
2) Использовать старый тоже НЕ надежный вариант, но зато проблемы старые и известные
Из этого следует что п2 "не менее надежный" чем п1 хотя бы тем что с п2 мы знаем с какими проблемами можем столкнуться.
Для примера, "плохие" варианты уже были озвучены:
Цитата
Sergey Gorokhov написал:
Допустим брокер загрузил пачку, isLimitsLoaded вернет true, а именно Ваши лимиты брокер не загрузил, а загрузит их чуть позже. Ваш код в этой ситуации примет решение что лимитов нет (нулевые) а на самом деле они будут позже.

Цитата
Sergey Gorokhov написал:
А значит, Вам легко может приехать строка содержащая 0, а потом через некоторое время нормальное значение.
В аналогичной ситуации цикл из п2 "дождется" лимитов и скрипт нормально отработает.

Можно и дальше придумывать примеры, ограничено это только воображением.

Цитата
Mixa написал:
Если вы скинете мне документ, описывающий процедуру загрузки лимитов, то я смогу ответить более конструктивно.

Документация на рабочее место QUIK, глава "Операции брокера" - "Операции над позициями"
 
Что это за терминал, если даже такая базовая функция, как определение лимитов работает ненадежно?

Цитата
Sergey Gorokhov написал:
Документация на рабочее место QUIK, глава "Операции брокера" - "Операции над позициями"
Это не исчерпывающее описание всех вариантов загрузки лимитов на сервер.

Цитата
Sergey Gorokhov написал:
Самый верный вариант ждать пока нужные скрипту данные появятся в колбеке, если не появились значит ничего не делать.


Цитата
Sergey Gorokhov написал:
1) Придумывать новый НЕ надежный вариант и наткнуться на новые проблемы
2) Использовать старый тоже НЕ надежный вариант, но зато проблемы старые и известные
Чего? Какие "новые проблемы"? Пока я не увидел никаких "новых проблем", с которыми "новый НЕ надежный вариант" справился бы хуже.
Все ваши надуманные проблемы - бред сивой кобылы. Если брокер начнет козлить, он быстро растеряет своих клиентов.
В нормальной ситуации "новый вариант" отработал бы корректно, в отличие от вашего "старого НЕ надежного варианта".

Всегда можно ПРИДУМАТЬ ситуации, когда надежное решение будет работать ненадежно. С таким же успехом можно заявить: зачем делать защиту паролем вход в ЛК, если многие создают простые пароли, к тому же записывают на листочке? А некоторые используют скрипт автологин, в котором указывают пароль. Так давайте уберем окно ввода пароля, ведь
Цитата
Sergey Gorokhov написал:
всегда найдется НО которое делает решение не надежным.


Sergey Gorokhov, какое место вы занимаете в компании и почему решение о "надежности" функционала принимаете вы, а не программисты, которые явно лучше вас в этом разбираются?
 
Mixa,

Ок, еще пример.
Упомянутый sys_events, в документации на P2 сказано что он приходит после окончания загрузки данных на клиента, т.е. в данном случае на сервер, а не терминал QUIK
допустим он попал на сервер утром до торгов, сервер его запомнил с тем чтобы отправить Вам в isLimitsLoaded
Вы ведь этого хотите не так ли?
А что дальше. Ведь событие из sys_events оно одно на всех клиентов, а не отдельно по каждому.
Вы посреди дня запускаете терминал QUIK и запускаете Ваш скрипт.
Терминал подключается к серверу, начинает качать данные и сообщает скрипту isLimitsLoaded=true, т.е. на сервере все лимиты действительно загружены
Что изменится от того что есть сейчас?
Информация на терминал о Вашем лимите еще не пришла (т.к. только подключились).
О том придет Ваш лимит в конце концов или нет скрипт не знает и не узнает даже если будет знать что на сервере все лимиты загружены.
Да благодаря sys_events скрипт будет знать что на сервере все лимиты есть и опять же скрипту придется ждать прокачки данных (то что и сейчас)
Но опять же скрипт не узнает когда эта прокачка закончится, а значит может ждать вечно (ни или то что уже было предложено, делать условие выхода)
Получается sys_events может позволить решить проблему только если рабочее место подключится к серверу ДО старта шлюза срочного рынка.


Цитата
Mixa написал:
Sergey Gorokhov , какое место вы занимаете в компании и почему решение о "надежности" функционала принимаете вы, а не программисты, которые явно лучше вас в этом разбираются?
Вам было уже сказано что этому вопросу уже очень и очень много лет, и решение уже давным давно принято.
По этой причине предлагается альтернативное решение
 
Цитата
Sergey Gorokhov написал:
Терминал подключается к серверу, начинает качать данные и сообщает скрипту isLimitsLoaded=true, т.е. на сервере все лимиты действительно загружены
Это действительно странно, что вы отвечаете в разделе "Программирование" и тем более имеете право принимать решения.
Цитата
Mixa написал:
А вслед за лимитами - уведомление "лимиты загружены". Отдельно для каждой секции.
Таким образом, в какое бы время не подключился клиент, уведомление "лимиты загружены" должно быть отправлено после лимитов.


Цитата
Sergey Gorokhov написал:
этому вопросу уже очень и очень много лет
Потому что этим вопросом занимается человек, мало понимающий в программировании.
 
Цитата
Mixa написал:
Цитата
Sergey Gorokhov написал:
Терминал подключается к серверу, начинает качать данные и сообщает скрипту isLimitsLoaded=true, т.е. на сервере все лимиты действительно загружены
Это действительно странно, что вы отвечаете в разделе "Программирование" и тем более имеете право принимать решения.
Цитата
Mixa написал:
А вслед за лимитами - уведомление "лимиты загружены". Отдельно для каждой секции.
Таким образом, в какое бы время не подключился клиент, уведомление "лимиты загружены" должно быть отправлено  после  лимитов.


Цитата
Sergey Gorokhov написал:
этому вопросу уже очень и очень много лет
Потому что этим вопросом занимается человек, мало понимающий в программировании.
миха, прекращай.

не нравится Горохов - не задавай ему вопросы. Ищи ответы в другом месте.
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
Sergey Gorokhov написал:
Да благодаря sys_events скрипт будет знать что на сервере все лимиты есть и опять же скрипту придется ждать прокачки данных (то что и сейчас)
Но опять же скрипт не узнает когда эта прокачка закончится
Уведомление надо посылать клиенту после прокачки лимитов, тогда скрипт узнает об окончании прокачки по этому уведомлению.

Цитата
Sergey Gorokhov написал:
Для примера, "плохие" варианты уже были озвучены:
Цитата
Sergey Gorokhov написал:
Допустим брокер загрузил пачку, isLimitsLoaded вернет true, а именно Ваши лимиты брокер не загрузил, а загрузит их чуть позже. Ваш код в этой ситуации примет решение что лимитов нет (нулевые) а на самом деле они будут позже.
Если брокер загружает лимиты посреди сессии, то - это внештатная ситуация.

Цитата
Sergey Gorokhov написал:
Цитата
Sergey Gorokhov написал:
А значит, Вам легко может приехать строка содержащая 0, а потом через некоторое время нормальное значение.
Это скорее исключение, чем правило. У подавляющего числа пользователей этого не случится никогда.
А вообще "плохие примеры" притянуты за уши и абсолютно ничего не доказывают.

Цитата
Sergey Gorokhov написал:
Вариант которые уже сейчас решает вопрос уже был предложен
Ждите колбек или смотрите в цикле.
Данные появились - хорошо работаем
Данные не появились - сидим ждем дальше.
Этот вариант не рабочий от слова совсем.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Этот вариант не рабочий от слова совсем.
Почему не рабочий? Ведь им пользуются значит рабочий.
То что не надежный, так это и не скрывается.
Вопрос был что надежней. Только внештатные ситуации и могут дать ответ на этот вопрос.
В идеальных условиях и вопроса о признаке бы не возникло, не так ли.
 
Цитата
Sergey Gorokhov написал:
Данные не появились - сидим ждем дальше.
Цитата
Sergey Gorokhov написал:
Почему не рабочий? Ведь им пользуются значит рабочий.
Именно таким вариантом не пользуется никто.
Эта моделька, где скрипт рвется в бой сразу после получения хотя бы одной позиции в depo_limits. В результате в большинстве случаев получает фальстарт.
В вашем варианте в большинстве случаев вы так и будете сидеть ждать на старте, пока вам не дадут хорошего пинка, т.е. пока кто-то не откроет позиции (или хотя бы не выставит заявки) по всем инструментам, которыми торгует скрипт.

Цитата
Sergey Gorokhov написал:
В идеальных условиях и вопроса о признаке бы не возникло, не так ли.
Не так. Что такое "идеальные условия" в данном контексте? Это когда позиции загружены на сервер до начала торгов, они верные, не требуют корректировки.
Можем ли мы сейчас определить их при "идеальных условиях". Надёжно - нет, вы сами признали.
Возможно ли допилить QUIK таким образом, чтобы позиции можно было бы надёжно определить в "идеальных условиях". Да:
Цитата
Старатель написал:
Уведомление надо посылать клиенту после прокачки лимитов, тогда скрипт узнает об окончании прокачки по этому уведомлению.


Цитата
Sergey Gorokhov написал:
Вопрос был что надежней. Только внештатные ситуации и могут дать ответ на этот вопрос.
Сравнивать надежность во внештатных ситуациях имело бы смысл, если бы ваш вариант надёжно работал в штатной ситуации или, по крайней мере, не хуже предложенной ТС.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Что такое "идеальные условия" в данном контексте? Это когда позиции загружены на сервер до начала торгов, они верные, не требуют корректировки.

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

Цитата
Старатель написал:
Можем ли мы сейчас определить их при "идеальных условиях". Надёжно - нет, вы сами признали.
Про "идеальные условия" было сказано только то что признак вообще не нужен.
 
Цитата
Sergey Gorokhov написал:
Этому вопросу уже больше 10 лет и никто так и не предложил надежного способа.
Цитата
Sergey Gorokhov написал:
признак вообще не нужен
Ну и не надо врать. Так и пишите, что ваши программисты не способны/не хотят (нужное подчеркнуть) сделать по-нормальному.
 
Или что вы сами лично за всех решили, что "признак вообще не нужен".

Цитата
Mixa написал:
Sergey Gorokhov , какое место вы занимаете в компании и почему решение о "надежности" функционала принимаете вы, а не программисты, которые явно лучше вас в этом разбираются?
 
Как об стенку горох.

Sergey Gorokhov, надёжный способ вам предложили, отрицать очевидное бессмысленно.
Теперь вы врёте, всячески изворачиваетесь и бросаетесь из крайности в крайность, пытаясь оправдать своё безделие.

Цитата
Sergey Gorokhov написал:
сам терминал подключен к серверу тоже до начала торгов
Так это существенное ограничение. А в 9-10 часов теперь подключать нельзя?

Тогда уж указывайте в Руководстве "идеальные условия", для которых предназначен QLua, и соответствующие ограничения.
Надо делать так, как надо. А как не надо - делать не надо.
 
Тут вопрос стоит в том, что нет разницы между "архивными" и "текущими" данными - это что называется абстрактный конструкт. Что вообще понимается под "текущие данные"? Наиболее актуальные? Тогда очень старые данные могут быть "текущими" если ничего нового не пришло. Которые соответствуют текущему моменту времени? Тогда вообще все данные  будут "архивными" потому что к моменту прихода данных к вашему терминалу  они уже устарели. Которые не старше ХХХ времени? Тогда старые данные могут считаться "текущими", которые теперь еще и представляют собой большой блок данных а не одну запись, плюс это конфликтует с понятием об актуальных данных которые могут быть очень старые.


Тут проблема не в технической реализации, а в том что вы расплывчатые фантазии из страны бабочек и единорогов пытаетесь натянуть на действительность с железобетонной логикой.
 
Артем, железобетонная логика состоит в том, что стартовые позиции на начало торговой сессии (в принятой терминологии - входящие) можно было бы однозначно определить, имея признак окончания процедуры загрузки лимитов.
А что вы пытаетесь натянуть и что такое "архивные" данные в контексте вопроса, я не знаю.
 
Mixa, О том что признак окончания зависит от определения разграничения между архивными и текущими данными, а такового разграничения нет. Мозгами подумайте как это чисто технически должно было бы работать вообще, псевдокодом хотя бы изложите - тогда и будет разговор. А то сейчас это полемика уровня "прицепите карбюратор к дизелю".
 
Цитата
Артем написал:
определения разграничения между архивными и текущими данными
Вы сами себе эти определения придумали, вот себе и разграничивайте.
А мне нахрен не сдались ваши "архивные данные". Нужны только входящие позиции на СЕГОДНЯ.

А псевдокод вот вам:
Код
function main()
  while isConnected() ~= 1 do
    sleep(100)
    if not is_run then return end
  end
  while isLimitsLoaded("TQBR") ~= true or isLimitsLoaded("SPBFUT") ~= true do -- указать все нужные классы, позиции по которым должны быть загружены
    sleep(100)
    if not is_run then return end
  end
  
end
Теперь можете мозгами подумать.
 
Цитата
Mixa написал:
isLimitsLoaded("TQBR")
Это не будет работать по простой причине, лимиты не привязаны к классу.
Возможно только узнать об окончании загрузки в терминал сразу по всем данным в таблице (отдельно по срочной отдельно по фондовой секциям), т.е. без привязки к классу или бумаге.
Грубо, узнать когда количество загруженных строк в таблице будет равно количеству на сервере в том состоянии которое есть в данный момент.
Такой вариант устроит? Если да готовы зарегистрировать пожелание в соседней ветке
 
Цитата
Sergey Gorokhov написал:
Цитата
Mixa написал:
isLimitsLoaded("TQBR")
Это не будет работать по простой причине, лимиты не привязаны к классу.
Возможно только узнать об окончании загрузки в терминал сразу по всем данным в таблице (отдельно по срочной отдельно по фондовой секциям)
А если подумать?
Код
isLimitsLoaded("фондовая секция") == isLimitsLoaded("TQBR") and isLimitsLoaded("TQOB") and isLimitsLoaded ... все классы на фондовой секции
 
Цитата
Mixa написал:
А если подумать?
В фондовой секции 236 классов, Вы хотите все их указывать? А если класс прекратит свое существование скрипт сломается.
Например, EQBR никто годами не верил что этот класс исчезнет, но он же исчез.
Лимиты не привязаны к классам, думать тут нечего, так было всегда.
Одна бумага может быть в разных классах и даже на разных биржах.
 
Цитата
Sergey Gorokhov написал:
отдельно по срочной отдельно по фондовой секциям), т.е. без привязки к классу или бумаге.
Загрузка лимитов по фондовой секции автоматически означает, что загружены лимиты по ВСЕМ классам этой секции.
isLimitsLoaded вернет true тогда и только тогда, когда загружены ВСЕ лимиты секции.

Цитата
Sergey Gorokhov написал:
В фондовой секции 236 классов, Вы хотите все их указывать?
Да нафига мне указывать все классы в скрипте?
Я укажу только НУЖНЫЕ мне. Мне даже не надо перечислять все классы, а только по одному классу каждой секции, на которой скрипт торгует.
 
Цитата
Mixa написал:
Я укажу только НУЖНЫЕ мне. Мне даже не надо перечислять все классы, а только по одному классу каждой секции, на которой скрипт торгует.

Сделать задуманное означает реализовать/создать привязку лимита к классам. Проще говоря, чтобы по каждому лимиту, где то хранился список классов.
Как уже было сказано сейчас такой привязки просто нет, ни в сервере ни в терминале, и никогда не было.
Хранить где-то такой список ради одной функции явно выглядит нецелесообразным.
 
Цитата
Sergey Gorokhov написал:
Сделать задуманное означает реализовать/создать привязку лимита к классам. Проще говоря, чтобы по каждому лимиту, где то хранился список классов.

Кажется понимаю, что вы хотите сказать: в таблицах depo_limits и futures_client_holding нет параметра "Класс". Вы об этом?
Можно сделать привязку к фирме или счету. Если я правильно понимаю, технически это равнозначно:
"Загрузка всех лимитов на фондовой секции" == "загрузка лимитов по всем классам фондовой секции" == "загрузка лимитов по всем trdaccid, привязанным к фондовой площадке" == "загрузка лимитов по всем firmid, привязанным к фондовой площадке"
 
Цитата
Mixa написал:
Можно сделать привязку к фирме или счету.

Т.е., в скрипте:
Код
if isLimitsLoaded(firmid) == true
или
Код
if isLimitsLoaded(trdaccid) == true
 
Цитата
Mixa написал:
Кажется понимаю, что вы хотите сказать: в таблицах depo_limits и futures_client_holding нет параметра "Класс". Вы об этом?

Вот именно, что там нет такого параметра.
Причина в том что
Цитата
Sergey Gorokhov написал:
Одна бумага может быть в разных классах и даже на разных биржах.

Цитата
Mixa написал:
Можно сделать привязку к фирме или счету. Если я правильно понимаю, технически это равнозначно:"Загрузка всех лимитов на фондовой секции" == "загрузка лимитов по всем классам фондовой секции" == "загрузка лимитов по всем trdaccid, привязанным к фондовой площадке" == "загрузка лимитов по всем firmid, привязанным к фондовой площадке"

На фондовом и Валютном рынках, сервер выбирает лимиты для отправки по фирме и коду клиента (не торговому счету)
А на срочном, по фирме и торговому счету (НЕ коду клиента)
Код клиента и торговый счет это абсолютно разные вещи. Так на фондовом рынке по одному торговому счету могут торговать сотни клиентов. А на срочном только один.
На всех рынках может быть одна фирма, а могут быть разные. Если делать привязку к фирме, нет абсолютно никаких гарантий что true будет именно по нужной секции.
Банальный пример, срочный и фондовый рынки объединены в одну фирму, isLimitsLoaded(firmid) вернет true, по какому рынку?
Со счетом может быть еще сложнее т.к. на том же СПБ и MOEX счета могут совпадать, а фирмы нет.
Только связка фирма + торговый счет (или код клиента) вернет правильное значение, но опять же без класса, без рынка.

Чем предложенный вариант не устаревает?
Цитата
Sergey Gorokhov написал:
узнать когда количество загруженных строк в таблице будет равно количеству на сервере в том состоянии которое есть в данный момент.
 
Цитата
Sergey Gorokhov написал:
Одна бумага может быть даже на разных биржах.
Цитата
Sergey Gorokhov написал:
на сервере лимит есть, он не знает можно ли давать его пользователю, пользователь подключился лимит не видит. А потом когда шлюз запустят лимит вдруг появился.
Как в этом случае будут загружаться лимиты? После запуска какого из шлюзов?

Цитата
Sergey Gorokhov написал:
на том же СПБ и MOEX счета могут совпадать, а фирмы нет.
А код клиента?

Цитата
Sergey Gorokhov написал:
но опять же без класса, без рынка.
Для решения задачи этого и не требуется. Грубо говоря, нам нужно уведомление, что лимиты по конкретному рынку загружены, но, поскольку в QUIK нет такого понятия "рынок", нужно делать привязку к чему-то другому.

Цитата
Sergey Gorokhov написал:
Чем предложенный вариант не устаревает?
Цитата
Sergey Gorokhov написал:
узнать когда количество загруженных строк в таблице будет равно количеству на сервере в том состоянии которое есть в данный момент.

Вы же сами пишите, что сервер может транслировать не все лимиты, которые на него загружены:
Цитата
Sergey Gorokhov написал:
сервер не будет транслировать фондовые лимиты по тем инструментам которые отсутствуют, либо у пользователя нет прав.
 
Постоянный спор. Вот это "Грубо, узнать когда количество загруженных строк в таблице будет равно  количеству на сервере в том состоянии которое есть в данный момент." было бы полезно.
Получать событие когда количество строк в таблицах futures_client_limits, money_limits, depo_limits на сервере и клиенте стали разные и обратно одинаковые.
Правда само число строк мало о чем говорит, если только это не очистка и заполнение.
Страницы: 1 2 3 След.
Читают тему
Наверх