{转}tbl语言简介

TB里面代码执行
1,代码从第一根K线开始执行,一直到最后一根K线;
2,在每一根K线上,代码都是从第一行开始执行,一直到最后一行;
我们就写个输出每日的收盘价的例子;
打开TB,在左边的TB公式里面,点击新建技术指标,
然后在出来的公式编辑器里面输入
Begin
End
注意,除了参数和变量定义外,所有的代码都必须包含在Begin和End之间

我们再在Begin和End之间输入一些代码,完整的就是:
Begin
  FileAppend("c:\\a.log",Text(Year)+"年"+Text(Month)+"月"+Text(Day)+"日的收盘价等于");
  FileAppend("C:\\a.log",Text(Close));
End
我们再说说这两行代码是什么意思
File就是文件,Append就是添加,现在明白了吧
FileAppend就是添加一个文件,文件名是什么呢?就是你后面写的a.log,这个文件的路径在哪里呢?就是c:\\a.log里面的C盘,且在这个文件里面添加一行东西,
这行东西的内容就是你后面所写的Text(Year)+"年"+Text(Month)+"月"+Text(Day)+"日的收盘价等于"
当然,如果这个文件已经存在,他就不会添加文件了,仅仅在这个文件的后面添加一行上面你写的内容
好了,再看看Text,Text的意思就是把那些不是字符串的东西如数字啊,等变成字符串.而Year,Month,Day就代表了
正在执行你写的代码的那一根K线的年,月,日,年月日是数字,我们当然要用Text把它搞成字符串
CloseK线的收盘价啊,如果代码执行到最后的那根K线

