系统交易论坛 - 开拓者期货自动交易平台's Archiver

nopain 发表于 2009-9-15 15:21

关于持仓系统过夜提前发单的写法

最近有很多朋友问到如何实现持仓系统过夜提前发单的问题,特意写一个模板,有此需要的朋友可以依样画葫芦。修改入场条件即可。

模板的交易系统采取价格和均线通道的穿越入场,一直在市。如果您的系统有较大差别,可以将开仓和平仓分别按此模板处理。

模板是应用于30分钟周期,上午收盘或下午收盘会提前交易。[code]
Params
        Numeric Length(20);
        Numeric OffSet(5);
Vars
        Numeric MinPoint;
        Numeric AvgValue;

        NumericSeries UpBand;
        NumericSeries DnBand;
        BoolSeries LongCon;
        BoolSeries ShortCon;
       
        Numeric LastBarIndex;                // 用来保存最后交易Bar的索引
        Numeric SendOrderFlag;                // 用来保存交易状态信息
Begin
        If(Date!=Date[1] && High == Low ) Return; // 集合竞价数据的过滤

        LastBarIndex = GetGlobalVar(0);
        SendOrderFlag = GetGlobalVar(1);
        If(LastBarIndex != CurrentBar)
        {
                SendOrderFlag = 0;
                LastBarIndex = CurrentBar;
                SetGlobalVar(0,LastBarIndex);
                SetGlobalVar(1,SendOrderFlag);
        }
       
        MinPoint = MinMove*PriceScale;
        AvgValue = AverageFC(Close,Length);
        UpBand = AvgValue + OffSet * MinPoint;
        DnBand = AvgValue - OffSet * MinPoint;
       
        LongCon = CrossOver(Close,UpBand);
        ShortCon = CrossUnder(Close,DnBand);
       
        If(BarStatus == 2) // 实际交易
        {               
                If(SendOrderFlag==1)
                {
                        Buy(1,Close);
                }else If(SendOrderFlag==-1)
                {
                        SellShort(1,Close);
                }Else If(SendOrderFlag ==0 && ((Time==0.1100 && CurrentTime > 0.112800 )||(Time==0.1430 && CurrentTime > 0.145800 )))
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(1,Q_AskPrice);
                                SendOrderFlag = 1;
                        }Else If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(1,Q_BidPrice);
                                SendOrderFlag = -1;
                        }
                        SetGlobalVar(1,SendOrderFlag);
                }
        }Else If(CurrentBar==BarCount-2)// 倒数第二根Bar
        {
                If(SendOrderFlag==1)
                {
                        Buy(1,NextOpen,True);
                }else If(SendOrderFlag==-1)
                {
                        SellShort(1,NextOpen,True);
                }Else
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(1,NextOpen,True);
                        }
                                       
                        If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(1,NextOpen,True);
                        }               
                }
        }Else // 测试
        {
                If(MarketPosition!=1 && LongCon)
                {
                        Buy(1,Close);
                }
                               
                If(MarketPosition!=-1 && ShortCon)
                {
                        SellShort(1,Close);
                }
        }
End
[/code]

只求薄利 发表于 2009-9-17 16:37

强帖先占座

othellojing 发表于 2009-9-18 11:07

对于这个模板我有以下的问题,望得到解答,多谢!

Params
        Numeric Length(20);
        Numeric OffSet(5);
Vars
        Numeric MinPoint;
        Numeric AvgValue;

        NumericSeries UpBand;
        NumericSeries DnBand;
        BoolSeries LongCon;
        BoolSeries ShortCon;
        
        Numeric LastBarIndex;                // 用来保存最后交易Bar的索引
        Numeric SendOrderFlag;                // 用来保存交易状态信息
