Скрипт "Хранитель сделок"

1 звезда2 звезды3 звезды4 звезды5 звезд (Голосов 7, среднее: 5,00 из 5)
Загрузка...
Цена: БЕСПЛАТНО
OpenSource: да

img-2015-09-05-00-05-37

Код скрипта
Сохраняет все Ваши сделки в формате CSV (Excel) в реальном времени.
Данный скрипт нужен для работы Индикатора "Мои Сделки"

Скрипт запускается в терминале QUIK обычным способом. Если Вы не знаете как это делается, ознакомьтесь с данной статьей.
После запуска скрипт в главном каталоге терминала QUIK (там, где info.exe) создает(если еще нет) папку "Данные(c)quikluacsharp.ru", а в ней папки для каждого счета, используемого в терминале, как в примере ниже:
img-2015-09-05-02-22-19
Информация о сделках хранится в файлах CSV (Excel), названных именем инструмента. Т.е. если Вы торгуете инструментом "RIU5" и используете для этого счет с идентификатором "1234ABC", то полный путь к файлу истории сделок будет следующим:
"(Папка терминала QUIK)/Данные(c)quikluacsharp.ru/1234ABC/RIU5.csv".

Внутри файла сделки хранятся в виде строк следующего вида:
"Идентификатор счета;Код бумаги;Номер сделки;Дата в формате ГГГГММДД;Время в формате ЧЧММСС;Операция (B -buy/S -sell);Количество лотов;Цена;Текст всплывающей подсказки".
"Текст всплывающей подсказки" нужен для работы Индикатора "Мои Сделки".
Пример:
"SPBFUT00506;RIU5;160936092;20150904;204725;B;1;78380;Счет: SPBFUT00506_Номер: 160936092_Дата: 04/09/2015_Время: 20:47:25_Количество: 1_Цена: 78380"
В тексте всплывающей подсказки отдельные строки отделяются друг от друга символом нижнего подчеркивания ("_").

Благодаря такому простому формату, Вы, при необходимости, можете в ручную редактировать данный файл, как меняя в нем информацию о сделках, так и удаляя какие-то сделки, или добавляя новые (каждая сделка на новой строке). Имейте в виду, что Индикатор "Мои Сделки" соединяет сделки линиями руководствуясь последовательностью сделок в файле.

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

Если у Вас появились вопросы по данному продукту задайте их в комментариях ниже, или на почту reply@quikluacsharp.ru.

Добавить комментарий

