福利 跨周期的傻瓜式解决方案
TB的跨周期调用,论坛以前已经有一些解决方案。但对很多人来说不够方便 ,本方案主要参考了追涨杀跌的一些基础函数,兼顾了使用方便、运算性能速度、精确,在具体的算法上如 均线ma 标准差std 等不用因为数据源的变化而重新编写算法函数。比如close 的ma myValue 的ma 都可以用一个 iMA函数解决。iMA的形式之所以不用 iMA(iPrice 数据源,TimeFrame 时间周期,Length 算法参数) 而是选择 iMA((iPrice 数据源,mtBarCnt ,Length1);是为了运算速度,否则如果一个策略多次用到跨周期的算法 函数内部会多次重复计算mtBarCnt值 , 会影响运算速度。 本帖最后由 读书山林 于 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 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-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-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 可求任意数据源
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 //------------------------------------------------------------------------
// 简称: 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-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-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
白线就是Mean 自定义的数据源的跨周期值