Добрый день. У нас в компании работает скрипт, сохраняющий сделки в нужном нам формате для загрузки в учетные системы. Но иногда бывают сбои - пользователь может случайно закрыть табличку и ... сделок нет. Хотя бы на один-два дня глубиной хранить историю сделок было бы очень актуально. Брокер, к сожалению, дает какой-то невообразимо дурацкий формат для загрузки сделок, а квиковский нам нравится.
Поддерживаю - сделайте пожалуйста чтобы Квик автоматически локально сохранял в файл на компьютер пользователя всю историю сделок - этого крайне не хватает - и пользователь сам решит (то есть может сам чистить историю или нет) то есть городить ничего не надо - просто сделайте что бы в Квике отображалась история сделок как на графике так и в окне сделки и инфа будет браться из автоматически сохранённого файла - поскольку городить и напичкивать в Квик разные (сторонние приблуды) для сохранения истории сделок это абсурд - это же есть по умолчанию даже в банальном МТ4-5 как впрочем и во всех платформах вообще по умолчанию - и было бы хорошо иметь возможность экспорт в exel
Константин написал: Могу предложить полуфабрикат для хранения истории в своей базе данных Написано на 1С Придется ознакомиться с 1С
Спасибо не надо - тут смысл ИМЕННО в том ЧТО БЫ ОТКАЗАТЬСЯ от сторонних решений - поймите ВАЖНО ИМЕННО чтобы в Квике это было реализовано ИМЕННО разработчиком!
Константин написал: Могу предложить полуфабрикат для хранения истории в своей базе данныхНаписано на 1СПридется ознакомиться
Вот не надо совсем. Надо, чтоб Quik выдал сегодня вчерашние сделки. Всё.
А ЕЩЕ ЛУЧШЕ что бы история сделок была с неограниченной длительностью - поскольку не все торгуют внутри дня - сделки есть и на несколько дней - повторюсь история может локально сохраняться в файл на автомате в самой программе, если история не нужна можно ее очистить как удалением файла так и в самом Квике - это же можно сделать все банально до невозможного!
Константин написал: Могу предложить полуфабрикат для хранения истории в своей базе данныхНаписано на 1СПридется ознакомиться
Вот не надо совсем. Надо, чтоб Quik выдал сегодня вчерашние сделки. Всё.
А ЕЩЕ ЛУЧШЕ что бы история сделок была с неограниченной длительностью - поскольку не все торгуют внутри дня - сделки есть и на несколько дней - повторюсь история может локально сохраняться в файл на автомате в самой программе, если история не нужна можно ее очистить как удалением файла так и в самом Квике - это же можно сделать все банально до невозможного!
И файл в который все сохраняется (если его удалить) заново создается самим Квиком для новой истории сделок-)
Ирина Никонова написал: Уже на дворе 2024-й год, а Квик все еще интрадейная система...увы%(
Самое важное в торговой платформе это не графики и тд - это банальное выставление ордеров и все что с этим связано - в Квике это не реализовано на должном уровне - как пример МОЖНО же сделать как в Trading View торговый модуль с калькулятором позиций И историей позиций - но почему то ЭТО никто не делает - это же НАИПЕРВЕЙШАЯ важность по определению - но этого никто не понимает !
Суммы сделок которые проходят в QUIK отличаются от отчета брокера на следующий день. Если попытаться реализовать Ваши потребности, то придется интегрировать QUIK со всеми брокерами сразу. Это долго и дорого.
Точнее даже так: Отче брокера может отличаться как суммами сделок, так и комиссиями так и вообще наличием конкретной сделки. В QUIK была, а в отчете брокера не случилась по каким то причинам.
Константин написал: Суммы сделок которые проходят в QUIK отличаются от отчета брокера на следующий день. Если попытаться реализовать Ваши потребности, то придется интегрировать QUIK со всеми брокерами сразу. Это долго и дорого.
Я что то не пойму КАК может быть различия - если я к примеру за месяц провел 50 сделок - как они могут отличаться хоть у брокера или в Квике - 50 сделок и в африке 50 - они что что то припишут или вычтут НЕПОНЯТНО !!! Даже в мт5 все нормально по этому поводу - о каком несоответствии Вы говорите НЕПОНЯТНО!
не если в месяц 50 сделок то ошибок возможно и нет. Разные инструменты в разные дни. А вот если вдень много сделать купли продажи одного и того же то пара тройка пропадет в завтрашнем отчете брокера.
Константин написал: не если в месяц 50 сделок то ошибок возможно и нет. Разные инструменты в разные дни. А вот если вдень много сделать купли продажи одного и того же то пара тройка пропадет в завтрашнем отчете брокера.
А если эти сделки прибыльные - как вообще такое возможно это же обман со стороны брокера - он вообще не имеет права на 1000% потасовывать данные - провел трейдер за день 567 сделок - брокер обязан все на 1000% указать в отчете - вроде время (кухонь прошло)
Денег никто не украдет. Просто сделка купли пропадет и сделка продажи пропадет как их обеих не было. Возможно это как то связано что они как то не прошли у другого брокера. Не знаю как насчет других программ. Чтобы проверить попробуйте каждый вечер сохранять в Excel наличие в портфеле а потом сверять его например утром до начала торгов.
На всякий случай напишу. Это не каждый день. Но бывает. Поэтому то и сложно интегрироваться со всеми брокерами сразу если хранить историю. Думаю дуло в этом.
Константин написал: Суммы сделок которые проходят в QUIK отличаются от отчета брокера на следующий день. Если попытаться реализовать Ваши потребности, то придется интегрировать QUIK со всеми брокерами сразу. Это долго и дорого.
А ПОЧЕМУ у Брокеров (банки итд) все нормально с MetaTrader 5 - там все нормально с историей как у брокеров так и в самом МТ5 (и вроде не говорили что на это денег нет ) а просто по умолчанию сделали как впрочем во всех торговых терминалах - все по умолчанию делается поскольку это первостепенная важность!
Квику надо ИМЕННО нормально на уровне серверов и не только все переделать что касается торговли и выставления ордеров Простите но нет банального стоплосса к отложенному ордеру - повторюсь в МТ5 это есть тут нет!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Я так понимаю QUIK работает через систему серверов QUIK МТ работает через систему серверов MT Это разные принципы. Чтобы проверить правильно ли в МТ попробуйте сохранять в Excel Возможно Вам завтра сервер МТ дает переписанную историю. Вы же в голове не помните все сделки и суммы. Этот как модная сейчас торговля через маркетплейсы. Маркетплейс сам придумывает цифры и говорят что так и было.
Ирина Никонова написал: Добрый день. У нас в компании работает скрипт, сохраняющий сделки в нужном нам формате для загрузки в учетные системы. Но иногда бывают сбои - пользователь может случайно закрыть табличку и ... сделок нет. Хотя бы на один-два дня глубиной хранить историю сделок было бы очень актуально. Брокер, к сожалению, дает какой-то невообразимо дурацкий формат для загрузки сделок, а квиковский нам нравится.
Попробую объяснить почему это не будет сделано. ------------------------ Согласно ФЗ о рынке ЦБ сделки на бирже делает не клиент, а брокер. QUIK лишь терминал для подачи заявок брокеру. . Поэтому действительны лишь те сделки , которые есть в отчете брокера. -------------------- При этом, если Вы выключили QUIK, то историю сделок Вы не получите, а брокер, вне зависимости от включения QUIK, обязательно Вам ее передаст согласно ГК РФ. -------------------- В итоге то, что прислал брокер это и есть Ваши сделки. ------------------ Если формат не устраивает, то конвертируйте в другой формат. Это техническая задача на уровне студента.
nikolz написал: если Вы выключили QUIK, то историю сделок Вы не получите, а брокер, вне зависимости от включения QUIK, обязательно Вам ее передаст согласно ГК РФ.
Поумничали.... А нам не официальный отчет нужен, а просто табличка из Квик со сделками на предыдущий день. Без всякого ГК. Для сервиса удобного, а не ради соблюдения ГК. Брокеров много, от каждого идет свой формат загрузки, иногда дурацкий. Простая структура данных, которую самая стать построчно формировать, в такую матрешку оборачивается, запаришься ее обрабатывать. А из Квика можно получать одинаковые файлы от разных брокеров.
nikolz написал: если Вы выключили QUIK, то историю сделок Вы не получите, а брокер, вне зависимости от включения QUIK, обязательно Вам ее передаст согласно ГК РФ.
Поумничали.... А нам не официальный отчет нужен, а просто табличка из Квик со сделками на предыдущий день. Без всякого ГК. Для сервиса удобного, а не ради соблюдения ГК. Брокеров много, от каждого идет свой формат загрузки, иногда дурацкий. Простая структура данных, которую самая стать построчно формировать, в такую матрешку оборачивается, запаришься ее обрабатывать. А из Квика можно получать одинаковые файлы от разных брокеров.
Ну,ну. Я Вам объяснил, почему делать филькину грамоту Вам никто не будет. Ну если Вы других не дурите, то вам можно .
Ирина Никонова, Если Вас я правильно понял, Вам нужна история собственных сделок, формат csv наверняка подходит, вот код копируйте запускайте, он создаст историю по всем счетам и будет сохранять собственные сделки, все что нужно запустить скрипт (утилиту) и забыть, остальное она сделает сама, Ваша задача выгружать в excel нужный файл и анализировать или еще чего. Если попали в точку, меня не нужно благодарить, благодарить нужно автора, возможно даже благотворительность проявлять, и здесь не важно сколько, важно как. От себя ни чего добавить не могу, так как запустил когда то и забыл, думаю что это тот самый вариант автора, судите сами. Взято https://quikluacsharp.ru/.
Код
local Run = nil; -- флаг работы цикла в main
local DataFolder = ''; -- Полный путь к папке "Данные(c)quikluacsharp.ru"
local TradesFiles = {};-- Массив дескрипторов файлов
-- Создает каталоги по всем найденным счетам
function CreateAccountsFolders()
-- Перебирает все счета
for i=0, getNumberOf("trade_accounts")-1 do
-- Получает номер счета
local Account = getItem("trade_accounts", i).trdaccid;
-- Получает путь
local Path = '"'..DataFolder..Account..'\\"';
-- Если каталог не существует
if os.execute('cd '..Path) == 1 then
-- Создает каталог
os.execute('mkdir '..Path);
end;
end;
end;
-- Проверяет записана ли данная сделка в файл истории
function CheckTradeInFile(trade)
-- Получает путь к файлу инструмента в папке торгового счета
local PathAccountSec = DataFolder..trade.account..'\\'..trade.sec_code..'.csv';
-- Пытается открыть файл текущего инструмента в режиме "чтения"
local TradesFile = io.open(PathAccountSec,"r");
-- Если файл не существует, то сделка не записана
if TradesFile == nil then return false;
else -- Если файл существует
-- Получает индекс файла
local FileIndex = trade.account..'_'..trade.sec_code;
-- Если файл еще не открыт для дописывания
if TradesFiles[FileIndex] == nil then
-- Открывает файл текущего инструмента в режиме "дописывания"
TradesFiles[FileIndex] = io.open(PathAccountSec,"a+");
end;
-- Перебирает строки файла
local Count = 0; -- Счетчик строк
for line in TradesFile:lines() do
Count = Count + 1;
if Count > 1 and line ~= "" then
-- Если номера сделок совпадают, то сделка записана
local i = 0;
for str in line:gmatch("[^;^\n]+") do
i = i + 1;
if i == 3 and tonumber(str) == trade.trade_num then
TradesFile:close();
return true;
end;
end;
end;
end;
end;
TradesFile:close();
return false;
end;
-- Записывает все ранее не записанные сделки из таблицы "Сделки" в файлы
function CheckAndSaveTerminalTrades()
local trade = nil;
-- Перебирает все сделки в таблице "Сделки"
for i=0,getNumberOf("trades")-1,1 do
trade = getItem ("trades", i);
-- Если данная сделка еще не записана в файл истории
if not CheckTradeInFile(trade) then
-- Добавляет сделку в файл истории
AddTradeInFile(trade);
end;
end;
end;
-- Добавляет новую сделку в файл истории
function AddTradeInFile(trade)
local DateTime = trade and trade.datetime;
local Date = tonumber(DateTime.year);
local month = tostring(DateTime.month);
if #month == 1 then Date = Date.."0"..month; else Date = Date..month; end;
local day = tostring(DateTime.day);
if #day == 1 then Date = Date.."0"..day; else Date = Date..day; end;
Date = tonumber(Date);
local Time = "";
local hour = tostring(DateTime.hour);
if #hour == 1 then Time = Time.."0"..hour; else Time = Time..hour; end;
local minute = tostring(DateTime.min);
if #minute == 1 then Time = Time.."0"..minute; else Time = Time..minute; end;
local sec = tostring(DateTime.sec);
if #sec == 1 then Time = Time.."0"..sec; else Time = Time..sec; end;
Time = tonumber(Time);
-- Если ночная сделка, смещает дату на 1 день вперед
if Time < 90000 then
local seconds = os.time(DateTime);
seconds = seconds + 24*60*60;
DateTime = os.date("*t",seconds);
Date = tonumber(DateTime.year);
month = tostring(DateTime.month);
if #month == 1 then Date = Date.."0"..month; else Date = Date..month; end;
day = tostring(DateTime.day);
if #day == 1 then Date = Date.."0"..day; else Date = Date..day; end;
Date = tonumber(Date);
end;
local Operation = "";
if CheckBit(trade.flags, 2) == 1 then Operation = "S"; else Operation = "B"; end;
-- Добавляет сделку в массив
local Trade = {};
Trade.Account = trade.account;
Trade.Sec_code = trade.sec_code;
Trade.Num = trade.trade_num;
Trade.Date = Date;
Trade.Time = Time;
Trade.Operation = Operation;
Trade.Qty = tonumber(trade.qty);
Trade.Price = tonumber(trade.price);
Trade.Hint = "Счет: "..Trade.Account.."_Номер: "..trade.trade_num.."_Дата: ";
if #day == 1 then Trade.Hint = Trade.Hint.."0"..day.."/"; else Trade.Hint = Trade.Hint..day.."/"; end;
if #month == 1 then Trade.Hint = Trade.Hint.."0"..month.."/"..DateTime.year; else Trade.Hint = Trade.Hint..month.."/"..DateTime.year; end;
if #hour == 1 then Trade.Hint = Trade.Hint.."_Время: 0"..hour..":"; else Trade.Hint = Trade.Hint.."_Время: "..hour..":"; end;
if #minute == 1 then Trade.Hint = Trade.Hint.."0"..minute..":"; else Trade.Hint = Trade.Hint..minute..":"; end;
if #sec == 1 then Trade.Hint = Trade.Hint.."0"..sec; else Trade.Hint = Trade.Hint..sec; end;
Trade.Hint = Trade.Hint.."_Количество: "..trade.qty;
Trade.Hint = Trade.Hint.."_Цена: "..trade.price;
-- Получает путь к файлу инструмента в папке торгового счета
local PathAccountSec = DataFolder..Trade.Account..'\\'..Trade.Sec_code..'.csv';
local FileIndex = Trade.Account..'_'..Trade.Sec_code;
-- Если файл еще не открыт, или не существует
if TradesFiles[FileIndex] == nil then
-- Пытается открыть файл текущего инструмента в режиме "дописывания"
TradesFiles[FileIndex] = io.open(PathAccountSec,"a+");
-- Если файл не существует, то сделка не записана
if TradesFiles[FileIndex] == nil then
-- Создает файл в режиме "записи"
TradesFiles[FileIndex] = io.open(PathAccountSec,"w");
-- Закрывает файл
message('Закрывает файл: ' ..tostring(FileIndex))
TradesFiles[FileIndex]:close();
-- Открывает уже существующий файл в режиме "дописывания"
TradesFiles[FileIndex] = io.open(PathAccountSec,"a+");
end;
end;
-- Встает в начало файла
TradesFiles[FileIndex]:seek("set",0);
-- Если файл пустой
if TradesFiles[FileIndex]:read() == nil then
-- Добавляет строку заголовков
TradesFiles[FileIndex]:write("Счет;Код бумаги;Номер сделки;Дата сделки;Время сделки;Операция;Количество;Цена;Текст подсказки", "\n");
end;
-- Встает в конец файла
TradesFiles[FileIndex]:seek("end",0);
-- Записывает сделку в файл
TradesFiles[FileIndex]:write(Trade.Account..";"..Trade.Sec_code..";"..Trade.Num..";"..Trade.Date..";"..Trade.Time..";"..Trade.Operation..";"..Trade.Qty..";"..Trade.Price..";"..Trade.Hint, "\n");TradesFiles[FileIndex]:flush();
end;
-- Функция возвращает значение бита (число 0, или 1) под номером bit (начинаются с 0) в числе flags, если такого бита нет, возвращает nil
function CheckBit(flags, bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~= "number" then error("Ошибка!!! Checkbit: 1-й аргумент не число!"); end;
if type(bit) ~= "number" then error("Ошибка!!! Checkbit: 2-й аргумент не число!"); end;
local RevBitsStr = ""; -- Перевернутое (задом наперед) строковое представление двоичного представления переданного десятичного числа (flags)
local Fmod = 0; -- Остаток от деления
local Go = true; -- Флаг работы цикла
while Go do
Fmod = math.fmod(flags, 2); -- Остаток от деления
flags = math.floor(flags/2); -- Оставляет для следующей итерации цикла только целую часть от деления
RevBitsStr = RevBitsStr ..tostring(Fmod); -- Добавляет справа остаток от деления
if flags == 0 then Go = false; end; -- Если был последний бит, завершает цикл
end;
-- Возвращает значение бита
local Result = RevBitsStr:sub(bit+1,bit+1);
if Result == "0" then return 0;
elseif Result == "1" then return 1;
else return nil;
end;
end;
-- Функция возвращает значение бита (0 или 1) под номером bit в числе flags
function CheckBit1(flags, bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~= "number" or type(bit) ~= "number" then
error("Ошибка!!! CheckBit: оба аргумента должны быть числами!")
end
-- Проверяет, что бит под номером bit существует в числе flags
if bit < 0 or bit >= (8 * sizeof(flags)) then
return nil
end
-- Извлекает значение бита с помощью побитовой операции
local bitValue = (bit32.band(flags, bit32.lshift(1, bit)) > 0) and 1 or 0
return bitValue
end
-----------------
function OnTrade(trade)
-- Если данная сделка еще не записана в файл истории
if not CheckTradeInFile(trade) then
-- Добавляет сделку в файл истории
AddTradeInFile(trade);
end;
end;
function OnStop()
-- Закрывает все файлы
for key,Handle in pairs(TradesFiles) do
if Handle ~= nil then Handle:close(); end;
end;
Run = false;
end;
function OnInit()
Run = true;
-- Получает полный путь к папке "Данные(c)quikluacsharp.ru"
DataFolder = getWorkingFolder()..'\\Данные(c)quikluacsharp.ru\\';
-- Создает папки по всем найденным счетам
CreateAccountsFolders();
-- Записывает все ранее не записанные сделки из таблицы "Сделки" в файлы
CheckAndSaveTerminalTrades();
end;
function main()
while Run do
sleep(1);
end;
end;
VPM написал: Ирина Никонова, Если Вас я правильно понял, Вам нужна история собственных сделок, формат csv наверняка подходит, вот код копируйте запускайте, он создаст историю по всем счетам и будет сохранять собственные сделки, все что нужно запустить скрипт (утилиту) и забыть, остальное она сделает сама, Ваша задача выгружать в excel нужный файл и анализировать или еще чего. Если попали в точку, меня не нужно благодарить, благодарить нужно автора, возможно даже благотворительность проявлять, и здесь не важно сколько, важно как. От себя ни чего добавить не могу, так как запустил когда то и забыл, думаю что это тот самый вариант автора, судите сами. Взято https://quikluacsharp.ru/ .
Код
local Run = nil ; -- флаг работы цикла в main
local DataFolder = '' ; -- Полный путь к папке "Данные(c)quikluacsharp.ru"
local TradesFiles = {}; -- Массив дескрипторов файлов
-- Создает каталоги по всем найденным счетам
function CreateAccountsFolders ()
-- Перебирает все счета
for i = 0 , getNumberOf ( "trade_accounts" ) - 1 do
-- Получает номер счета
local Account = getItem ( "trade_accounts" , i).trdaccid;
-- Получает путь
local Path = '"' .. DataFolder .. Account .. '\\"';
-- Если каталог не существует
if os.execute ( 'cd ' .. Path) = = 1 then
-- Создает каталог
os.execute ( 'mkdir ' .. Path);
end ;
end ;
end ;
-- Проверяет записана ли данная сделка в файл истории
function CheckTradeInFile (trade)
-- Получает путь к файлу инструмента в папке торгового счета
local PathAccountSec = DataFolder .. trade.account .. '\\' .. trade.sec_code .. '.csv';
-- Пытается открыть файл текущего инструмента в режиме "чтения"
local TradesFile = io.open (PathAccountSec,"r");
-- Если файл не существует, то сделка не записана
if TradesFile = = nil then return false ;
else -- Если файл существует
-- Получает индекс файла
local FileIndex = trade.account .. '_' .. trade.sec_code;
-- Если файл еще не открыт для дописывания
if TradesFiles[FileIndex] = = nil then
-- Открывает файл текущего инструмента в режиме "дописывания"
TradesFiles[FileIndex] = io.open (PathAccountSec,"a + ");
end ;
-- Перебирает строки файла
local Count = 0 ; -- Счетчик строк
for line in TradesFile:lines() do
Count = Count + 1 ;
if Count > 1 and line ~ = "" then
-- Если номера сделок совпадают, то сделка записана
local i = 0 ;
for str in line:gmatch( "[^;^\n]+" ) do
i = i + 1 ;
if i = = 3 and tonumber(str) = = trade.trade_num then
TradesFile:close();
return true ;
end ;
end ;
end ;
end ;
end ;
TradesFile:close();
return false ;
end ;
-- Записывает все ранее не записанные сделки из таблицы "Сделки" в файлы
function CheckAndSaveTerminalTrades ()
local trade = nil ;
-- Перебирает все сделки в таблице "Сделки"
for i = 0 , getNumberOf ( "trades" ) - 1 , 1 do
trade = getItem ( "trades" , i);
-- Если данная сделка еще не записана в файл истории
if not CheckTradeInFile(trade) then
-- Добавляет сделку в файл истории
AddTradeInFile(trade);
end ;
end ;
end ;
-- Добавляет новую сделку в файл истории
function AddTradeInFile (trade)
local DateTime = trade and trade.datetime;
local Date = tonumber(DateTime.year);
local month = tostring(DateTime.month);
if # month = = 1 then Date = Date .. " 0 " .. month; else Date = Date .. month; end ;
local day = tostring(DateTime.day);
if # day = = 1 then Date = Date .. " 0 " .. day; else Date = Date .. day; end ;
Date = tonumber(Date);
local Time = "" ;
local hour = tostring(DateTime.hour);
if # hour = = 1 then Time = Time .. " 0 " .. hour; else Time = Time .. hour; end ;
local minute = tostring(DateTime.min);
if # minute = = 1 then Time = Time .. " 0 " .. minute; else Time = Time .. minute; end ;
local sec = tostring(DateTime.sec);
if # sec = = 1 then Time = Time .. " 0 " .. sec; else Time = Time .. sec; end ;
Time = tonumber(Time);
-- Если ночная сделка, смещает дату на 1 день вперед
if Time < 90000 then
local seconds = os.time (DateTime);
seconds = seconds + 24 * 60 * 60 ;
DateTime = os.date ( "*t" ,seconds);
Date = tonumber(DateTime.year);
month = tostring(DateTime.month);
if # month = = 1 then Date = Date .. " 0 " .. month; else Date = Date .. month; end ;
day = tostring(DateTime.day);
if # day = = 1 then Date = Date .. " 0 " .. day; else Date = Date .. day; end ;
Date = tonumber(Date);
end ;
local Operation = "" ;
if CheckBit(trade.flags, 2 ) = = 1 then Operation = "S" ; else Operation = "B" ; end ;
-- Добавляет сделку в массив
local Trade = {};
Trade.Account = trade.account;
Trade.Sec_code = trade.sec_code;
Trade.Num = trade.trade_num;
Trade.Date = Date;
Trade.Time = Time;
Trade.Operation = Operation;
Trade.Qty = tonumber(trade.qty);
Trade.Price = tonumber(trade.price);
Trade.Hint = "Счет: " .. Trade.Account .. "_Номер: "..trade.trade_num.." _Дата: ";
if #day == 1 then Trade.Hint = Trade.Hint.." 0 " .. day .. "/"; else Trade.Hint = Trade.Hint .. day .. "/"; end ;
if # month = = 1 then Trade.Hint = Trade.Hint .. " 0 " .. month .. "/" .. DateTime.year; else Trade.Hint = Trade.Hint .. month .. "/" .. DateTime.year; end ;
if # hour = = 1 then Trade.Hint = Trade.Hint .. "_Время: 0 " .. hour .. ":"; else Trade.Hint = Trade.Hint .. "_Время: "..hour.." :"; end ;
if # minute = = 1 then Trade.Hint = Trade.Hint .. " 0 " .. minute .. ":"; else Trade.Hint = Trade.Hint .. minute .. ":"; end ;
if # sec = = 1 then Trade.Hint = Trade.Hint .. " 0 " .. sec; else Trade.Hint = Trade.Hint .. sec; end ;
Trade.Hint = Trade.Hint .. "_Количество: "..trade.qty;
Trade.Hint = Trade.Hint.." _Цена: "..trade.price;
-- Получает путь к файлу инструмента в папке торгового счета
local PathAccountSec = DataFolder..Trade.Account..'\ \' ..Trade.Sec_code..'.csv';
local FileIndex = Trade.Account..'_'..Trade.Sec_code;
-- Если файл еще не открыт, или не существует
if TradesFiles[FileIndex] == nil then
-- Пытается открыть файл текущего инструмента в режиме " дописывания"
TradesFiles[FileIndex] = io.open (PathAccountSec,"a + ");
-- Если файл не существует, то сделка не записана
if TradesFiles[FileIndex] = = nil then
-- Создает файл в режиме "записи"
TradesFiles[FileIndex] = io.open (PathAccountSec,"w");
-- Закрывает файл
message ( 'Закрывает файл: ' .. tostring(FileIndex))
TradesFiles[FileIndex]:close();
-- Открывает уже существующий файл в режиме "дописывания"
TradesFiles[FileIndex] = io.open (PathAccountSec,"a + ");
end ;
end ;
-- Встает в начало файла
TradesFiles[FileIndex]:seek( "set" , 0 );
-- Если файл пустой
if TradesFiles[FileIndex]:read() = = nil then
-- Добавляет строку заголовков
TradesFiles[FileIndex]:write( "Счет;Код бумаги;Номер сделки;Дата сделки;Время сделки;Операция;Количество;Цена;Текст подсказки" , "\n" );
end ;
-- Встает в конец файла
TradesFiles[FileIndex]:seek( "end" , 0 );
-- Записывает сделку в файл
TradesFiles[FileIndex]:write(Trade.Account .. ";" .. Trade.Sec_code .. ";" .. Trade.Num .. ";" .. Trade.Date .. ";" .. Trade.Time .. ";" .. Trade.Operation .. ";" .. Trade.Qty .. ";" .. Trade.Price .. ";" .. Trade.Hint, "\n" );TradesFiles[FileIndex]:flush();
end ;
-- Функция возвращает значение бита (число 0, или 1) под номером bit (начинаются с 0) в числе flags, если такого бита нет, возвращает nil
function CheckBit (flags, bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~ = "number" then error( "Ошибка!!! Checkbit: 1-й аргумент не число!" ); end ;
if type(bit) ~ = "number" then error( "Ошибка!!! Checkbit: 2-й аргумент не число!" ); end ;
local RevBitsStr = "" ; -- Перевернутое (задом наперед) строковое представление двоичного представления переданного десятичного числа (flags)
local Fmod = 0 ; -- Остаток от деления
local Go = true ; -- Флаг работы цикла
while Go do
Fmod = math.fmod (flags, 2 ); -- Остаток от деления
flags = math.floor (flags/ 2 ); -- Оставляет для следующей итерации цикла только целую часть от деления
RevBitsStr = RevBitsStr .. tostring(Fmod); -- Добавляет справа остаток от деления
if flags = = 0 then Go = false ; end ; -- Если был последний бит, завершает цикл
end ;
-- Возвращает значение бита
local Result = RevBitsStr:sub(bit + 1 ,bit + 1 );
if Result = = "0" then return 0 ;
elseif Result = = "1" then return 1 ;
else return nil ;
end ;
end ;
-- Функция возвращает значение бита (0 или 1) под номером bit в числе flags
function CheckBit1 (flags, bit)
-- Проверяет, что переданные аргументы являются числами
if type(flags) ~ = "number" or type(bit) ~ = "number" then
error( "Ошибка!!! CheckBit: оба аргумента должны быть числами!" )
end
-- Проверяет, что бит под номером bit существует в числе flags
if bit < 0 or bit > = ( 8 * sizeof(flags)) then
return nil
end
-- Извлекает значение бита с помощью побитовой операции
local bitValue = ( bit32.band (flags, bit32.lshift ( 1 , bit)) > 0 ) and 1 or 0
return bitValue
end
-----------------
function OnTrade (trade)
-- Если данная сделка еще не записана в файл истории
if not CheckTradeInFile(trade) then
-- Добавляет сделку в файл истории
AddTradeInFile(trade);
end ;
end ;
function OnStop ()
-- Закрывает все файлы
for key,Handle in pairs(TradesFiles) do
if Handle ~ = nil then Handle:close(); end ;
end ;
Run = false ;
end ;
function OnInit ()
Run = true ;
-- Получает полный путь к папке "Данные(c)quikluacsharp.ru"
DataFolder = getWorkingFolder () .. '\\Данные(c)quikluacsharp.ru\\';
-- Создает папки по всем найденным счетам
CreateAccountsFolders();
-- Записывает все ранее не записанные сделки из таблицы "Сделки" в файлы
CheckAndSaveTerminalTrades();
end ;
function main ()
while Run do
sleep ( 1 );
end ;
end ;
Спасибо - простите за глупый вопрос - я создал txt файл - скопировал в него код, а дальше какое ему расширение дать - то есть как пользоваться этим в Квике?
VPM, у нас есть код примерно такой же, он работает. Проблема только в том, что пользователи иногда закрывают табличку или квик, интернет иногда отрубается и вообще... что-то такое происходит, что в итоге мы остаемся без файла загрузки сделок. Вот если бы была история, хотя бы глубиной в один день, то у нас бы такой проблемы не было.
Может стоит рассматривать реальные решения, а то скорость реализации пожеланий тут такая, что можете несколько лет ждать реализации
Цитата
Ирина Никонова написал: Проблема только в том, что пользователи иногда закрывают табличку или квик
Отдельный комп с квиком настроенный на тот же счет что и пользовательский (брокер должен разрешить множественные подключения), за который пользователей не пускать, пускай он и выдергивает сделки
Цитата
Ирина Никонова написал: интернет иногда отрубается и вообще
Если вы не по пол дня без интернета сидите, то при подключении все сделки подтянутся за последнюю торговую сессию. Если дольше, то резервный канал поднимать надо как бы
Цитата
Ирина Никонова написал: что-то такое происходит, что в итоге мы остаемся без файла загрузки сделок
Есть такое слово бэкапы, начните делать пока не поздно
Цитата
Ирина Никонова написал: Вот если бы была история, хотя бы глубиной в один день, то у нас бы такой проблемы не было
Ирина Никонова, Данный скрипт (утилита) сохраняет сделки за торговую сессию, ровно столько сколько хранит их Квик, ТОРГОВЫЙ день "деюро" иное, можно для понимания ознакомиться на сайте биржи. Если квик отключился то и сделок нет. Когда подключаетесь то сохраненные за сессию сделки подтянутся и сохранятся. Все что нужно подключаться в режиме торговой сессии. И тут BlaZed, прав Ваша проблема скрывает два момента технический и программирования. Для решения каждой нужен отдельный специалист.