[color=red]//1 对于sendorderflag这个变量,应该是记录的每个bar的交易信息吧,=1代表当前买多,=-1代表当前卖空,=0代表当前bar没有发送交易,那应该在每次buy,sell,sellshort,buytocover以后对它赋值,为什么在代码里没有呢?
[/color]Begin
        If(Date!=Date[1] && High == Low ) Return; // 集合竞价数据的过滤
[color=red]//2 关于集合竞价的判断条件:为什么在集合竞价阶段要加上date!=date[1]的判断条件,对于每天来说date[1]不都应该是昨天吗?另外集合竞价阶段high和low记录的是什么价格?[/color]        
     LastBarIndex = GetGlobalVar(0);
        SendOrderFlag = GetGlobalVar(1);
        If(LastBarIndex != CurrentBar)
        {
                SendOrderFlag = 0;
                LastBarIndex = CurrentBar;
                SetGlobalVar(0,LastBarIndex);
                SetGlobalVar(1,SendOrderFlag);
        }
        
        MinPoint = MinMove*PriceScale;
        AvgValue = AverageFC(Close,Length);
        UpBand = AvgValue + OffSet * MinPoint;
        DnBand = AvgValue - OffSet * MinPoint;
        
        LongCon = CrossOver(Close,UpBand);
        ShortCon = CrossUnder(Close,DnBand);
        
        If(BarStatus == 2) // 实际交易
        {               
                If(SendOrderFlag==1)
[color=red]//3 应该用marketposition和Longcon来作为判断条件下单吧,怎么会是用sendorderflag呢?
[/color]                {
                        Buy(1,Close);
                }else If(SendOrderFlag==-1)
                {
                        SellShort(1,Close);
                }Else If(SendOrderFlag ==0 && ((Time==0.1100 && CurrentTime > 0.112800 )||(Time==0.1430 && CurrentTime > 0.145800 )))
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(1,Q_AskPrice);
                                SendOrderFlag = 1;
                        }Else If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(1,Q_BidPrice);
                                SendOrderFlag = -1;
                        }
                        SetGlobalVar(1,SendOrderFlag);
                }
        }Else If(CurrentBar==BarCount-2)// 倒数第二根Bar
[color=red]//4 为什么会有一个倒数第二根bar和测试的判断条件呢?是不是在每当时间推移,走到新的bar,系统都会从第一个bar开始往前做运算呢,否则currentbar怎么会不等于barcount-1呢?[/color]
        {
                If(SendOrderFlag==1)
                {
                        Buy(1,NextOpen,True);
                }else If(SendOrderFlag==-1)
                {
                        SellShort(1,NextOpen,True);
                }Else
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(1,NextOpen,True);
                        }
                                       
                        If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(1,NextOpen,True);
                        }               
                }
        }Else // 测试
        {
                If(MarketPosition!=1 && LongCon)
                {
                        Buy(1,Close);
                }
                                
                If(MarketPosition!=-1 && ShortCon)
                {
                        SellShort(1,Close);
                }
        }
End

nopain 发表于 2009-9-18 13:21

1、SendOrderFlag只处理实际交易时提前委托的标记,所以只在指定地方添加。
2、Date!=Date[1]这个条件反应的是当天的第一个Bar,集合竞价出来的价格只有一个,High,Low,Close,Open都相等,我们希望这个时候不进行处理,直到开盘后交易产生更多的Tick之后。
3、这里是处理但条件满足委托之后,如果条件不稳定,则会出现讯号消失,通过这种写法,确保下单之后讯号还会保留。
4、同3,当增加一个新Bar时,会将最近两个Bar的数据一起计算,通过这么编写,可以确保最后两个Bar的信号能够保持住。

othellojing 发表于 2009-9-21 14:00

感谢答复。
还有几个问题望解答。
1、对于3,您指的条件不稳定是不是在模板里指的是早晚收市时的情形。什么时候会出现讯号消失呢?
2、在这个模板里,判断条件一barstatus==2,判断条件二CurrentBar==BarCount-2,判断条件三 else//测试。
请问判断条件三(测试)下的buy不会对真实交易产生影响对吗? 是不是说真实交易下的我们所用的代码会和测试时的有很大的不同。如果我们用测试用的策略代码来交易会怎样呢?