我们点公式编辑器上面的工具栏的第五个按钮(打勾的那个东西),校验保存公式,稍微等一下,就OK了
我们在回到K线图里面,TB把K线图叫做超级图表
在K线图里面右键,选择商品设置,然后吧里面的样本数由默认的300改成5,意思是让在超级图表里面仅仅显示5条K线,点确定后,你就看到在K线图里面只显示了5跟K线,
当然现在代码还不能被执行,因为我们现在还需要把我们刚刚所写的那个指标加到K线图上面才能被执行的
我们上面说了,我们这个例子仅仅是把每日的收盘价写到文件里面去啊,那么我们找一找文件在什么地方咯?
FileAppend("c:\\a.log",很明显,文件是在c盘的,文件的名字是a.log
好了,我们到c盘找到a.log文件,双击打开,我们就会看到下面的内容:

2007年9月24日的收盘价等于
67280
2007年9月25日的收盘价等于
67800
2007年9月26日的收盘价等于
67160
2007年9月27日的收盘价等于
67300
2007年9月28日的收盘价等于
68020


我们现在来分析下:


首先你写的代码在第一根K线上执行,先执行第一行代码:
FileAppend("c:\\a.log",Text(Year)+"年"+Text(Month)+"月"+Text(Day)+"日的收盘价等于");
这行代码就输出了第一根K线的年,月,日,就在a.log文件里输出成"2007年9月24日的收盘价等于"
然后执行第二行代码:
FileAppend("C:\\a.log",Text(Close));
折行代码把第一根K线的收盘价输出到a.log文件里面,于是就输出了"67280"
好了,代码在第一根K线上执行完毕,于是再转到第二根K线,再执行第一行代码,再执行第二行代码
.........

我一直非常愿意帮助客户们解答在编程中的难点,但是却不大愿意帮助客户写完整的公式策略。这其中有三个原因:
1、别人写的交易策略,你难以调整它。
据统计,90%以上的交易策略会在2年半之内由于种种原因失效或者效率降低。通常的做法是一个季度左右,交易员就需要微调其策略,调整参数或改动某些条件。如果策略不是自己编写的,调整起来就会有困难。

2、别人写的交易策略,你很难彻底执行它。
系统交易最重要的好处在于它的执行能力。它可以使你的交易摆脱人性的弱点,摆脱心理因素的干扰。然而这一切的基础,在于自信。人只会信任自己了解的东西,这是人性。如果一个交易策略是别人写的,无论它的测试报告是多么天花乱坠,你都不会信任它,因为你不了解它。一旦市场出现了危机情况,你就会坐立不安,你就会总怀疑是不是策略有问题,然后就又把策略扔到一边,回到凭感觉去操作的老路上去了。
3、最重要的一点在于:编程就是理解,编写交易策略调试交易策略的过程其实就是理解市场的过程。这是一种非常宝贵的积累。大多数人都是通过在市场中亏钱,靠爆仓来理解市场的。成本高昂,而且难以总结。使用这种方法来了解市场,往往就算你亏了很多钱,交了大把学费,你仍然不知道自己到底输在哪里。你总结不出来,你就不可能有长进,就不可能赢。而通过写交易策略来了解市场你不需要交什么学费,从历史测试报告里很容易分析出来自己到底错在哪里,如此你就很容易改进。把编好的交易策略与模拟帐户交易结合起来就可以为你带来足够逼真的实战经验。
编程其实是一种思想,编程的目的是把你的思想用各种图形表现出来而已
我们期货编程的目的是表现我们的交易思想
是为思想而编程,不是为编程而编程!

现在开始写数据类型,变量和赋值.


数据类型
分字符串类型,数值型,还有布尔型

字符串类型很简单,用分号"   "括起来的东西就叫做字符串类型的数据,如"I love you",如"3345",.....
数值型数据类型也同样的简单,数值大家知道吧,如1542啊,1.021啊....这些东西就是数值型的数据类型
当然,如果把一个数值型的东西用分号""括起来了那他就不再是数值型数据了,而是字符串类型的数据
如1688是数值型数据,但是"1688"就是字符串类型的数据了
还有就是布尔型,当然,没有接触过编程的朋友可能不明白布尔型的意思
说白点,布尔型就是真假型,意思就是布尔类型的数据只能取真(True)或假(False)值.
比如2>1,这个东西就是布尔类型的数据,因为2是大于1啊,所以这个表达式返回True(真)
那么2<1,大家说这个表达式是不是个布尔类型的数据呢?
也是,因为2大于1啊,所以2<1是错误的,就返回False(假)
大家明白了吧,就这三个类型,其中最只要的就是数值型数据类型
用的最多的也是数值型数据类型
如果明白了,那么请您就记住在TB里面数值型 Numeric
看下TB的帮助,数据类型里面还有个序列型,如果数值序列型,字符串序列型,布尔序列型
序列这个东西看起来很难理解
比如我们的K线图上有10跟K线,Close就是收盘价
但是这个Close包含了第一根K线的收盘价,也包含了第二根K线的收盘价.......一直包含到第五根K线的收盘价
也就是说序列型的数据在每根K线上都有一个值的


说说变量
变量就是一个可以改变的东西
现在这个变量的值是100,但是等下我可以把它改成20, 只要您喜欢,你可以随心所欲的改变这个值
能够修改他的值的东西就叫做变量了
记住:
在TB里面变量都是要先定义的!而且有着他独到的定义方法,而且这个定义必须放到Begin的前面
如我们定义一个数值型变量a.就应该这样
Vars
  Numeric a;
Begin
......
End
当然你也可以定义两个或者多个变量,如
Vars
  Numeric a;
  Numeric b;
  //.........更多变量定义
Begin
......
End

大家也许想到了
我定义这个变量a,我要让他等于2,这个东西很简单
你可以在变量定义的时候就给他赋初值让他一开始被定义就等于2,也可以在Begin下面写.如
Vars
  Numeric a(2);
  Numeric b;
  //.........更多变量定义
Begin
......
End
明白了么|?那么变量b呢?我们没有用括号()扩个东西啊,那么这个时候b这个变量等于什么呢?
很简单,如果你在定义变量的时候没有给他初值,那么b这个时候等于0
再看在Begin里面怎么修改这个变量的值
Vars
  Numeric a(2);
  Numeric b;
  //.........更多变量定义
Begin
  a = 3;
  b = 100;
End
很简单的
现在大家应该知道了变量是什么东西了吧
对了,忘记告诉大家了,在Begin下面给变量复制仅仅只对当前正在执行你的代码的K线有效,到下一根K线他就是初始值了啊
写个例子吧
Vars
  Numeric a(100);//定义一个变量,类型是数值类型,变量名字是a,变量的初始值是100
Begin
  if(CurrentBar == 0)//如果是第一根K线,就把变量a的值变为1
  {
      a = 1;
   }
  FileAppend("C:\\a.Log",Text(a));
End

我们再来看看输出结果:
1
100
100
100
100
我们再来理解下这个结果(当然这个时候我们的K线图上面只有5跟K线啊,其实随便多少跟K线都一样)
首先代码在第一根K线上面执行,先执行if(CurrentBar == 0)这个东西,CurrentBar代表正在被执行的K线的索引
因为代码现在在第一根K线上执行,所以索引就是0拉,于是这个表达式就成立了啊,既然if(CurrentBar == 0)这个表达式
成立,那么他就会执行{}里面的东西a = 1;把1赋给变量a,也就是说吧变量a的内容改成1,
然后执行FileAppend("C:\\a.Log",Text(a));
这个时候变量a的值是1,所以当然输出1了啊
代码执行完毕
然后转到第二根K线,
既然是第二根K线,那么这根K线的索引就是1了啊,1肯定不等于0啊
那么表达式if(CurrentBar == 0)就不成立了啊,既然不成立那么他也就不会执行{}里面的东西 a = 1;
于是就直接执行FileAppend("C:\\a.Log",Text(a));
那么这个时候a的值是多少呢?
很明显是100,就是他的初始值,而不是上一根K线执行代码的时候改变了的a的值!这点千万注意啊

变量赋值
其实我们上面已经说了,记住=和==的区别
=就是把=右边的东西赋给=左边的东西
如a = 100;
就是把=右边的100赋给左边的变量a
如b = 9;
就是把9赋给变量b
等于的符号是==
if(a==b)//就是如果a等于b
{
   //做某件事情
}


再看在Begin里面怎么修改这个变量的值
Vars
  Numeric a(2);
  Numeric b;
  //.........更多变量定义
Begin
  a = 3;
  b = 100;
End

现在我们说说TB中的流程控制
流程控制就是控制代码执行的流程
还说的明白点就是如果满足什么条件就做什么事情
或者不满足什么条件的时候做什么事情
简单说流程控制就是控制语句控制代码
控制语句中分为逻辑控制语句(就是条件控制语句)和循环控制语句
条件控制语句中大家记住If这个关键字,翻译成中文就是如果
循环控制语句中大家记住For,就是开始循环了

先说If.
假设一个这样的条件:
如果(收盘价>开盘价)
  则输出:今日收红阳线
我们先把这个东西翻译成TB
如果翻译成If
收盘价和开盘价大家都知道会翻译成Close和Open
输出语句就是FileAppend,则翻译成TB就是:
If(Close>Open)
  {
     FileAppend("c:\\a.log","今日收红阳线");
  }
是不是很简单呢?
大家记住一点,凡是if(如果)语句中的代码,都给我用{}括起来
我们再把上面的条件加上一点:
如果(收盘价>开盘价)
  则输出:今日收红阳线
否则如果(收盘价==开盘价)
  则输出:今日收十字线
我们再翻译成TB,把否则翻译成Else,如果翻译成If
If(Close>Open)
  {
     FileAppend("c:\\a.log","今日收红阳线");
  }
Else If(Close==Open)
  {
     FileAppend("C:\\a.log","今日收十字线");
  }
同样的简单,我们可以再把上面的条件再加:
如果(收盘价>开盘价)
  则输出:今日收红阳线
否则如果(收盘价==开盘价)
  则输出:今日收十字线
否则
则输出:今日收绿阴线

上面的否则大家知道翻译成Else吧,有两种翻译方法,因为收盘价和开盘价的比较只存在着三种情况:
收盘价大于开盘价,收盘价等于开盘价,收盘价少于开盘价,我们先这样翻译:
If(Close>Open)
  {
     FileAppend("c:\\a.log","今日收红阳线");
  }
Else If(Close==Open)
  {
     FileAppend("C:\\a.log","今日收十字线");
  }
Else If(Close<Open)
  {
     FileAppend("c:\\a.log","今日收绿阴线");
  }
上面的这个语句是很好理解的
但是大家想到了吗?开盘价和收盘价的比较,如果不满足Close>Open,也不满足Close==Open
那么肯定的一点就是:Close<Open,所以上面的语句可以写成:
If(Close>Open)
  {
     FileAppend("c:\\a.log","今日收红阳线");
  }
Else If(Close==Open)
  {
     FileAppend("C:\\a.log","今日收十字线");
  }
Else
  {
     FileAppend("c:\\a.log","今日收绿阴线");
  }


再说For循环语句.
先记下For语句的语法格式:
For 循环变量 = 初始值 To 结束值
{
    TradeBlazer公式语句;
}
也就是(假如变量i已经定义,且循环5次)
For i = 0 To 4
{
    TradeBlazer公式语句;
}

for语句的理解稍微复杂点,我们先看看For语句是如何执行的:
比如上面的例子
首先执行i=0,就是给变量i赋值让i等于0,然后判断i是不是少于等于4,这里i等于0,所以小于4,于是执行{}里面的TradeBlazer公式语句;
执行{}里面的TradeBlazer公式语句后,TB系统会自动给变量i加1,这个时候i就等于1了(上面刚刚开始的时候i等于0,加了1就是等于1了)
再判断i是不是少于等于To后面的4,1当然少于4,于是再执行{}里面的TradeBlazer公式语句;
执行完{}里面的TradeBlazer公式语句后,Tb系统又自动给变量i加1,上面i已经等于1了,加1,于是这个时候i等于2了,
于是再判断变量i的值2是不是少于To后面的4,当然少于拉,于是再执行{}里面的TradeBlazer公式语句;
....
以此执行,当i等于5的时候,再与To后面的4进行比较,当然5>4了,所以不满足条件了,于是不再执行{}里面的TradeBlazer公式语句;
而开始执行{}下面的语句拉
大家再研究下下面的HHV的写法,就会很明白了的:
//------------------------------------------------------------------------
// 简称: HHV
// 名称: 求N周期的最高值
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

Params

 

Numeric Length(5);

Vars

Numeric highestValue(0);

Numeric minDay;

Numeric i;

Begin

minDay = Min(CurrentBar,Length-1);

for i=0 to minDay

{ highestValue=Max(highestValue,c[i]);

}

Commentary("最高价"+text(highestValue));

End

 

现在说说参数与函数,说完了这个东西,就要进入实践阶段了,就要准备开始实打实的独立编写指标了
首先我们必须明白,参数仅仅存在于函数里面,如果函数里面存在着参数,那么当你调用这个函数的时候必须要先传递参数给这个函数
函数就是帮助我们完成某一件事情,并且完成这件事情以后会返回个东西给我们的一个方法.
比如一个这样的函数 请注意,这仅仅是个假想的函数,仅为了帮助理解函数是什么:
GetCloseFromTrader
我们就很明白,这个函数就是帮助我们到交易所跑一趟,然后把收盘价返回给我们;
有点明白了吧,但是仔细一想,这个东西似乎有点问题,比如返回收盘价,交易所
那么多的品种,且每个品种都有那么多的月份,他到底返回的是什么东西的收盘价啊?
那么我们这样写:
GetCloseFromTrader(Cu0801)
现在应该完全明白了,这个函数就是从交易所返回某个品种的收盘价,到底是什么品种什么月份的收盘价呢?
Cu0801就是拉.
其实,这里面的Cu0801就是这个函数所需要的参数!
我们于是就可以这样理解:函数是帮助用户完成某一件事情且返回用户所需要的数据的方法;
那么参数呢?参数就是参到函数里面去的数,也就是说必须要传递给函数的数;
我们现在不要求一定能够自己写函数,但是必须要懂得的是要看懂这个函数是做什么用的,且知道如何去调用这个函数!

我们先看看下面的这个函数,这个函数的名字叫:HHV,是根据轮回老大的建议改写的,我们必须要读懂这个函数,且知道怎么样去

CODE:

//------------------------------------------------------------------------
// 简称: HHV
// 名称: 求N周期的最高值
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

Params
   NumericSeries Price(0);
   Numeric Length(5);
Vars
   Numeric highestValue(0);
   Numeric minDay;
   Numeric i;
Begin
   minDay = Min(CurrentBar,Length-1);
   for i=0 to minDay
   {
           highestValue=Max(highestValue,Price[i]);
   }
   Return highestValue;
End

 

我们一行一行的读,一行一行的理解;
首先我们都知道,//后面的代表是注释,什么是注释
通过注释我们可以粗略的明白这个函数是干什么的?代表了什么意思:
这个函数的名字HHV,他的作用是求N周期的最高值,并且会把这个最高值返回给调用这个函数的用户
通过此,我们就能够想到,这个N是个参数,比如5个周期或者10个周期或者其他周期的最高值,
再仔细一想,是什么价格的最高值啊?是收盘价的最高值还是开盘价的最高值?或者是最高价的最高值呢?
于是我们也就想到了这个函数的另外个参数:价格,比如5个周期的收盘价的最高值,或者10个周期的最高价的最高值
紧接着,这个函数开始定义参数了,
Params后面定义的就是参数,一个代表要得到什么价格的最高值,一个代表要得到什么周期的最高值;
参数定义完了,这个函数就开始定义变量,对于函数,我们首先定义一个变量highestValue,我们这个函数必须要把这个变量返回给用户的
这个变量highestValue就代表了你想得到的最高值!其他的两个变量我们先不要理睬,紧接着就是Begin了,前面我们说过,Begin后面,我们的代码就要开始工作
我们先想一想,假设我们求5天的收盘价的最高值,在第一根K线上,我们希望得到的收盘价的最高值就是这天的收盘价;
到第二根K线的时候我们希望得到的收盘价的最高值是这两天的收盘价中价格最高的那个,第三根就是得到这三根K线里面收盘价最大的那个收盘价,
第四天同样如此,第五天同样如此,第六天开始就取前面5天的收盘价的最高价,第七天......第N天同样如此了;
这个时候我们就应该想到,如果当前K线的索引小于你需要的周期数的时候就取当前K线的前面几个周期的最高值
于是代码开始写:
minDay = Min(CurrentBar,Length-1);
这个大家都很明白吧,如果当前K线索引假设是3,而你要得到的是5个周期的最高值,因为暂时还没有5个周期,我们我们就取这3个周期来获得这三个周期的最高值
为什么要-1呢?因为K线的索引是从0开始计算的,那么前面的minDay呢?就是个变量,我们用这个变量来代表周期,于是我们再到定义变量的地方去定义这个变量:
Numeric minDay;

再看代码:

CODE:

for i=0 to minDay
   {
           highestValue=Max(highestValue,Price[i]);
   }


很明显,这是一个前面我们所说的For循环,在For循环里面我们必须要先定义一个变量i(可以是其他名字),代表从什么基数开始循环;
于是再到定义变量的地方去定义这个i变量:
Vars
   Numeric highestValue(0);
   Numeric minDay;
   Numeric i;
再看这个For循环,
当i是0的时候,看这个时候0是不是小于等于最小周期minDay,如果条件成立,就执行:

CODE:

highestValue=Max(highestValue,Price[i]);


Price[0]代表今天的价格,先比较今天的价格和最高值,取最大的那个保存;再把i+1
于是这个时候i为1了,再比较是不是小于等于最小周期minDay,如果条件成立,再执行:

CODE:

highestValue=Max(highestValue,Price[i]);


这个时候Price[1]就代表了昨天的价格,把昨天的价格和保存的最高值比较,取他们的最高的那个再次保存;
依次循环,我们是不是就得到了某个周期某个价格的最高值了呢?
最后面,我们用代码:
Return highestValue;
把这个得到的最高值返回给用户,Return就是返回
调用这个函数的时候就更简单了,比如求10个周期的收盘价的最高值:
HHV(Close,10);
求20个周期的最高价的最高值:
HHV(High,20);
大家在看看和分析这个文章里面的函数就会完全明白了的

 

我们现在来写一个飞狐的DMA函数
原文出自这里:

QUOTE:

请编飞狐DMA函数.

函数: DMA(X,N)
别名: 动态移动平均
参数: X为数组,N为计算周期
返回: 返回数组
说明: 求X的动态移动平均。 
算法: 若Y=DMA(X,N) 则 Y=N*X+(1-N)*Y',其中Y'表示上一周期Y值,n必须小于1。
示例: DMA(CLOSE,(HIGH-LOW)/CLOSE)
表示求以该周期震幅为平滑因子的平均价
很简单,我们可以看出,如果要写这个用户函数,则我们必须要先定义两个参数,
一个是上面的X,代表价格,我们用Price来表示,一个是N,代表动态因子,我们用Length来表示


好的,开始吧!
我们先新建一个用户函数,简称写DMA,名称写:求动态移动平均,分类选用户函数,然后确定;
出来如下东西:
Params
        Numeric Num(10);
Vars
        Bool Con1;
Begin
        Con1 = Close > Num;
        Return Con1;
End
我们把那些没用的东西删除,仅留下下面的内容
Params
       
Vars
       
Begin
       
End
在定义参数的时候我们首先考虑下参数的数据类型
我们先看价格参数,很明显我们应该把它定义为数值序列型,因为Close,Open...啊,都是数值序列型的
对于动态因子,同样简单,应该是数值型,于是,我们在Params关键字后面写定义参数的代码,如下:
Params
    NumericSeries Price(100);
    Numeric Length(0.5);
Vars
       
Begin
       
End
我们首先应该明白,我们写函数的目的是要他帮我们做点事情并且返回个什么东西给我们,所以我们
再定义一个变量ReturnValue,代表这个函数要返回的数据,到时候当这个函数执行完的时候我们就把这个东西返回给调用者
于是我们再在Vars后面定义一个变量ReturnVlaue,数据类型是数值序列型,因为每根K线上都有的,所以定义成序列型,代码如下:
Params
    NumericSeries Price(100);
    Numeric Length(0.5);
Vars
    NumericSeries ReturnValue(0);
Begin
       
End

现在我们开始写这个函数的工作代码
看看这个函数的意思,今日的动态移动平均=昨日的动态移动平均*(1-动态因子)+今日的价格*动态因子;然后再把这个值Return返回就Ok了;
于是我们在Begin后面写代码:
Params
    NumericSeries Price(100);
    Numeric Length(0.5);
Vars
    NumericSeries ReturnValue(0);
Begin
    ReturnValue = ReturnValue[1]*(1-Length)+Price*Length;
    Return ReturnValue;
End

好了,这个函数就写好了
但是细心的朋友可能会发现,这个函数还有点小问题,就是如果是第一根K线,那么这根K线的昨日的动态移动平均没有啊?
这样做是不是会出错啊?
对,非常对,会出错的啊,所以我们要先判断一下这根K线是不是第一根K线,用什么来判断是不是第一根K线呢?请看这个函数:
Integer BarStatus()
当前公式应用商品当前Bar的状态值,返回值0表示为第一个Bar,返回值为1表示为中间的普通Bar,返回值为2表示最后一个Bar。
呵呵,就用BarStatus这个函数,如果他返回0,就代表第一根K线啊
于是我们再改写完善上面的代码为:
//------------------------------------------------------------------------
// 简称: DMA
// 名称: 求动态移动平均
// 类别: 用户函数
// 类型: 用户函数
// 输出: 数值型
//------------------------------------------------------------------------

Params
        NumericSeries Price(100);
    Numeric Length(0.5);
Vars
        NumericSeries ReturnValue(0);
Begin
    If(BarStatus==0)
    {
       ReturnValue = Price;//如果是第一根K线就直接把Price赋值
    }
    Else
    {
       ReturnValue = ReturnValue[1]*(1-Length)+Price*Length;
    }
    Return ReturnValue;
End

我比较喜欢而且非常喜欢把交易模型做成变色的K线,红色代表买,绿色代表卖,非常的简单明了,但是一看就又很能明白是什么意思,K线本来就是一位大大的美女,如果把红色的K线练成一块,把绿色的K线练成一块,那是多少爽的一件事情啊!!!
于是我们就要先学会画K线,在文华中画K线是STICKLINE,在TB中很简单,就用PlotNumeric吧.
如果你要画红色K线,那么就先输出High,Low,Close,Open,很好理解吧,大家都知道阳线从上到下是最高,收盘,开盘,最低,我们这个也一样,只是先输出最高最低,再输出收盘开盘;如果是要画绿色K线,那么就按照以下顺序输出那四个价格:最高,最低,开盘,收盘,呵呵
下面是画红色K线的代码:
PlotNumeric("High",High);
PlotNumeric("Low",Low);
PlotNumeric("Close",Max(Close,Open));
PlotNumeric("Open",Min(Close,Open));
大家看到了上面有个Max和Min函数,大家可以想一想为什么咯,
下面是画绿色K线的代码:
PlotNumeric("High",High);
PlotNumeric("Low",Low);
PlotNumeric("Open",Max(Close,Open));
PlotNumeric("Close",Min(Close,Open));
那么就让我先来解释下上面的为什么要用Max和Min函数吧,还是说明白一点好.
如果我们要把所有K线画成红色K线,那么是要先输出High,和Low,再输出收盘价和开盘价.但是如果当天Close<Open怎么办?于是就用Max了咯,当然,画绿色K线的Min原理也一样.
明白了吧
那么我们先来把前面的150根K线全部画成红色,后面的150根K线全部画成绿色(呵呵,我是假设超级图表中存在300根K线啊)
在右边的TB公式里面新建个技术指标,名称为MyKLine,简称随意,类型随意选,模板空,确定,写下如下代码:

CODE:

//------------------------------------------------------------------------
// 简称: MyKLine


Begin
   if(CurrentBar>150)
   {
      //如果是第151根K线画绿色
          PlotNumeric("High",High);
      PlotNumeric("Low",Low);
      PlotNumeric("Open",Max(Close,Open));
      PlotNumeric("Close",Min(Close,Open));
   }
   Else
   {
      //如果是151根K线以前的Kurtosis线画红色
          PlotNumeric("High",High);
      PlotNumeric("Low",Low);
      PlotNumeric("Close",Max(Close,Open));
      PlotNumeric("Open",Min(Close,Open));
   }
End


然后在文件---属性设置----默认-----默认显示改成主图显示,点编译按钮完成编译,然后再在超级图表里面调用这个技术指标,
当K线是十字星的时候K线会是白色的拉.
怎么办?我们首先要明白为什么会出现这样的现象的原因是收盘价=开盘价的时候会出现这样的问题.那么如何去解决这个问题呢?

下面实现的代码:

CODE:

//------------------------------------------------------------------------
// 简称: MyKLine
// 类别: 技术指标
// 类型: 其它类
// 输出:
//------------------------------------------------------------------------
Vars
   Numeric OpenIsClose;//当开盘等于收盘价的时候
Begin
   if(CurrentBar>150)
   {
      //如果是第151根K线画绿色
          PlotNumeric("High",High);
      PlotNumeric("Low",Low);
          if(Open==Close)
          {
                  //如果收盘价等于开盘价
                  OpenIsClose = Close-PriceScale*MinMove;
                  PlotNumeric("Open",Open);
                  PlotNumeric("Close",OpenIsClose);
          }
          Else
          {
         PlotNumeric("Open",Max(Close,Open));
         PlotNumeric("Close",Min(Close,Open));
          }
   }
   Else
   {
      //如果是151根K线以前的Kurtosis线画红色
          PlotNumeric("High",High);
      PlotNumeric("Low",Low);
          if(Open==Close)
          {
                  OpenIsClose = Close+PriceScale*MinMove;
                  PlotNumeric("Close",OpenIsClose);
                  PlotNumeric("Open",Open);
          }
          Else
          {
         PlotNumeric("Close",Max(Close,Open));
         PlotNumeric("Open",Min(Close,Open));
          }
   }
End

上面有两个函数PriceScale和MinMove,他们相乘的结果得到当前品种的最小变动价位,比如铜是10,胶是5......(这两个函数的具体意义以及他们的乘积为什么会得到这个结果请看TB的函数帮助)
也就是说当开盘==收盘的时候在收盘价的基础上上下浮动一个变动价位来画K线,大家看下效果,是不是很完美的解决了这个问题呢?

有了上面的画变色K线的基础,现在来做个简单的变色K线系统吧,是非常简单的;
曾听说有人用两条均线打天下,我们就做这个打天下的变色K线交易模型;
假设两条均线是5日均线和10日均线,于是就有两个变量,MaFive和MaTen,5日上穿10日买,5日下穿10日卖;
写成代码如下:

[Copy to clipboard] [ - ]

CODE:

//------------------------------------------------------------------------
// 简称: MyKLine
// 名称: 哈哈
// 类别: 技术指标
// 类型: 其它类
// 输出:
//------------------------------------------------------------------------
Vars
   Numeric OpenIsClose;//当开盘等于收盘价的时候
   NumericSeries MaFive;//5日均线
   NumericSeries MaTen;//10日均线
Begin
   MaFive = SAverage(Close,5);//5天移动平均
   MaTen = SAverage(Close,10);//10天移动平均
   if(MaFive<MaTen)
   {
          PlotNumeric("High",High);
      PlotNumeric("Low",Low);
          if(Open==Close)
          {
                  //如果收盘价等于开盘价
                  OpenIsClose = Close-PriceScale*MinMove;
                  PlotNumeric("Open",Open);
                  PlotNumeric("Close",OpenIsClose);
          }
          Else
          {
         PlotNumeric("Open",Max(Close,Open));
         PlotNumeric("Close",Min(Close,Open));
          }
   }
   Else If(MaFive>MaTen)
   {
          PlotNumeric("High",High);
      PlotNumeric("Low",Low);
          if(Open==Close)
          {
                  OpenIsClose = Close+PriceScale*MinMove;
                  PlotNumeric("Close",OpenIsClose);
                  PlotNumeric("Open",Open);
          }
          Else
          {
         PlotNumeric("Close",Max(Close,Open));
         PlotNumeric("Open",Min(Close,Open));
          }
   }
End


编译,然后插入这个技术指标,看看效果,

转载于:https://www.cnblogs.com/toujizhe/articles/2956584.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值