开拓者期货期权程序化系统交易论坛

标题: 强悍的全局变量功能 [打印本页]

作者: jiaoyizhe    时间: 2011-6-29 20:18:18     标题: 强悍的全局变量功能

关于特殊变量,大家可学习下“天才期市神话”的这个文章:


全自动的程序化交易必须解决以下三大难题:

⒈既要保证交易信号的及时性,又要做到信号不能反复;

⒉记录每一次系统开、平仓的价格,以及账户的持仓变动,以便进行加减头寸及资金管理的安排;

⒊在同一根K线上进行交易控制,实现跨周期数据引用,以便精确实现短线交易时机的把握。

通过三天的学习,依托交易开拓者软件全局变量的强大功能,我终于攻克了上述三大难关。

除了普通变量外,交易开拓者软件提供了三种特殊变量,它们分别是:

⒈序列变量:可以进行数据的回溯,从而实现条件、循环语句的应用;它的运行特点是每一根BAR依次执行,这不同于坊间文华等其它交易软件平台的一次性运算。而且,它的全部函数均提供了算法,不同于黑箱的做法,有利于校对和修改。

⒉引用型变量:可以通过用户函数的形式,进行一劳永逸式的编写,避免程序的冗余。

⒊全局变量:用于中间计算过程的记录和存取,可以实现同一根BAR上的仓位管理与开平仓价格记录。

假设我们需要记录当前BAR的动态仓位状态,使用普通变量、序列变量都是无法完成这项任务的,必须使用全局变量来实施控制,并配合A_SENDORDER函数来发出买卖指令。比如,我们当条件满足时,分别记录买卖仓位的动态变化后,采用SET GLOBALVAR(0,1),记录当前的仓位为1手多单,然后可以不断改写第一个全局变量的值,在需要读取操作的时候,我们采用cw=getglobvar(0)的方式来实时地取回。使用全局变量时一定要进行初始化的设置,这样在系统断线后,只要不关闭相关图表,重连后的数据依然可以保持正确。切记不可简单使用BARSTATS的状态来确认全局变量,以下的这个例子较好地表述了套利系统中全局变量的应用。