[color=red]另外,这个模板可以用于真实交易吗?日内的交易呢?您可以提供真实交易时日内的比较完备的代码模板吗?[/color]
[color=red]

[/color]

kautz 发表于 2009-11-6 16:52

我在1分钟线上使用时最后一个bar会出多个信号!

王顾左右 发表于 2009-11-8 21:29

2、Date!=Date[1]这个条件反应的是当天的第一个Bar,集合竞价出来的价格只有一个,High,Low,Close,Open都相等,我们希望这个时候不进行处理,直到开盘后交易产生更多的Tick之后。
如果开盘停板的话High,Low,Close,Open都相等,这个情况怎么处理?

lfxuezz 发表于 2010-7-9 10:19

}Else If(CurrentBar==BarCount-2)// 倒数第二根Bar
        {
                If(SendOrderFlag==1)
                {
                        Buy(1,NextOpen,True);
                }else If(SendOrderFlag==-1)
                {
                        SellShort(1,NextOpen,True);
                }Else
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(1,NextOpen,True);
                        }
                                       
                        If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(1,NextOpen,True);
                        }               


请问为什么要用“nextopen"呢?

efrog 发表于 2010-11-26 21:41

好久没有人对这个帖子研究了。我有几个问题想请教:
(1) 在BarStatus == 2分支,由于使用B/S指令,所以不存在重复发单问题。
(2) 在CurrentBar==BarCount-2 分支,实际行情时,是发生在新的Bar的第一个Tick传来时,TB补一个程序,还是与新Bar的第一个Tick一起执行?进一步问题是这个分支下的B/S指令是否能发送到交易柜台,还是只作信号显示?
(3) 最后的Else分支只是用作历史回测,应该说只要LongCon和ShortCon条件时稳定的,信号就能保持,但是我试下来并非如此。
为了做测试验证,我对版主的原始程序做了少许变得,让LongCon和ShortCon满足条件变得容易些;在不同的分支B/S的手数不一样;还加了FileAppend用来记录,程序如下,希望大家测试分析。谢谢![code]
//------------------------------------------------------------------------
// 简称: test1
// 名称:
// 类别: 交易指令
// 类型: 多头建仓
// 输出:
//------------------------------------------------------------------------

Params
        Numeric Length(20);
        Numeric OffSet(5);
Vars
        Numeric MinPoint;
        Numeric AvgValue;

        NumericSeries UpBand;
        NumericSeries DnBand;
        BoolSeries LongCon;
        BoolSeries ShortCon;
        
        Numeric LastBarIndex;                // 用来保存最后交易Bar的索引
        Numeric SendOrderFlag;                // 用来保存交易状态信息
