1、程序化交易ETL 平台简介01013ETL平台提供整套策略分析、设计、测试、评价、优化的交易平台 ETL 平台提供交易策略和系统函数,支持用户函数图形分析界面,多维度的交易模型测试分析报告及参数优化功能支持交易模型导入导出,DLL(无源码)形式导出,移植性好不易破解014ETL语言l ETL是在C+语言的基础上扩展而来,兼容C+的语法l ETL在编译时首先被解析为C+,再被编译为标准的动态链接库(DLL)l ETL主要在如下几方面对C+做了扩展:a.不区分大小写b.设定了参数和变量的定义区域Params、Vars、GlobalVarsc.兼容C+的一些通用关键字和符号,如:or、and、 no
2、t、“+=”d.实现了浮点数的模糊比较e.函数没有参数时可以省略括号f.实现了序列变量015程序化交易开发测试执行账户设置、策略监控持仓矫正、后台交易ETLVisual Studio第三方软件历史回溯、参数优化性能报告、属性设置016交易模式策略交易模式指的是一种虚拟交易模式通过Buy,Sell,SellShort,BuyToCover等策略交易函数进行开仓和平仓通过CurrentContracts等策略状态函数和Available等策略性能函数查看当前策略的持仓和资金状态策略交易订单交易订单交易是直接通过交易通道发送订单的交易方式使用账户函数(A_函数)进行下单、撤单、查询等操作可以精确得知
3、订单的状态,并及时进行撤单、追单等操作017持仓矫正实现不成交订单的自动撤单和自动追单通过设置撤单和追单的相关参数,实现策略仓和账户仓的自动校正实现策略持仓与账户持仓自动同步将处于排队中的订单进行撤单,然后根据仓差情况发送等量的订单追单助手持仓同步发送订单遵循先平仓后开仓的思路 使用持仓同步时,若追单助手功能已经开启,会将追单助手自动关闭,以免追单助手的自动下单影响到持仓同步。018实时触发机制行情变动触发每当合约价格发生变动,就会运行一次公式代码。定时触发用户可以设置定时器,如:指定每秒运行一次代码,或指定11:29:00时刻运行一次代码。当定时器到时,就会自动将代码运行一次。订单状态改变触
4、发一种常见的基于事件的触发机制,每当用户的订单状态发生改变,就会自动执行一次代码。使用函数GetCausation获取策略触发的原因。当触发原因为“订单状态改变”时,可使用函数GetCausationOrder获得触发策略的订单号。019历史回测和实时交易历史回测实时交易Bar数据确定不变实时更新公式运行每根Bar一次每个Tick一次交易信号固定不变有可能变化是否发单否是(受公式机制控制)函数调用部分函数无效有效0110性能报告交易汇总按照全部交易、多头交易和空头交易列出当前交易策略的交易统计信息交易分析对当前策略的交易情况进行分析,包括交易分析、盈亏分析和连续盈亏分析交易记录按开仓平仓对所有
5、交易进行配对组合,并计算盈亏及累计盈亏平仓分析按平仓记录对交易情况进行分析和汇总阶段总结按年、月对交易盈亏及次数进行统计资产变化列出资产的变化记录及统计信息系统参数显示交易策略的参数,设置以及数据等内容每日收益记录交易期间每日权益、保证金、收益率情况图表分析按资产盈亏和交易效率图表两大类共七小类对策略进行图表分析0111交易状态策略只会在触发机制的调用下运行,不会发送订单,也不会报警如果策略发出下单信号,会出现一个报警窗口提示用户策略发出下单信号时,将发送订单至交易通道,用户也可以勾选“下单前进行确认”,则在下单前会弹出对话框询问用户是否下单自动发单状态报警状态静默状态0112策略执行监控所有
6、策略单个策略组合性能 列出了所有策略单个以及组合的资产收益情况,便于用户直观的了解每个策略的性能。持仓监控 列出了所有交易策略在不同账户和不同的合约的持仓情况策略性能 使用户对当前策略的性能有一个粗略的认识,了解策略交易的情况策略持仓 了解当前策略的持仓情况运行日志 当前策略的输出,用户输出及买入、卖出信号0113扩展性支持采用Visual Studio编写策略,生成DLL,便于对策略进行扩展,及使用第三方库(如:Matlab)软件安装目录下VisualStudioSample文件夹,里面有VS编写的相关文档和例子0114安全性策略导入导出模式无源码模式:直接导出应用程序,对方客户端导入后无需
7、编译可直接使用于图表上,不能看到源代码。有源码模式:对方客户端导入后需要通过编译方可使用。无源码,dll格式,安全性高有源码,esl格式,可重复编辑编程入门020216交易指令和函数易盛程序化交易公式包括交易指令和函数交易指令程序化交易的主体,它可以被加载到一个图表。交易指令开始运行后,每当合约价格发生变化,交易指令的代码就会被执行一次函数分为系统函数和用户函数,是指一行或者多行代码集合,它实现了一个相对完整的功能。函数不能被加载到图表中运行,只能在代码中被调用被调用调用系统函数用户函数交易指令允许允许系统函数允许禁止用户函数允许允许0217代码结构参数定义区变量定义区程序主体Params N
8、umeric Length(10); 公式参数段 Vars NumericSeries MA; 局部变量段 GlobalVars NumericSeries MA; 全局变量段 Begin MA = AverageFC(Close, Length); PlotNumeric(“MA”, MA); End0218数据类型名称说明Integer整形Numeric数值型NumericSeries数值序列NumericRef数值引用String字符串StringSeries字符串序列StringRef字符串引用Bool布尔型BoolSeries布尔型序列BoolRef引用NumericArray数组型
9、NumericArrayRef数组型引用0219参数声明参数是一个预先声明的存储空间,用来存放输入参数的值。使用参数可以增强代码的健壮性和可维护性。声明方法如下:Params 参数类型 参数名 1(初值); 参数类型 参数名 2(初值); l 交易指令的参数只支持三种基本类型和整型,函数的参数支持全部的数据类型l 交易指令的参数一定要有初始值,函数的参数可以没有默认值l 当函数被交易指令调用,若交易指令省略了参数,此时交易指令参数的输入值就为函数的默认值l Ref数据类型参数不能设置初始值l 若某个参数没有设置初始值,则定义在该参数前边的参数即使有初始值,该初始值也会被忽略ParamsNume
10、ricRef P1; NumericSeries P2(0); String P3(Hello); Params Numeric P1(3); Numeric P2; Numeric P3(10);Params Numeric P1; Numeric P2; Numeric P3(10); 0220变量声明变量的主要用处在于存放计算或比较的结果,以方便在之后的程序中直接引用运算的值,而无需重现计算过程。变量在使用前必须进行声明,声明方法如下:Vars 变量类型 变量名 1(初值); 变量类型 变量名 2(初值); l 引用类型(NumericRef、StringRef、BoolRef)不能定义
11、为变量,只能定义为参数l 变量赋值时,变量类型和表达式的类型要一致,如:VarsNumericSeries MA; Numeric Stopline(30); 变量名 = 表达式 MA=AverageFC(Close,10);0221序列变量序列变量是程序化交易编程语言与一般编程语言(如:C+)的一个显著差别,是为了简化金融统计运算而设计实现的,如下为序列变量定义的例子:Vars NumericSeries MyNum (0); BoolSeries MyBool (False); StringSeries MyStr ( ); l 序列变量拥有数据回溯的功能,它可以用中括号的方式访问以前K线
12、的数据,如:High表示本周期的最高价,High1就表示上一根K线的最高价。Close代表本周期收盘价或者最新价,Close3就表示3周期前的收盘价。l Close和Close()两个的意思完全不同!l 序列变量是一个长度自动变化的数组,它的长度始终和图表中K线的数量是一致的。0222序列变量与非序列变量Vars Numeric m(0); NumericSeries n(0);Begin If (CO) m=1; If (CO) n=1; PlotNumeric(m=,m); PlotNumeric(n=,n);Endl 序列变量的值具有传导效应非序列变量在条件满足时,显示的是满足条件时的值
13、,在不满足条件时,显示的是为初始值;序列变量在条件满足时,显示的是满足条件的值,在不满足条件时,显示的是上一根K线的值。0223序列变量与数组l 序列变量依赖于图表,数组不依赖图表l 序列变量对于历史周期的数据只能访问,不能修改,而数组可以随意修改以前的数据l 访问当前周期数据时,序列变量可以省略0,而数组必须加上0l 不能将一个数组作为函数的参数传给一个序列变量。如计算数组的均值,不能用Average函数,而应当使用iMA函数计算为方便用户实现对跨周期跨合约历史数据的获取,系统定义了数组类型NumericArray和数组引用类型NumericArrayRef。系统提供了函数HisData函数
14、供调用,它的返回值为一个数组(NumericArray)。数组和序列变量都可以进行历史数据的回溯,但数组与序列变量有着本质的区别:0224数组ParamsVarsNumericArray arr; /注意,数组不能设置初始值BeginArrAdd(arr,3); /添加一个数据,此时arr:3ArrAdd(arr,15.6); /添加一个数据,arr:3, 15.6ArrRevers(arr); /反转数组,arr中的数据15.6, 3arr1=5; /修改一个元素的值,arr中的数据15.6, 5 ArrPrint(arr); /在调试窗口打印数组arr的成员ArrClear(arr); /
15、arr被清空/获取周线的收盘价历史数据arr = HisData(Enum_Data_Close,Enum_Period_Week,1); if(ArrLength(arr)1) /判断是否成功获取到了周线收盘价历史数据 Print(arr0); /打印当前时刻的周线价格 Print(arr1); /打印上周的周线价格End0225全局变量公式内部使用的全局变量l 全局变量需要定义在GlobalVars区域,为方便起见,除了序列变量外,其他变量都可以定义在以Begin开头的程序体内部,序列变量只能定义在GlobalVars或Vars区域中l 全局变量在公式被加载将一直存在,直到公式停止运行。局
16、部变量在每次代码运行结束都会被自动销毁,下次运行代码时会被重新赋予初始值l 只有交易指令才有GlobalVars区域,函数中不能定义GlobalVarsVarsNumeric a(5);Begin a = a+ 5;Print(a);EndGlobalVarsNumeric a(5);Begin a = a+ 5;Print(a);EndVars NumericSeries a(5);Begin a = a+5; Print(a);EndGlobalVars NumericSeries a(5);Begin a = a+ 5;Print(a);End0226全局变量公式之间使用的全局变量l 除
17、了使用GlobalVars关键字定义全局变量外,用户还可以使用系统函数SetGlobalVar和GetGlobalVar存取全局变量。这两个函数定义的全局变量可以实现多个交易指令之间共享数据l 单个公式应用中可提供最多 500 个全局变量,全局变量的索引值从0开始计数到499l 全局变量的默认值为0,它的值不会因为当前Bar的变化而变化,而只能由SetGlobalVar函数来设置l 全局变量值的变化只跟SetGlobalVar的执行顺序有关,因此在图表上进行刷新时,必须考虑因交易指令重新运行导致的全局变量值的变化l 全局变量依附在K线图上,一旦关掉K线图,所有与该图表有关的全局变量将不复存在B
18、eginSetGlobalVar(0,125);EndBeginNumeric P = GetGlobalVar(0);Print(P);End0227全局变量可被存储的全局变量l 使用SetELProfileString函数可以将一个字符串写入到配置文件中保存下来,采用GetELProfileString获得配置文件中的字符串;同理函数SetELProfileString2file和GetELProfileString2file也一样单个公式应用中可提供最多 500 个全局变量,全局变量的索引值从0开始计数到499l 读写文件的效率会远低于SetGlobalVar/GetGlobalVar的
19、效率,避免频繁调用该函SetELProfileStringGetELProfileStringSetELProfileString2fileGetELProfileString2file0228运算l 运算包括算术运算,关系运算,逻辑运算。进行运算时,扩展数据类型和基础数据类型没有任何区别l 数值型变量、字符串变量可以进行算术运算和关系运算,不能进行逻辑运算l 布尔型变量不能进行算术运算和关系运算,只能进行逻辑运算0229运算算术运算数值型变量可以进行加、减、乘、除、求余数、乘方等运算算术运算符 + -,赋值运算符 += -= *=字符串变量 两个字符串可以做相加运算,结果返回一个将两个源串连
20、接在一起的字符串,源串不发生变化 不能写Print (Hello+ World);关系运算= = 5;b = 5 6;Print( a & b); /0Print(a& !b); /0EndVarsBool a(true);Bool b(false);Begina=54;Print( a and CO); /0Print( CO and a); /执行效率没有上一条高Print(b or CO); /1Print(CO or b); /执行效率没有上一条高End0231控制语句条件语句If 语句If - Else 语句If - Else - If 语句If - Else 嵌套循环语句While
21、 循环(避免死循环)For 循环变量 = 初始值 To 结束值For 循环变量 = 初始值 DownTo 结束值If (Condition)ETL公式语句;If (Condition1) ETL公式语句1; Else If(Condition2) ETL公式语句2; Else ETL公式语句3; For 循环变量 = 初始值 To(DownTo) 结束值ETL公式语句;While (Condition)ETL公式语句;0232终止语句Break循环在每次执行后,都将判断Condition的值,当Condition为true时,则执行Break语句,跳出整个循环Continue当Conditio
22、n1为true时,执行循环体,当Condition2为true时,将跳过ETL公式语句2,重新判断Condition1的值,进入下一次循环,否则将继续执行ETL公式语句2While (True)ETL公式语句;If (Condition)Break; While (Condition1)ETL公式语句1;If (Condition2)Continue;ETL公式语句2;Break是跳出整个循环,Continue是跳出当层循环对于For循环,Break和Continue的用法也是类似0233终止语句Vars Numeric i;BeginFor i=0 to 9If( i=2 )Break;El
23、sePrint(i);EndVars Numeric i(0);BeginWhile (i open) Buy(1); If (marketpositon = 1) Sell(1); MarketPosition会在每个策略交易指令发出后立即更新,不管该笔交易是否成交。例如:在同一次策略执行过程中前面有开仓,后面紧接着平仓,判断条件是(MarketPosition = 1),只要前面开仓条件满足后,后面的平仓语句是会执行的。0342策略状态BarSinceEntry If (Markeposition=1 & Sellcondition & BarsSinceEntry=1) Sell();
24、If (Markeposition=0 &Buycondition &BarsSinceExit=1) Buy(); 在历史回测中,无法得知是先满足了开仓条件还是先满足了平仓条件,这样就会造成回测和实盘不一致,所以要避免在同一根K线上即开仓又平仓。0343其他函数PrintCommentary0344其他函数FileAppendBeginFileAppend(D:sample.txt, Date=+DateToString(Date)+ Time= + TimeToString(time) + Close= + Text(Close)+ CurrentBar= + Text(CurrentBa
25、r) + Barstatus=+ Text(BarStatus);End0345绘图函数PlotNumeric0346绘图函数UnPlot0347商品属性最小变动价Numeric MinPoint = MinMove * PriceScale;MinMove最小变动量PriceScale计数精度0348金融统计穿越函数CrossOver上穿CrossUnder下破0349策略交易Buy - 平掉所有空头持仓,开多头仓位sell - 平掉指定多头持仓Sellshort - 平掉所有多头持仓,开空头仓位Buytocover - 平掉指定空头持仓0350账户函数A_SendOrder0351A函数和
26、Q函数l A函数指以A_开头的系统函数,获取自动交易关联帐户的帐户信息l Q函数指以Q_开头的系统函数,主要是获取实时行情信息l Q函数和A函数都是反映最新的实时状态,该类函数若用于历史回测,历史数据可能会取不到或者不准确,所以不适用对历史行情数据进行回溯或调用l A_SendOrder函数每一次执行都会发送一次委托,一般需配合仓位头寸进行条件处理,使用全局变量配合控制委托次数,避免反复开仓。 A函数在不清楚运行机制的情况下慎用。l A函数的例子:系统自带的账户交易示例0352浮动止损SetFloatStopPoint做多模式,做空相反0353跨合约获取行情CloseParamsString
27、Symbol1(ZCE TA 509);String Symbol2(ZCE TA 510);BeginPlotNumeric (Spread, Close(Symbol1) - Close(Symbol2);End0354跨周期获取行情HisDataParamsString Symbol1(ZCE TA 509);VarsNumericArray data;Begindata = HisData(Enum_Data_Close,Enum_Period_Min,15, Symbol1);if( ArrLength(data) 0)Numeric myMA = iMA(data, 5); /5周
28、期均线PlotNumeric(myMA,myMA);End相似函数对比040456Average & AverageFCl Average和AverageFC都是系统函数,目的都是用来求N个Bar以来的平均值,可以直接在编辑器里看到实现的代码。l AverageFC是指FastCalculate,即快速计算。当这两个函数的第二个参数,即N个Bar是常量时,使用AverageFC,提高计算效率。当N是不确定的变量时,则必须使用Average,否则会出现计算问题。l 系统里面类似的用户函数还有Summation和SumamtionFC,Highest 和HighestFC,Lowest和Lowes
29、tFC等。0457序列平均 & 数组平均l 序列变量求平均Average :求平均,同MAXAverage :求指数平均,同EMASMA:求权重移动平均MACD :求指数平滑异同平均WAverage :求权重平均 l 数组求平均iMA :求数组中元素的平均值iEMA :求数组中元素的指数平滑平均值iSMA:求权重移动平均iMACD :求数组中元素的指数平滑平均值 MA = (C1 + C2 + C3 + C4 + C5 + . + Cn) / n EMA = 2 / (N + 1) * C + (N - 1) / (N + 1) * 昨EMA SMA = M / (N + 1) * C + (
30、N + 1 - M) / (N + 1) * 昨SMA MACD = 2 * (DIFF DEA) 其中: DIFF = EMA12 - EMA26; DEA = EMA (DIFF,9); WAverage =(C1 + 2C2 + 3C3 + 4C4 + 5C5 + . + n * Cn) * 2 / (n * (n + 1))0458最高 & 最低l Low :当前合约当前周期的最低价,简写为L;l LowD: N天前(含当天)的最低价;l Lowest:计算指定周期内的数值型序列值的最低值;l LowestFC :快速计算指定周期内的数值型序列值的最低值;同理:有 H , High,H
31、ighD,Highest,HighestFC0459策略资金 & 账户资金策略资金Available :获得策略当前的可用虚拟资金;Margin :获得策略当前占用的持仓保证金。账户资金A_Available :返回当前账户的可用资金;A_Margin :当前账户的持仓保证金;A_Assets :返回当前账户的权益。0460时间函数Time:返回Bar数据的时间,每一个Bar上的Time是确定且唯一的,不随着系统时间的变化而变化;Time在时分秒周期Bar上返回的是Bar结束时间,在日周月年周期返回的是Bar起始时间;历史阶段日线上的Time返回0。CurrentTime:实时阶段返回电脑操作系统的时间。历史阶段返回历史K线Bar的时间,与Time函数一致。若以CurrentTime作为判断条件的公式指令,会有可能导致信号消失,需加以处理以保持信号的稳定性。 注意:同样的关系还有Date和CurrentDate。TradeDate:当前Bar的交易日时间,如果是日间交易结果跟Date是一样的,但是国内品种夜盘返回的TtadeDate会比Date晚一天。ExchangeTime:实时阶段启动交易后返回交易所的时间。否则返回值如下:处于历史阶段时,返回历史K线当前的时间。处于实时阶段时,但是没有启动交易,返回客户端所在操作系统的时间。谢谢观看