Препроцессор и AmiSharp

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

 

С целью экономии объёмов набиваемого текста при написании скриптов AFL под Amisharp я использую препроцессор M4.

Самое простое. При вызове каждого метода AmiSharp приходится сначала указывать имя объекта. Чтобы перестать об этом думать, в файл макроопределений, включаемым в каждый модуль, можно поместить следующие макросы:

dnl ======================= AmiSharp support =================
dnl Ширина и высота таблиц
define(`GetHeight',`StrToNum(m4_amisharp.`GetHeight'(`$*'))') dnl Высота таблицы
define(`GetWidth',`StrToNum(m4_amisharp.`GetWidth'(`$*'))') dnl Ширина таблицы

dnl Получение строк из таблицы AmiSharp
define(`GetCell',`m4_amisharp.`GetCell'(`$*')')
define(`GetCellName',`m4_amisharp.`GetCellName'(`$*')')

dnl Таблицы
define(`IsTableExists',`m4_amisharp.`IsTableExists'(`$*')')
define(`DeleteTable',`m4_amisharp.`DeleteTable'(`$*')')
define(`LoadTable',`m4_amisharp.`LoadTable'(`$*')')
define(`CreateTable',`m4_amisharp.`CreateTable'(`$*')')
define(`SaveTable',`m4_amisharp.`SaveTable'(`$*')')

dnl Удаление строки
define(`DeleteRow',`m4_amisharp.`DeleteRow'(`$*')')

dnl Получение чисел из таблицы AmiSharp
define(`GetCellNumber',`StrToDouble(GetCell(`$*'))')
define(`GetCellNameNumber',`StrToNum(NormalizeNumber(GetCellName(`$*')))')

dnl Поиск
define(`SearchValue',`StrToNum(m4_amisharp.`SearchValue'(`$*'))')
define(`SearchValueName',`StrToNum(m4_amisharp.`SearchValueName'(`$*'))')

dnl Фильтры
define(`ApplyFilter',`m4_amisharp.`ApplyFilter'(`$*')')
define(`ApplyFilterName',`m4_amisharp.`ApplyFlterName'(`$*')')

dnl Trans2QUIKdll
define(`QuikIsDLLConnected',`m4_amisharp.`QuikIsDLLConnected'(`$*')')
define(`QuikIsConnected',`m4_amisharp.`QuikIsConnected'(`$*')')
define(`QuikConnect',`m4_amisharp.`QuikConnect'(`$*')')

dnl Процессы
define(`StartProcess',`m4_amisharp.`StartProcess'(`$*')')
define(`IsWindowExists',`m4_amisharp.`IsWindowExists'(`$*')')
define(`SendKeysByTitle',`m4_amisharp.`SendKeysByTitle'(`$*')')
define(`IsProcessStarted',`m4_amisharp.`IsProcessStarted'(`$*')')

dnl Ошибки
define(`GetError',`m4_amisharp.`GetError'(`$*')')
define(`GetErrorName',`m4_amisharp.`GetErrorName'(`$*')')

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

dnl ================= Optional parameters for library functions ==========================
define(`StaticVarInc', ``$0'(`$1',m4_default(`$2',1))')
define(`Plot_Real_Trades', ``$0'(m4_default(`$1',m4_result_table),m4_default(`$2',"Сигнал"),m4_default(`$3',"Время"),m4_default(`$4',"Цена"),m4_default(`$5',m4_ColorBuy),m4_default(`$6',m4_ColorSell),m4_default(`$7',m4_real_position_level_style))')
define(`Get_Real_Status', ``$0'(m4_default(`$1',m4_result_table),m4_default(`$2',"Статус"))')
define(`Initialize', ``$0'(m4_default(`$1',m4_quik_path),m4_default(`$2',m4_quik_login),m4_default(`$3',m4_quik_password))')
define(`Write_Log', ``$0'(`$1',m4_default(`$2',m4_log_file))')
define(`InitUserTable', ``$0'(`$1',m4_default(`$2',m4_result_table),m4_default(`$3',m4_result_file))')
define(`ExistsInTTP', ``$0'(m4_default(`$1',m4_dde_ttp),m4_default(`$2',m4_classcode),m4_default(`$3',m4_seccode))')
define(`GetParameter', ``$0'(`$1',m4_default(`$2',m4_dde_ttp),m4_default(`$3',m4_classcode),m4_default(`$4',m4_seccode),m4_default(`$5',"m4_dde_ttp_classcode"),m4_default(`$6',"m4_dde_ttp_seccode"))')
define(`GetClassCode', ``$0'(m4_default(`$1',m4_dde_ttp),m4_default(`$2',m4_seccode),m4_default(`$3',"m4_dde_ttp_seccode"),m4_default(`$4',"m4_dde_ttp_classcode"))')
define(`MaxPrice', ``$0'(m4_default(`$1',m4_dde_ttp),m4_default(`$2',m4_classcode),m4_default(`$3',m4_seccode))')
define(`MinPrice', ``$0'(m4_default(`$1',m4_dde_ttp),m4_default(`$2',m4_classcode),m4_default(`$3',m4_seccode))')
define(`GetAveragePrice', ``$0'(m4_default(`$1',m4_result_table),m4_default(`$2',m4_dde_trades_price),m4_default(`$3',m4_dde_trades_value))')
define(`WriteTable', ``$0'(m4_default(`$1',m4_result_table),m4_default(`$2',m4_result_file))')
define(`SumColumnName', ``$0'(m4_default(`$1',m4_dde_trades),m4_default(`$2',m4_dde_trades_qty))')
define(`StartDDE', ``$0'(m4_default(`$1',m4_quik_path))')
define(`Send_Transaction', ``$0'(`$1',`$2',`$3',m4_default(`$4',m4_classcode),m4_default(`$5',m4_seccode),m4_default(`$6',m4_account),m4_default(`$7',m4_clientcode),m4_default(`$8',m4_dde_ttp))')
define(`Menu_Button', ``$0'(`$1',`$2',`$3',`$4',`$5',m4_default(`$6',colorBlack),m4_default(`$7',colorBlack),m4_default(`$8',colorWhite),m4_default(`$9',"Arial"),m4_default(`$10',12),m4_default(`$11',1))')
define(`Initialize', ``$0'(m4_default(`$1',m4_quik_path),m4_default(`$2',m4_quik_login),m4_default(`$3',m4_quik_password))')
define(`Enter_Buy', ``$0'(m4_default(`$1',m4_longsize),m4_default(`$2',0))')
define(`Enter_Short', ``$0'(m4_default(`$1',m4_shortsize),m4_default(`$2',0))')
ifndef(`DefaultMarketTimeZoneOffset',`define(`DefaultMarketTimeZoneOffset',eval(-4*60*60))') dnl Поясное время биржи в секундах
define(`tzNow', ``$0'(m4_default(`$1',0),m4_default(`$2',DefaultMarketTimeZoneOffset))')

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

 

dnl Вывод графика цены
dnl Plot_Price("Название секции",Color,Style)
define(`Plot_Price',`
{ m4_ifval(`$1',`_section_begin(`$1');')
SetChartOptions(0,chartShowArrows|chartShowDates);
Plot(Close, "", m4_default(`$2',ParamColor("Цвет цены", colorBlack )),m4_default(`$3',ParamStyle("Стиль цены",GetPriceStyle(),styleBar|styleCandle|styleLine|styleThick|styleNoTitle)));
m4_ifval(`$1',`_section_end();')
}')

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

Функция ParamOptimize тоже прекрасно выглядит в виде макроса:

dnl Объявление оптимизируемого параметра
define(`ParamOptimize',`Optimize(`$1',Param(`$1',`$2',`$3',`$4', m4_default(`$5',1) ),`$3',`$4',m4_default(`$5',1))')

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

dnl Расчет и отрисовка фракталов
dnl Plot_Fractal("Имя секции",def,min,max,color)
define(`Plot_Fractals',`
{ m4_ifval(`$1',`_section_begin(`$1');')
m4_FractalPeriod = Param("Период фракталов",m4_default(`$2',5),m4_default(`$3',3),m4_default(`$4',25),2);
m4_HighFractal = HHV(Ref(High,int(m4_FractalPeriod/2)),m4_FractalPeriod) == High;
m4_LowFractal = LLV(Ref(Low,int(m4_FractalPeriod/2)),m4_FractalPeriod) == Low;

Local lFractalColor;
lFractalColor = ParamColor("Цвет фракталов",m4_default(`$5',colorBlue));
m4_ifval(`$5',
PlotShapes(IIf(m4_HighFractal,shapeSmallDownTriangle,shapeNone),lFractalColor,0,High);
PlotShapes(IIf(m4_LowFractal,shapeSmallUpTriangle,shapeNone),lFractalColor,0,Low);
)
m4_ifval(`$1',`_section_end();')
}')

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

Таким образом, получается использование сразу двух препроцессоров последовательно. Первый - M4 на этапе сборки, второй (встроенный) на этапе выполнения скрипта - при его первичной трансляции в байт-код.

 

 

Комментарии   

# Zoringer 03.12.2015 22:02
А как это использовать? Можно подробнее?
Ответить | Ответить с цитатой | Цитировать
# admin 03.12.2015 22:10
Цитирую Zoringer:
А как это использовать? Можно подробнее?


Добрый день. Если выписали на с++, то знаете функции препроцессора, который там есть.
М4 - это тоже препроцессор, но гораздо более мощный.

Я использую его в основном для расширения возможностей языка и для сборки скриптов из модулей.
Ответить | Ответить с цитатой | Цитировать
# Zoringer 13.01.2017 19:38
Понял спасибо!
Ответить | Ответить с цитатой | Цитировать

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


Защитный код
Обновить