Params
Bool  bInitStatus(False);  // 初始化标志,修改初始仓位时需设置为True
Numeric EveryLots(1);    // 每次交易数量手数
Numeric LongEntryPrice(-100000); // 开多仓的触发价格
Numeric LongExitPrice(100000);  // 平多仓的触发价格
Numeric ShortEntryPrice(100000); // 开空仓的触发价格
Numeric ShortExitPrice(-100000); // 平空仓的触发价格
Numeric LongStartLots(0);    // 多仓的初始仓位(手数),必须是EveryLots的倍数
Numeric LongEndLots(0);     // 多仓的最大仓位(手数),必须是EveryLots的倍数
Numeric ShortStartLots(0);    // 空仓的初始仓位(手数),必须是EveryLots的倍数
Numeric ShortEndLots(0);     // 空仓的最大仓位(手数),必须是EveryLots的倍数
Numeric OffsetPoint(2);   // 委托价格的偏移值(点数)
Vars  
Numeric SpreadUpper;
Numeric SpreadLower;
Numeric longPosition;
Numeric shortPosition;
Bool bLongEntryCon;
Bool bShortEntryCon;
Bool bLongExitCon;
Bool bShortExitCon;
Bool bTimeCon;
Numeric Data0Lots(1);
Numeric Data1Lots(2);
Begin
longPosition = GetGlobalVar(0);
shortPosition = GetGlobalVar(1);
If (BarStatus == 0)
{
  If(longPosition == InvalidNumeric || bInitStatus)
  {
   longPosition = LongStartLots;
   SetGlobalVar(0,longPosition);
  }
  If(shortPosition == InvalidNumeric || bInitStatus)
  {
   shortPosition = ShortStartLots;
   SetGlobalVar(1,shortPosition);
  }
}Else If(BarStatus == 2 && A_AccountID!="")
{
  If(EveryLots < 1) Return;
  If(Data0.Q_AskPrice <= 0 || Data0.Q_BidPrice <= 0 || Data1.Q_AskPrice <= 0 || Data1.Q_BidPrice <= 0) Return;
  If(Data0.Q_BidPrice == Data0.Q_UpperLimit || Data0.Q_AskPrice == Data0.Q_LowerLimit) Return;
  If(Data1.Q_BidPrice == Data1.Q_UpperLimit || Data1.Q_AskPrice == Data1.Q_LowerLimit) Return;

  SpreadUpper = Data0.Q_AskPrice-Data1.Q_BidPrice;
  SpreadLower = Data0.Q_BidPrice-Data1.Q_AskPrice;

  bTimeCon = true;//Time>0.0903 ;//And (Time<0.1127 Or Time>0.1333) And Time<0.1456;
  bLongEntryCon = (SpreadUpper<=LongEntryPrice) && (Data0.Q_AskVol>=EveryLots && Data1.Q_BidVol>=EveryLots);
  bLongExitCon = (SpreadLower>=LongExitPrice) && (Data1.Q_AskVol>=EveryLots && Data0.Q_BidVol>=EveryLots);  
  bShortEntryCon = (SpreadLower>=ShortEntryPrice) && (Data1.Q_AskVol>=EveryLots && Data0.Q_BidVol>=EveryLots);
  bShortExitCon = (SpreadUpper<=ShortExitPrice) && (Data0.Q_AskVol>=EveryLots && Data1.Q_BidVol>=EveryLots);

  If(((bLongExitCon And bTimeCon And longPosition>0) Or longPosition>LongEndLots ))
  {
   Data0.A_SendOrder(Enum_Sell,Enum_Exit,Data0Lots,Data0.Q_BidPrice-OffsetPoint*MinMove*PriceScale);
   Data1.A_SendOrder(Enum_Buy,Enum_Exit,Data1Lots,Data1.Q_AskPrice+OffsetPoint*MinMove*PriceScale);
   SetGlobalVar(0,longPosition - EveryLots);
  }

  If(((bShortExitCon And bTimeCon And shortPosition>0) Or shortPosition>ShortEndLots ))
  {
   Data0.A_SendOrder(Enum_Buy,Enum_Exit,Data0Lots,Data0.Q_AskPrice+OffsetPoint*MinMove*PriceScale);
   Data1.A_SendOrder(Enum_Sell,Enum_Exit,Data1Lots,Data1.Q_BidPrice-OffsetPoint*MinMove*PriceScale);
   SetGlobalVar(1,shortPosition - EveryLots);
  }

  If((bLongEntryCon And bTimeCon And longPosition<LongEndLots))
  {
   Data0.A_SendOrder(Enum_Buy,Enum_Entry,Data0Lots,Data0.Q_AskPrice+OffsetPoint*MinMove*PriceScale);
   Data1.A_SendOrder(Enum_Sell,Enum_Entry,Data1Lots,Data1.Q_BidPrice-OffsetPoint*MinMove*PriceScale);
   SetGlobalVar(0,longPosition + EveryLots);
  }
  
  If(( bShortEntryCon And bTimeCon And shortPosition<ShortEndLots))
  {
   Data0.A_SendOrder(Enum_Sell,Enum_Entry,Data0Lots,Data0.Q_BidPrice-OffsetPoint*MinMove*PriceScale);
   Data1.A_SendOrder(Enum_Buy,Enum_Entry,Data1Lots,Data1.Q_AskPrice+OffsetPoint*MinMove*PriceScale);
   SetGlobalVar(1,shortPosition + EveryLots);
  }
}

Commentary("多头仓位="+Text(longPosition));
Commentary("空头仓位="+Text(shortPosition));
End
作者: 白驹过隙    时间: 2011-7-9 23:28:44

很好的帖子 不要被埋没啊
作者: jiaoyizhe    时间: 2011-7-10 07:47:31

终于有人识货了
作者: 天崖    时间: 2012-4-29 07:05:18

很好的帖子,强烈支持
作者: 如烟    时间: 2012-6-1 09:51:40

看不懂啊
作者: 傻了吧    时间: 2012-6-4 09:56:14

好文,收藏
作者: kyler    时间: 2012-6-12 13:59:18

顶起来
作者: guguzhang    时间: 2012-9-23 17:38:43


作者: 千牛發理財工作    时间: 2012-10-6 15:03:44

好贴!!好清晰的思路。谢谢,收藏了。
作者: FortuneGates    时间: 2012-11-21 21:30:54

好文,参考学习。
作者: lanmeng_818    时间: 2012-12-8 15:50:17

收藏,学习.
作者: 九十九年    时间: 2012-12-8 23:04:04