Begin
        If(Date!=Date[1] && High == Low ) Return; // 集合竞价数据的过滤

        LastBarIndex = GetGlobalVar(0);
        SendOrderFlag = GetGlobalVar(1);
        If(LastBarIndex != CurrentBar)
        {
                SendOrderFlag = 0;
                LastBarIndex = CurrentBar;
                SetGlobalVar(0,LastBarIndex);
                SetGlobalVar(1,SendOrderFlag);
        }
        
        MinPoint = MinMove*PriceScale;
        AvgValue = AverageFC(Close,Length);
        UpBand = AvgValue + OffSet * MinPoint;
        DnBand = AvgValue - OffSet * MinPoint;
        
        LongCon = Low< Lowest(Low[1],5); //CrossOver(Close,UpBand);
        ShortCon = High> Highest(high[1],5); //CrossUnder(Close,DnBand);
        
        If(BarStatus == 2) // 实际交易
        {               
                If(SendOrderFlag==1)
                {
                        Buy(3,Close);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" Buy(3,Close) "+Text(Close));
                }else If(SendOrderFlag==-1)
                {
                        SellShort(3,Close);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" SellShort(3,Close) "+Text(Close));
                }Else If(SendOrderFlag ==0 && ((Time==0.1100 && CurrentTime > 0.112800 )||(Time==0.1430 && CurrentTime > 0.145800 )))
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(3,Q_AskPrice);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" Buy(3,Q_AskPrice) "+Text(Q_AskPrice));
                                SendOrderFlag = 1;
                        }Else If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(3,Q_BidPrice);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" SellShort(3,Q_BidPrice) "+Text(Q_BidPrice));
                                SendOrderFlag = -1;
                        }
                        SetGlobalVar(1,SendOrderFlag);
                }
        }Else If(CurrentBar==BarCount-2)// 倒数第二根Bar
        {
                If(SendOrderFlag==1)
                {
                        Buy(2,NextOpen,True);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" Buy(2,NextOpen,True) Flag==1 "+Text(NextOpen));
                }else If(SendOrderFlag==-1)
                {
                        SellShort(2,NextOpen,True);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" SellShort(2,NextOpen,True) Flag==-1 "+Text(NextOpen));
                }Else
                {
                        If(MarketPosition!=1 && LongCon)
                        {
                                Buy(2,NextOpen,True);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" Buy(2,NextOpen,True) "+Text(NextOpen));
                        }
                                       
                        If(MarketPosition!=-1 && ShortCon)
                        {
                                SellShort(2,NextOpen,True);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" SellShort(2,NextOpen,True) "+Text(NextOpen));
                        }               
                }
        }Else // 测试
        {
                If(MarketPosition!=1 && LongCon)
                {
                        Buy(1,Close); FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" Buy(1,Close) "+Text(NextOpen));
                }
                                
                If(MarketPosition!=-1 && ShortCon)
                {
                        SellShort(1,Close);FileAppend("C:\Test1.log",TimeToString(CurrentTime)+" "+Text(CurrentBar)+" SellShort(1,Close) "+Text(NextOpen));
                }
        }
End
//------------------------------------------------------------------------
// 编译版本        GS2004.06.12
// 用户版本        2009/10/07 20:34
// 版权所有        guqf
// 更改声明        TradeBlazer Software保留对TradeBlazer平台
//                        每一版本的TrabeBlazer公式修改和重写的权利
//------------------------------------------------------------------------[/code]

efrog 发表于 2010-11-26 21:58

[i=s] 本帖最后由 efrog 于 2010-11-26 22:00 编辑 [/i]

对第二个问题,根据我的测试,TB时补执行一个Bar运算,然后再执行新Bar的第一个Tick。
大家可以参见这个帖子的测试和记录:[url]http://www.tradeblazer.net/forum/thread-11073-1-1.html[/url]

问题是,这个分支下:If(CurrentBar==BarCount-2)// 倒数第二根Bar
发出的B/S指令发到了交易柜台,应该是不能发到交易柜台的。单交易记录里有手数为2的成交单,当然也有手数为3的单子。

tradingart 发表于 2011-3-23 22:15

请问 什么 叫 过夜提前发单?

hansw 发表于 2011-5-4 18:13

[b]回复 [url=http://www.tradeblazer.net/forum/redirect.php?goto=findpost&pid=67675&ptid=5506]11#[/url] [i]tradingart[/i] [/b]


    同问

CrewsHe 发表于 2011-7-11 13:22

mark,同问

kings425 发表于 2011-7-19 09:22

留个记号,支持一下

foot123 发表于 2011-8-6 10:12

比如,30分钟周期,如果下午收盘前最后1个BAR满足条件,程序上以收盘价作为买卖价格,实际上收盘价产生时已经收盘了,当天没法按信号交易,所以要“过夜提前发单”。

蔡宛宏 发表于 2011-12-19 10:19

好帖  谢谢

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.