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

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

Страницы: Пред. 1 2
Написание автономного бота
 
Цитата
Sergey Gorokhov написал:
Этому вопросу уже больше 10 лет и никто так и не предложил надежного способа.
Да ладно! Посчитать количество записей в таблице на сервере и отправить число клиенту. В чем проблема?

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

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

Цитата
Sergey Gorokhov написал:
Самый верный вариант ждать пока нужные скрипту данные появятся в колбеке, если не появились значит ничего не делать.
Что это за рекомендация такая? Как скрипт узнает сколько колбеков ждать и ждать ли вообще?
А если OnFuturesClientHolding не будет? "Ничего не делать"?
Написание автономного бота
 
Цитата
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,
В скрипте go() - это функция, когда бот определил все текущие позиции и может начать торговлю.

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

Цитата
Sergey Gorokhov написал:
что подразумевается под "не правильно"?
Получены не все открытые позиции.
Написание автономного бота
 
Цитата
BlaZed написал:
if getNumberOf('FUTURES_CLIENT_HOLDING')>0 then -- Таблица "Позиции по клиентским счетам (фьючерсы)" заполнена
ПОЛНОСТЬЮ заполнена?
А если getNumberOf('FUTURES_CLIENT_HOLDING') = 0?
Написание автономного бота
 
Цитата
BlaZed написал:
if getNumberOf('FUTURES_CLIENT_HOLDING')>0 then -- Таблица "Позиции по клиентским счетам (фьючерсы)" заполнена
ПОЛНОСТЬЮ заполнена?
А если getNumberOf = 0?
Написание автономного бота
 
Sergey Gorokhov,
Согласно Регламента работы по обращениям клиентов по проблемам в коде
Код
Для получения корректного ответа необходимо ёмкое описание проблемы с примером кода, который не работает или работает неправильно. В этом случае мы оказываем всяческую поддержку пользователям.
я предоставил пример кода и ёмкое описание проблемы.

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

Столкнулся со проблемой написания бота, который бы работал автономно без контроля со стороны человека.
Документ "Использование 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

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

Ув. разработчики., могли бы вы оказать поддержку в доработке скрипта, чтобы он корректно работал в любой штатной* ситуации?
* Здесть имеется ввиду, что ТС биржи и сервер брокера работают штатно, без сбоев.
Страницы: Пред. 1 2
Наверх