好文,参考学习。
作者: 月夜微凉    时间: 2012-12-19 20:35:47

水平太低 看的不太懂
作者: ppchar    时间: 2013-2-7 15:13:15

先顶
作者: sunrains    时间: 2013-2-11 10:22:03

好帖
作者: 糊涂何妨    时间: 2013-3-26 19:14:28

切记不可简单使用BARSTATS的状态来确认全局变量 ========这句话如何理解呢?
作者: beolee    时间: 2013-3-28 20:31:45

真有人敢实盘这么跑么???????
作者: co8    时间: 2013-4-13 20:39:01

看不懂,先收藏了。。。

作者: hepang    时间: 2013-4-13 20:43:56

多看几遍
作者: jinyi1212    时间: 2013-4-20 13:55:43

经过比对,通过MtMa等输出的大周期(我用的周线)的Ma的值和期货软件上的周线Ma的值不一样,不知道是不是因为tb的大周期是推算出来的缘故?本人觉得tb编程语言搞得太复杂,好像在培养编程工程师,我们学习编程,是为了交易,只要能体现你的交易思想,越简单越好,希望能改进。
作者: 慕一一    时间: 2013-4-20 18:57:44

赞!拿来改改就能用了!
作者: 大宝天天见68    时间: 2013-4-21 18:27:11

赞一个!
作者: Miss_z    时间: 2014-1-2 13:37:50

感觉平时写的策略程序和实盘用的程序 差别好大呀。。。。
作者: vgate    时间: 2014-1-14 21:47:27

好帖!
作者: luanhaiyi    时间: 2014-1-15 13:31:41

研究研究
作者: 公楚南杰    时间: 2014-2-11 08:34:42

好文,参考学习。
作者: mujinlong    时间: 2014-2-24 11:16:53

这个是运用于什么周期的??? TICK? 1分钟???日线?
作者: yystar    时间: 2014-2-24 21:17:43

程序化爱好者请加TB程序化交流群:304973064。验证:tb论坛
作者: w_sure_241    时间: 2014-2-25 14:37:36

  1. bLongEntryCon = (SpreadUpper<=LongEntryPrice) && (Data0.Q_AskVol>=EveryLots && Data1.Q_BidVol>=EveryLots);
  2.   bLongExitCon = (SpreadLower>=LongExitPrice) && (Data1.Q_AskVol>=EveryLots && Data0.Q_BidVol>=EveryLots);  
  3.     If(((bLongExitCon And bTimeCon And longPosition>0) Or longPosition>LongEndLots ))
  4.   {
  5.    Data0.A_SendOrder(Enum_Sell,Enum_Exit,Data0Lots,Data0.Q_BidPrice-OffsetPoint*MinMove*PriceScale);
  6.    Data1.A_SendOrder(Enum_Buy,Enum_Exit,Data1Lots,Data1.Q_AskPrice+OffsetPoint*MinMove*PriceScale);
  7.    SetGlobalVar(0,longPosition - EveryLots);
  8.   }


  9.   If((bLongEntryCon And bTimeCon And longPosition<LongEndLots))
  10.   {
  11.    Data0.A_SendOrder(Enum_Buy,Enum_Entry,Data0Lots,Data0.Q_AskPrice+OffsetPoint*MinMove*PriceScale);
  12.    Data1.A_SendOrder(Enum_Sell,Enum_Entry,Data1Lots,Data1.Q_BidPrice-OffsetPoint*MinMove*PriceScale);
  13.    SetGlobalVar(0,longPosition + EveryLots);
  14.   }
复制代码
多头开仓信号里面的一个条件SpreadUpper<=LongEntryPrice,怎么会是大于SpreadUpper,应该小于吧
同理空头开仓信号(SpreadLower>=LongExitPrice) 应该是大于等于吧
作者: lulululu    时间: 2015-7-26 23:24:14

谢了  还是不懂 能否出个帖子给仔细讲讲。
作者: BennyHuang    时间: 2015-7-30 11:14:54

谢谢!楼主花了功夫的
作者: kingdomforever    时间: 2015-9-25 09:20:52

努力了几天,才慢慢上手全局变量
作者: swjtusan    时间: 2018-10-21 06:45:46

mark




欢迎光临 开拓者期货期权程序化系统交易论坛 (http://bbs.tb18.net/) Powered by Discuz! X2