Пара-тройка бантиков QPILE + M4

Опубликовано в M4

Обычно в свои тесты на qpile я вставляю сигнатурку, которая выводится в лог-файл при каждом старте робота. Выглядит это таким образом:


write_log("Версия 15.03.11  Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.     www.bot4sale.ru")

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

Поскольку при написании программ на QPILE я активно использую препроцессор M4, разумно попробовать переложить эту функцию на него, пусть трактор трудится Подмигиваю. В препроцессоре имеется возможность запускать внешние программы и принимать от них стандартный вывод. Нам нужна команда date с ключом /T. Вот как выглядит макрос: 

define(Signature,`"substr(esyscmd(date /T),0,8) Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript. www.bot4sale.ru $*"')

Таким образом, в момент сборки робота препроцессор запустит командный интерпретатор Windows, отправит ему команду date /T, получит строку с системной датой и вставит ее в строку. Здесь использован встроенный макрос препроцессора substr, созвучный стандартной функции интерпретатора qpile. В результате из текста

write_log(signature)

после обработки препроцессором сегодня (05.08.2012) получится QPILE текст

write_log("Версия 05.08.12      Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript.     www.bot4sale.ru")

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

 Можно просто написать макросы __date__ и __time__ , которые существуют в UNIX-реализациях препроцессора M4, но отсутствуют в m4 для Windows:

define(`__date__',`substr(esyscmd(date /T),0,8)')
define(`__time__',`substr(esyscmd(time /T),0,5)')

 

Еще один бантик. Этот для создания таблицы OWN в QPILE.

define(`Own',`ifelse($#,0,`err'print(`Error '__file__`('__line__`): Missing parameter(s)
'),
`PARAMETER ifelse($1,,Param,$1);
PARAMETER_TITLE ifelse($2,,ifelse($1,,Param,$1),$2);
PARAMETER_DESCRIPTION ifelse($3,,ifelse($2,,ifelse($1,,Param,$1),$2),$3);
PARAMETER_TYPE ifelse($4,,STRING(8),translit($4, `a-z', `A-Z'));
END')'
)

Теперь исходный текст

 

Own(SECCODE,Код бумаги)
Own(CLASSCODE,Код класса)
Own(POSITION,Состояние,,STRING(12))
Own(Direction,Направление)
Own(STEPS,Объем,,NUMERIC(2,0))
Own(CYCLES,Переворотов,,NUMERIC(3,0))
Own(TIMEFRAME)

будет автоматически развёрнут в

PARAMETER SECCODE;
PARAMETER_TITLE Код бумаги;
PARAMETER_DESCRIPTION Код бумаги;
PARAMETER_TYPE STRING(8);
END
PARAMETER CLASSCODE;
PARAMETER_TITLE Код класса;
PARAMETER_DESCRIPTION Код класса;
PARAMETER_TYPE STRING(8);
END
PARAMETER POSITION;
PARAMETER_TITLE Состояние;
PARAMETER_DESCRIPTION Состояние;
PARAMETER_TYPE STRING(12);
END
PARAMETER Direction;
PARAMETER_TITLE Направление;
PARAMETER_DESCRIPTION Направление;
PARAMETER_TYPE STRING(8);
END
PARAMETER STEPS;
PARAMETER_TITLE Объем;
PARAMETER_DESCRIPTION Объем;
PARAMETER_TYPE NUMERIC(2,0);
END
PARAMETER CYCLES;
PARAMETER_TITLE Переворотов;
PARAMETER_DESCRIPTION Переворотов;
PARAMETER_TYPE NUMERIC(3,0);
END
PARAMETER TIMEFRAME;
PARAMETER_TITLE TIMEFRAME;
PARAMETER_DESCRIPTION TIMEFRAME;
PARAMETER_TYPE STRING(8);
END

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

 


Сможете сказать сходу, сколько секунд в 4 часах, чтобы задать этот таймфрейм в QPILE? Или сколько 5-минутных свечей в торговой неделе? Можно взять калькулятор. Можно написать выражение 4*60*60 и QPILE посчитает это число сам. Правда делать он это будет на каждой итерации, уменьшая и без того невысокую скорость выполнения скриптов. А можно прямо в тексте написать инструкцию препроцессора eval(4*60*60) и он еще на этапе сборки (до запуска портфеля) заменит весь этот фрагмент на 14400.

 


Что делать, если нужно задать шестнадцатиричную константу? Или двоичную? QPILE умеет работать только с десятичными константами. Ответ все тот же - использовать препроцессор. Он позволяет восполнить этот пробел в QPILE. M4 умеет работать с числами в системах счисления от 2 до 36. Числа без специального префикса являются десятичными. Простой префикс 0 указывает на то, что число восьмеричное. 0x указывает шестнадцатеричное число. 0b указывает двоичное число. 0r указывает число имеющего основание системы счисления от 1 до 36

Примеры:

  • eval(0b1100110011) = 819
  • eval(014) = 12
  • eval(0xFF) = 255
  • eval(0b1100 & 0b1010) = 8   или 0b1000

Про чтение чисел в разных системах счисления в процессе исполнения на QPILE: Hex: чтение 16-ричных чисел

Недостаточно прав для комментирования

Библиотека