📅 财经日历 📊 实时波动 📈 大盘云图 📶 行情走势 🆚 投机情绪 🚀 今日热点

    用DLL来编写TII指标

    2012-12-18 · 6068 阅读
    关于TII指标--趋势强度指数,Overview:
    The trend intensity index (TII), developed by M.H. Pee, is used to indicate the strength of a current trend in the market. It was introduced in the June 2002 issue of TASC.TII determines the current strength of a price trend based on deviations of previous prices from a current moving average.The stronger the current trend, the more likely the market will continue moving in its current direction instead of changing course.According to M.H. Pee, values >80 and <20 indicate strong trends.
    俺现在定义的TII(n)的算法是:
    MA1:= SMA(CLOSE,2*n,1);
    SDP1:= SUM(IF(CLOSE-MA1>0, CLOSE-MA1,0),n);
    SDM1:= SUM(IF(MA1-CLOSE>0, MA1-CLOSE,0),n);
    TII: (SDP1/(SDP1 + SDM1))* 100;
    如何在MT4上编写指标,需要了解MT4编程的一些概念:
    ● 第一个概念就是start(),它是一切程序的入口。
    对于custom indicator–每次start()的调用(程序的进入)发生在:客户端打开的时候;当指标加载到图表的时候;每一个新tick形成的时候。也就是说,你的电脑并没有存储任何与指标相关的数据,你每次开机或重新加载该指标(即调用该程序)的时候,它就会初始化:把已有的历史上所有的柱子(数据)重新算一遍。
    而每次调用start(),系统变量Bars和系统函数IndicatorCounted()就会被赋予新的值。
    ● Bars就是图表里柱子的总数,新tick到来时,只要不形成新的柱子,Bars的值维持不变。
    ● IndicatorCounted(),则返回自上次start()调用后到目前的那些没有变化的柱子的数量,也就是说:第一次调用start() 时,IndicatorCounted()的值为0;经过一次或多次调用后,IndicatorCounted()的值应该为Bars-1,因为最后一根柱子还在变化中;
    新ticks的到来,分两种情况:一是跨周期而又形成新的柱子,此时IndicatorCounted()的值应该为Bars-2,因为起变化的只有最后2根柱子;另一种情况是服务器传递数据不及时,比如断线重连等等,新增加的可能不只一根的柱子。
    一般指标的编程思路:
    ● 首先考虑:初次调用指标--也就是IndicatorCounted()为0的时候,一次性对指标Buffer赋值;
    ● 然后考虑:在新tick到来时,都会判断哪些柱子发生了变化,并据此重算和更新指标Buffer的赋值。指标Buffer其实可看成是系列变量或数组,通常情况下--数组前面的元素的值不变--无需重算,新tick到来时--只需赋值给数组后面增加的元素,对应于新增加的柱子。
    ● 在程序开始部分,我们需要定义指标的属性,以及一些全局变量,包括系列变量的数组和外部参数。
    ● mt4用于绘制的数组有数量限制:最多只能8个数组变量,在初始化init()中--通过IndicatorBuffers(n)和SetIndexBuffer来分配;不用来绘制的数组没什么限制(当然你内存要够), 只是需要通过ArrayResize分配内存后--才能使用。而由几个单值所组成的数组,通常作为中间变量,用于储存和交换--来自子程序或DLL的计算数据,如int inter[3]={0, 0, 0},则不需要再分配内存。
    DLL相关事项:
    ● 调用DLL里面的函数,和调用普通子程序的用法差不多,只是程序的开头,必须引入该DLL(如#import "XXXXXXX.dll")并对被引用的函数做一个声明......
    ● 与DLL相关的指标公式,我编写的习惯:一般都会把需要求值的指标变量(数组)-- 作为参数(函数形参,实际上传递的是一个数组指针)传递给DLL,声明的时候:变量类型后面带有标识符“&”,代码如double&TiiBuffer[];当然,传递给DLL的--通常还有系统提供的Bars和IndicatorCounted(),和行情数据double rates[][6]等等,都作为参数。这样的话,mt4本身的代码很简单,就等DLL函数更新相应的指标变量(数组)就可以了,而有关的算法都在DLL编程里实现。
    ● 需要注意的是:mq4行情数据传递到DLL后,数组顺序完全相反。mq4行情数组原来的顺序是:从Bars-1到0;而传递到DLL后,数组顺序变为0到Bars-1。
    图例:
    我喜欢把不同周期参数(5,7,17,31)的四根TII线放在一起,构成一个附图指标
    附:mt4编程源码
    #property copyright "Copyright 2010, Spark.Ho"
    #property link "http://hi.baidu.com/sparkho"
    //----
    #import "sparkhomt4.dll"
    int GetTII(double rates[][6],int ,int ,int ,double& SmaBuffer[],double& TiiBuffer[]);
    #import
    #property indicator_separate_window
    #property indicator_buffers 4
    #property indicator_color1 Lime
    #property indicator_color2 DarkViolet
    #property indicator_color3 DarkGoldenrod
    #property indicator_color4 Red
    //---- input parameters
    //---- buffers
    double Tii5[];
    double Tii7[];
    double Tii17[];
    double Tii31[];
    //---- 自定义数组,
    double S5[];
    double S7[];
    double S17[];
    double S31[];
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function |
    //+------------------------------------------------------------------+
    int init()
    {
    string short_name;
    //---- indicators
    IndicatorBuffers(4);
    SetIndexStyle(0, DRAW_LINE);
    SetIndexBuffer(0, Tii5);
    SetIndexStyle(1, DRAW_LINE);
    SetIndexBuffer(1, Tii7);
    SetIndexStyle(2, DRAW_LINE,STYLE_SOLID,1);
    SetIndexBuffer(2, Tii17);
    SetIndexStyle(3, DRAW_LINE,STYLE_SOLID,2);
    SetIndexBuffer(3, Tii31);
    //---- name for DataWindow and indicator subwindow label
    short_name="SpTii";
    IndicatorShortName(short_name);
    SetIndexLabel(0,"Tii5");
    SetIndexLabel(1,"Tii7");
    SetIndexLabel(2,"Tii17");
    SetIndexLabel(3,"Tii31");
    //----
    return(0);
    }
    //+------------------------------------------------------------------+
    //| SPTII indicator system with DLL code |
    //+------------------------------------------------------------------+
    int start()
    {
    int counted_bars = IndicatorCounted();
    double rates[][6];
    ArrayResize(S5,Bars);
    ArrayResize(S7,Bars);
    ArrayResize(S17,Bars);
    ArrayResize(S31,Bars);
    //----
    if(Bars < 31)
    return(0);
    ArrayCopyRates(rates);
    GetTII(rates,Bars,counted_bars,5,S5,Tii5);
    GetTII(rates,Bars,counted_bars,7,S7,Tii7);
    GetTII(rates,Bars,counted_bars,17,S17,Tii17);
    GetTII(rates,Bars,counted_bars,31,S31,Tii31);
    //----
    return(0);
    }
    //+------------------------------------------------------------------+
    附:DLL源码
    MT4_EXPFUNC int __stdcall GetTII(const RateInfo* rates,const int rates_total,const int rates_count,const int nPeriod,double *fSMA,double *ar_TII)
    {
    int nP2 = 1;
    double sdp,sdm;
    int i,j;
    if(rates_count == 0) // just the first time to enter the pro
    {
    fSMA[0]=rates[0].close;
    for ( i = 1; i < rates_total; i++ )
    {
    fSMA=(rates.close*nP2 + fSMA[i-1]*(nPeriod*2-nP2))/(nPeriod*2);
    }
    for ( i = nPeriod-1; i < rates_total; i++ )
    {
    sdp = 0.0;
    sdm = 0.0;
    for ( j = 0; j < nPeriod; j++ ) //累加
    {
    if(rates[i-j].close>fSMA[i-j])
    sdp += rates[i-j].close - fSMA[i-j];
    if(rates[i-j].close<fSMA[i-j])
    sdm += fSMA[i-j] - rates[i-j].close;
    }
    ar_TII = 100*sdp/(sdp+sdm);
    }
    }
    else
    {
    for ( i = rates_count-1; i < rates_total; i++ )
    {
    fSMA=(rates.close*nP2 + fSMA[i-1]*(nPeriod*2-nP2))/(nPeriod*2);
    }
    for ( i = rates_count-1; i < rates_total; i++ )
    {
    sdp = 0.0;
    sdm = 0.0;
    for ( j = 0; j < nPeriod; j++ ) //累加
    {
    if(rates[i-j].close>fSMA[i-j])
    sdp += rates[i-j].close - fSMA[i-j];
    if(rates[i-j].close<fSMA[i-j])
    sdm += fSMA[i-j] - rates[i-j].close;
    }
    ar_TII = 100*sdp/(sdp+sdm);
    }
    }
    return(rates_total);
    }
    附注:DLL函数TII元素的赋值,使用了2个循环体,这个代码的目的--是为了更直观的说明2种情况:初次调用指标,和在新tick到来时,指标赋值的不同处理。实际上,完全可以用一个循环体完成上述代码,只需对循环的起点做相应的判断即可......
    ""
    还没有人打赏,支持一下
    回复

    举报

     

    回答|共 12 个

    唯途vip LV4

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    支持你加分  

    kalialy LV5

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    好困啊  

    君君囧小兔 LV5

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    一楼的位置好啊..  

    狡猾仙人 LV5

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    给推荐一个好的平台,这样EA才能很好的发挥啊  

    bylfd LV3

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    不看白不看,看也不白看  

    垃圾 LV8

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    这贴?不回都不行啊  

    0809160528 LV5

    发表于 2012-12-18 20:11:59 | 显示全部楼层

    找个老师学习EA  

    dslapu LV4

    发表于 2014-11-28 05:08:54 | 显示全部楼层

    谢谢分享!!!!!

    mxlacrvd LV2

    发表于 2014-12-5 13:13:05 | 显示全部楼层

    路过。。看下先。
    12下一页
    您需要登录后才可以回帖 登录 | 注册

    提醒: 禁止引战、谩骂、灌水内容

    微信二维码

    有问题联系客服