读书山林 发表于 2015-5-8 23:29:31

福利 跨周期的傻瓜式解决方案

         TB的跨周期调用,论坛以前已经有一些解决方案。但对很多人来说不够方便 ,本方案主要参考了追涨杀跌的一些基础函数,兼顾了使用方便、运算性能速度、精确,在具体的算法上如 均线ma 标准差std 等不用因为数据源的变化而重新编写算法函数。
      
        比如close 的ma  myValue 的ma 都可以用一个 iMA函数解决。iMA的形式之所以不用  iMA(iPrice 数据源,TimeFrame 时间周期,Length 算法参数) 而是选择  iMA((iPrice 数据源,mtBarCnt ,Length1);是为了运算速度,否则如果一个策略多次用到跨周期的算法 函数内部会多次重复计算mtBarCnt值 ,  会影响运算速度。

读书山林 发表于 2015-5-8 23:31:36

本帖最后由 读书山林 于 2018-3-7 13:10 编辑

此函数是追涨杀跌的MtBar 函数 为了和后面函数包的美观 修改了函数名//------------------------------------------------------------------------
// 简称: iBar
// 名称:
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

Params
        Numeric TimeFrame(1440);   
        // 目标时间周期:月线=40320,周线=10080,日线=1440,4小时线=240
        // 其他1小时内的周期等于相应的分钟数,如:1小时=60, 30分钟=30。。。
        // 支持不规则分钟数,如3分钟,8分钟,之类都行
        
        Numeric BarsBack(1);
        // 目标时间周期BAR偏移:
        // 1--表示将目标时间周期下的前1根K线数据作为与当前Bar对应的目标时间周期下的K线数据
        // 0--表示将目标时间周期下的截止到目前为止的数据转换为与当前BAR对应的目标时间周期下K线数据
        
        NumericRef oCurBar;                 // 目标时间周期下的Bar索引
        NumericRef oOPenHT;         // 目标时间周期下的开盘价
        NumericRef oHighHT;         // 目标时间周期下的最高价
        NumericRef oLowHT;          // 目标时间周期下的最低价
        NumericRef oCloseHT;        // 目标时间周期下的收盘价
        NumericRef oVolHT;          // 目标时间周期下的成交量
        NumericRef oOpenIntHT;      // 目标时间周期下的持仓量

Vars
        NumericSeries barCnt;
        NumericSeries CurBar;
        NumericSeries barCntSum;
        NumericSeries OpenHT;
        NumericSeries HighHT;
        NumericSeries LowHT;
        NumericSeries CloseHT;
        NumericSeries VolHT;
        NumericSeries OpenIntHT;
        Numeric CurTime;
        Numeric PreTime;
        bool condition(false);
        Numeric i;
Begin
        If (TimeFrame == 40320)                 // 月线
        {
                CurTime = Month;
                PreTime = Month;
        }
        Else If (TimeFrame == 10080)                        // 周线
        {
                CurTime = IntPart(DateDiff(19700105,Date)/7);
                PreTime = IntPart(DateDiff(19700105,Date)/7);
        }
        Else                                                                        // 其他时间周期
        {
                CurTime = IntPart((DateDiff(19700105,Truedate(0) )*1440 + Hour*60 + Minute)/TimeFrame);
                PreTime = IntPart((DateDiff(19700105,Truedate(1) )*1440 + Hour*60 + Minute)/TimeFrame);
        }
        condition = CurTime != PreTime;

        If (CurrentBar==0)                // 如果是第一根Bar, CurBar=0
        {
                barCnt = 0;
                CurBar = 0;
                OpenHT = Open;
                HighHT = High;
                LowHT = Low;
                CloseHT = Close;
                VolHT = Vol;
                OpenIntHT = OpenInt;
        }
        Else
        {
                If(Condition)               
                // 如果在目标周期下,属于另一根K线,则CurBar加1
                {
                        barCnt = 1;
                        CurBar = CurBar + 1;
                        OpenHT = Open;
                        HighHT = High;
                        LowHT = Low;
                        VolHT = Vol;
                }Else
                // 如果在目标周期下,属于同一根K线,则CurBar不变,但最高价和最低价要记录价格的变化,成交量要累加
                {
                        barCnt = barCnt + 1;
                        CurBar = CurBar;
                        OpenHT = OpenHT;
                        HighHT = Max(HighHT,High);
                        LowHT = Min(LowHT,Low);
                        VolHT = VolHT + Vol;
                }
                // 收盘价和持仓量总是取最新值
                CloseHT = Close;
                OpenIntHT = OpenInt;
        }
        
        // 上面的程序,在每根小周期的K线上,记录了它所属的大时间周期下的开高低收等值的变化。
        // 接下来,要把在大的时间周期级别上,属于同一根K线的开高低收这些数据,记录在这一组小周期K线的最后一根上。
        barCntSum = barCnt ;
        If(BarsBack == 0)
        // 如果Bar偏移参数为0,则取每根小周期K线上保留的大时间周期截止到这根小周期K线为止的BAR数据
        {
                barCntSum = 0 ;
        }Else If(BarsBack == 1)
        // 如果Bar偏移参数为1,则取大时间周期的上一根K线的BAr数据
        {
                barCntSum = barCnt ;
        }Else
        // 如果BAR偏移参数为其他,则取大时间周期的指定偏移后的那根K线的BAR数据
        {
                For i = 2 To BarsBack
                {
                        barCntSum = barCntSum + barCnt;
                }
        }

        // 最后将相应的K线数据作为引用参数返回
        oCurBar = CurBar;
        oOpenHT = OpenHT;
        oHighHT = HighHT;
        oLowHT = LowHT;
        oCloseHT = CloseHT;
        oVolHT = VolHT;
        oOpenIntHT = OpenIntHT;
        Return barCnt;
End

读书山林 发表于 2015-5-8 23:33:39

iBar 参数太多 调用声明参数太麻烦 以下为简便写法//------------------------------------------------------------------------
// 简称: inBar
// 名称: 读书山林
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------
Params
        Numeric TimeFrame(1440);        // 目标时间周期参数,参数说明参见MtBar
        Numeric BarsBack(1);                // 目标时间周期BAR偏移参数,说明见MtBar函数
Vars
        NumericSeries mtBarCnt;
        Numeric refCurBar;
        Numeric refOpen;
        Numeric refHigh;
        Numeric refLow;
        Numeric refClose;
        Numeric refVol;
        Numeric refOpenInt;
        
        Numeric SumValue(0);
        Numeric i;
        Numeric j(0);
Begin
        mtBarCnt=iBar(TimeFrame,BarsBack,refCurBar,refOpen,refHigh,refLow,refClose,refVol,refOpenInt);

        Return mtBarCnt;
End

读书山林 发表于 2015-5-8 23:36:04

本帖最后由 读书山林 于 2015-5-21 02:19 编辑

跨周期求和函数//------------------------------------------------------------------------
// 简称: iSum
// 名称: 跨周期求和函数 读书山林
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

Params
        NumericSeries iPrice(1);
        NumericSeries BarCnt(0);
        Numeric Length(10);
Vars
        NumericSeries SumValue(0);
        Numeric i;
        Numeric j(0);
Begin
       If(Length==0)
       {
            Return iPrice;           
       }Else
       {
            j=0;
            SumValue = 0;
            For i = 1 to Length
            {
                If (iPrice <> InvalidNumeric)
                {
                        SumValue = SumValue + iPrice;
                        j = j + BarCnt;
                }
                else Break;
            }
       }
        Return SumValue;
End

读书山林 发表于 2015-5-8 23:37:59

本帖最后由 读书山林 于 2015-5-9 00:28 编辑

//------------------------------------------------------------------------
// 简称: iMA
// 名称: 跨周期求均值 读书山林
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------
Params
        NumericSeries iPrice(1); //数据源必须为跨周期的值 否则不能返回正确值
        NumericSeries mtBarCnt(1) ;  
        Numeric Length(10);                           
Vars
        Numeric SumValue(0);
        Numeric i;
        Numeric oMA;      
Begin
        SumValue = iSum(iPrice,mtBarCnt,Length);
        oMA = SumValue/Length;
        Return oMA;
EndiMA  可求任意数据源

读书山林 发表于 2015-5-8 23:41:17

iVariancePS 跨周期求方差   iStandardDev 跨周期求标准差 可求任意数据源//------------------------------------------------------------------------
// 简称: iStandardDev
// 名称: 跨周期求标准差 读书山林
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

Params
        NumericSeries iPrice(1);
        NumericSeries BarCnt(0);               
        Numeric Length(10);
        Numeric DataType(1);
Vars
        Numeric VarPSValue;
Begin
        VarPSValue = iVariancePS(iPrice,BarCnt, Length, DataType);
        If (VarPSValue > 0)
        {
                Return Sqrt(VarPSValue);
        }Else
        {
                Return 0;
        }
End

读书山林 发表于 2015-5-8 23:42:14

//------------------------------------------------------------------------
// 简称: iVariancePS
// 名称: 跨周期求方差 读书山林
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

   
Params
        NumericSeries iPrice(1);//数据源必须为跨周期的值 否则不能返回正确值
        NumericSeries BarCnt(0);       
        Numeric Length(10);
        Numeric DataType(1);
Vars
        Numeric Divisor;
        Numeric SumSqr(0);
        Numeric Mean;       
        Numeric i;
        Numeric j(0);       
Begin
        Mean = iMA(iPrice, BarCnt,Length);
        Divisor = Length-1;
        If(DataType==1)
                Divisor = Length;
        If(Divisor > 0)
        {
                for i = 0 to Length - 1
                {
                        SumSqr = SumSqr + Sqr( iPrice - Mean ) ;
                        j = j + BarCnt;
                }
                Return SumSqr / Divisor ;
        }Else
        {
                Return 0;
        }
End

读书山林 发表于 2015-5-8 23:45:30

本帖最后由 读书山林 于 2015-5-9 00:33 编辑

iPrice0  跨周期数据源转换//------------------------------------------------------------------------
// 简称: iPrice0
// 名称: 跨周期数据源转换 读书山林
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------
Params
        String iPriceType("close");     // 转换的类型,分为High,Low,Open,Close,Vol,OpenInt,BarCnt refCurBar 八种类型
                Numeric TimeFrame(1440);        // 目标时间周期参数,参数说明参见MtBar
                Numeric BarsBack(1);              // 目标时间周期BAR偏移参数,说明见MtBar函数
Vars
        String strTmp1("close");
        NumericSeries mtBarCnt;
        NumericSeries  mtValue ;               
        Numeric refCurBar;
        Numeric refOpen;
        Numeric refHigh;
        Numeric refLow;
        Numeric refClose;
        Numeric refVol;
        Numeric refOpenInt;
        
        Numeric SumValue(0);
        Numeric i;
        Numeric j(0);
Begin

        strTmp1 = Lower(iPriceType);
       
        If ( strTmp1 != "BarCnt" && strTmp1 != "CurBar" &&strTmp1 != "open" && strTmp1 != "high" && strTmp1 != "low" && strTmp1 != "close" && strTmp1 != "vol" && strTmp1 != "openint")
                Return -1;       
               
               
        mtBarCnt=iBar(TimeFrame,BarsBack,refCurBar,refOpen,refHigh,refLow,refClose,refVol,refOpenInt);
        if(strTmp1 =="high")
                {
                                mtValue = refHigh;
                }Else if(strTmp1 =="low")
                {
                                mtValue = refLow;
                }Else if(strTmp1 =="close" )
                {
                                mtValue = refClose;
                }Else if(strTmp1 =="vol")
                {
                                mtValue = refVol;
                }Else if(strTmp1 == "openInt")
                {
                                mtValue = refOpenInt;
                }Else if(strTmp1 =="BarCnt")
                {
                                mtValue = mtBarCnt;
                }Else if(strTmp1 =="CurBar")
                {
                                mtValue = refCurBar;
                }
               
        Return mtValue;
End

读书山林 发表于 2015-5-8 23:47:12

本帖最后由 读书山林 于 2015-5-9 00:09 编辑

使用方法举例//------------------------------------------------------------------------
// 简称: TesiMa
// 名称: 读书山林
// 类别: 公式应用
// 类型: 用户应用
// 输出:
//------------------------------------------------------------------------

Params
        Numeric TimeFrame(30);        // 目标时间周期参数,参数说明参见MtBar
        Numeric BarsBack(1);                // 目标时间周期BAR偏移参数,说明见MtBar函数

        Numeric Length1(10);                // 大周期的短期均线周期               
        Numeric Length2(20);                // 大周期的长期均线周期
        Numeric Length3(10);                // 小周期的短期均线周期
        Numeric Length4(20);                // 小周期的长期均线周期
        Numeric Lots(1);
Vars
        NumericSeries closeX;
        NumericSeries mtBarCnt;               
        NumericSeries MA1;
        NumericSeries MA2;

        NumericSeries MA3;
        NumericSeries MA4;
        NumericSeries Mean;               
Begin
        closeX=iPrice0("Close",TimeFrame,BarsBack);//跨周期的数据源
        mtBarCnt=inBar(TimeFrame,BarsBack);       // 跨周期的inBar
        //只要得知了以上两个数据就可以求任意算法的 跨周期值
               
        MA1 = iMA(closeX,mtBarCnt,Length1);
        PlotNumeric("MA1",MA1);

        MA2 = iMA(closeX,mtBarCnt,Length2);
        PlotNumeric("MA2",MA2);
               
        //可以把任意正确的数据源带入算法函数,不用因为数据源的变化 重新写算法函数
        Mean = iMA(MA1,mtBarCnt,Length2);// 以跨周期均线ma1为数据源的移动平均
        PlotNumeric("Mean",Mean);               
               
        MA3 = AverageFC(Close,Length3);
        MA4 = AverageFC(Close,Length4);
        PlotNumeric("MA3",MA3);
        PlotNumeric("MA4",MA4);
        
        
        If (MA1>MA2)                // 大周期均线金叉,多头趋势
        {
                if (MarketPosition!=1 and MA3>MA4)
                {
                        Buy(Lots,Open);
                }
                if (MarketPosition==1 and MA3<MA4)
                {
                        Sell(Lots,Open);
                }
        }
        If (MA1<MA2)                // 大周期均线死叉,空头趋势
        {
                if (MarketPosition!=-1 and MA3<MA4)
                {
                        SellShort(Lots,Open);
                }
                if (MarketPosition==-1 and MA3>MA4)
                {
                        BuyToCover(Lots,Open);
                }
        }
End

读书山林 发表于 2015-5-8 23:52:50



白线就是Mean  自定义的数据源的跨周期值
页: [1] 2 3 4 5 6
查看完整版本: 福利 跨周期的傻瓜式解决方案