Скрипт "Хранитель сделок": 48 комментариев

  1. Вы создали массив указателей на файлы TradesFiles. А в качестве указателя на элементы этого массива подсовываете имя инструмента.
    Такое обращение к массивам нормально? Если я в скрипте разом открою кучу файлов и передам по имени в массив указатели на них, как мне потом по-простому закрыть все эти файлы?

    Я сделал так:

    1
    2
    3
    
     for i=1,#fid do
        io.close(fid[i])
    end

    Но, при заполнении массива, я передавал не номер элемента, а имя инструмента, а при закрытии передаю порядковый номер. Ошибки не возникает, но это корректно?

  2. здравствуйте, Дмитрий. снова я к Вам с переделками скрипта "хранитель сделок". скрипт использую для заполнения журнала в excel. именованный диапазон столбца, в котором сцеплены дата и время, во время обновления выдает ошибку. приходится поправлять координаты диапазона. остальные именованные диапазоны(операция, цена, количество) работают корректно.скорее всего, каким то образом сказывается сцепление столбцов дата и время. если б в столбце" текст подсказки" дата и время уже были сцеплены в формате " ДД.ММ.ГГГГ ч:мм" , то проблем бы с диапазоном (дата_время), наверное ,не было . не могли бы, по возможности, посоветовать какие нужны изменения в коде скрипта. например, в итоге так: "Текст всплывающей подсказки"
    "SPBFUT00506;RIU5;160936092;20150904;204725;B;1;78380;Счет: SPBFUT00506_Номер: 160936092_Дата_Время: 04/09/2015 20:47:25_Количество: 1_Цена: 78380"

    1. Здравствуйте, попробуйте вот эти строки:

      1
      2
      3
      4
      5
      6
      
      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;

      заменить на:

      1
      2
      3
      4
      5
      6
      
      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;
      1. добрый день. к сожалению, после получения измененных данных из файла csv датаивремя имеют текстовый формат, хотя в предыдущих кодах скрипта дата и время имела формат"дата" и "время". все таки нужно вместо " 15/11/2016 18:29:31" сохранять "42689,7705". то есть сохранять порядковый номер, который excel воспринимает как дату. есть ли возможность сделать так?

  3. есть ли возможность поменять название конечного файла для сохранения сделок. в моем случае RIZ6 на, скажем, RIZ6_BAY и RIZ6_SELL. иначе, к сожалению, excel не может одновременно открыть две книги с одинаковыми именами, а у меня ссылки сразу на две. прошу простить за настырность.

    1. Измените строку 40 с:

      1
      
      local PathAccountSec = DataFolder..trade.account..'\\'..trade.sec_code..'.csv';

      на

      1
      
      local PathAccountSec = DataFolder..trade.account..'\\'..trade.sec_code..'_BUY.csv';

      строку 47 с:

      1
      
      local FileIndex = trade.account..'_'..trade.sec_code;

      на

      1
      
      local FileIndex = trade.account..'_'..trade.sec_code..'_BUY';

      строку 138 с:

      1
      
      local PathAccountSec = DataFolder..Trade.Account..'\\'..Trade.Sec_code..'.csv';

      на

      1
      
      local PathAccountSec = DataFolder..Trade.Account..'\\'..Trade.Sec_code..'_BUY.csv';

      строку 139 с:

      1
      
      local FileIndex = Trade.account..'_'..Trade.sec_code;

      на

      1
      
      local FileIndex = Trade.account..'_'..Trade.sec_code..'_BUY';

      То же самое проделайте для SELL в другом скрипте. Напишите что получиться.

      1. не схватывает почемуто. я уже первоночальный код пихал. вообщем. вот ответ квика MyLua\Хранитель сделок6.lua:139: attempt to concatenate field 'sec_code' (a nil value)

  4. СПАСИБО. условия выполняются. поначалу испугало. из истории записались и покупки и продажи, затем как положено бай в bay, селл в sell. теперь с журналом буду договариваться чтобы сам записывал что ему надо и куда надо.

    1. Пожалуйста! Измените еще эту функцию:

      1
      2
      3
      4
      5
      6
      
      -- Добавляет новую сделку в файл истории
      function AddTradeInFile(trade)
         local DateTime = trade.datetime;
         local Date = tonumber(DateTime.year);
         local month = tostring(DateTime.month);
      ...

      добавив в начало тот же механизм:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      
      -- Добавляет новую сделку в файл истории
      function AddTradeInFile(trade)
         if CheckBit(trade.flags, 2) == 1 then 
            -- Сделка SELL
            -- Выход из функции (не запишет в файл)
            return
         else
            -- Сделка BUY
            -- Выход из функции (не запишет в файл)
            --return
         end;
         local DateTime = trade.datetime;
         local Date = tonumber(DateTime.year);
         local month = tostring(DateTime.month);
      ...

      здесь все то же самое с return

      Что-то я забыл по началу, что скрипт еще таблицу сделок проверяет.

  5. добрый день. спасибо за ваши труды. у меня вопросик. как настроить хранитель сделок для записи только бай операций или селл операций? с уважением.

      1. функцию нашел. что дальше делать- не знаю. без подготовки не справлюсь. был бы переключатель в строке. что там за условие дописать? я сам в этом точно не разберусь.

        1. Измените эту функцию:

          1
          2
          3
          4
          5
          6
          7
          
          function OnTrade(trade)
             -- Если данная сделка еще не записана в файл истории
             if not CheckTradeInFile(trade) then        
                -- Добавляет сделку в файл истории
                AddTradeInFile(trade);
             end;
          end;

          вот так:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          
          function OnTrade(trade)
             if CheckBit(trade.flags, 2) == 1 then 
                -- Сделка SELL
                -- Выход из функции (не запишет в файл)
                return
             else
                -- Сделка BUY
                -- Выход из функции (не запишет в файл)
                --return
             end;
             -- Если данная сделка еще не записана в файл истории
             if not CheckTradeInFile(trade) then        
                -- Добавляет сделку в файл истории
                AddTradeInFile(trade);
             end;
          end;

          В данном варианте настройка происходит комментированием операторов return.
          Так закомментирован:

          1
          
          --return

          Так раскомментирован, или не закомментирован:

          1
          
          return

          Суть в том, что то, что написано в виде комментария, не будет выполняться.

          Сейчас скрипт будет писать только BUY-сделки, если закомментировать первый return и раскомментировать второй, то будут писаться только SELL-сделки, если закомментировать оба, то будут писаться все сделки, если раскомментировать оба, то никакие сделки не будут писаться.

            1. Возможно, для этого Вам нужно будет указать разные пути в скриптах в строке 8, например, в одном так:

              1
              
              DataFolder = getWorkingFolder()..'\\Данные(c)quikluacsharp.ru_BUY\\';

              в другом так:

              1
              
              DataFolder = getWorkingFolder()..'\\Данные(c)quikluacsharp.ru_SELL\\';

              только имейте в виду, что индикатор "Мои Сделки" не сможет работать с данными файлами, но думаю Вам это и не нужно.

              1. наверно можно и три скрипта запускать. а при запуске индикатора мои сделки первоночальный скрипт оставить , а два измененных выключить.

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

  6. Здравствуйте, Дмитрий!
    По аналогии приведенной выше, написал код, но не понимаю, почему читаются/считаются только четные строки?
    {LUA]
    function OnInit()
    local f = io.open(getScriptPath().."//set.ini","r+");
    if f ~= nil then --
    local Count = 0;
    for line in f:lines() do
    Count = Count + 1;
    message(f:read("*l"),2)
    end;
    message("Всего строк "..Count,1)
    f:close();
    end
    end;
    [/LUA ]

    содержание файла set.ini
    1 110
    2 120
    3 130
    4 140
    5 150
    6 160
    7 170
    8 180
    9 190
    10 200

      1. Спасибо. получилось, но не понятно, почему message(f:read("*l"),2) отображает только четные строки и счетчик дает только половину строк по количеству?

        1. потому что Вы сначала считываете строку при помощи for line in f:lines() do (что по Вашему делает эта строка?)
          а потом внутри цикла считываете еще одну строку при помощи f:read("*l"), по этому и выводились у Вас в сообщении строки через одну

            1. потому что f:lines() смещает указатель в файле на одну строку, а потом f:read("*l") смещает указатель еще на одну строку, получается, что цикл for за одну итерацию считывает 2 строки, по этому итераций в 2 раза меньше, чем строк

    1. Здравствуйте, Константин! Данная ошибка указывает на то, что скрипт не смог создать папку для счета. Подскажите, у Вас в папке с терминалом данный скрипт создал папку "Данные(c)quikluacsharp.ru" и в ней папки с названиями счетов?

        1. Даже не знаю в чем причина, у меня и на реальном и на демо-счетах все в порядке, а Вы по каким инструментам сделки совершали, возможно у Вас в названии счета, или названии инструмента какие-то символы недопустимые для названия файла, скрипт по их названиям папки и файлы создает, возможно в этом причина, если я буду знать что именно вызывает ошибку, я смогу исправить этот недочет. Можно Вам на email скрипт прислать, который при запуске будет логировать все свои действия, а Вы бы мне прислали на почту этот файл лога?

          1. Скрипт при запуске выдает данную ошибку и далее не работает, так что и лог файл он не создаст. Отправляйте на почту прямо сейчас проверю