关于持仓系统过夜提前发单的写法
最近有很多朋友问到如何实现持仓系统过夜提前发单的问题,特意写一个模板,有此需要的朋友可以依样画葫芦。修改入场条件即可。模板的交易系统采取价格和均线通道的穿越入场,一直在市。如果您的系统有较大差别,可以将开仓和平仓分别按此模板处理。
模板是应用于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] 强帖先占座 对于这个模板我有以下的问题,望得到解答,多谢!
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 1、SendOrderFlag只处理实际交易时提前委托的标记,所以只在指定地方添加。
2、Date!=Date[1]这个条件反应的是当天的第一个Bar,集合竞价出来的价格只有一个,High,Low,Close,Open都相等,我们希望这个时候不进行处理,直到开盘后交易产生更多的Tick之后。
3、这里是处理但条件满足委托之后,如果条件不稳定,则会出现讯号消失,通过这种写法,确保下单之后讯号还会保留。
4、同3,当增加一个新Bar时,会将最近两个Bar的数据一起计算,通过这么编写,可以确保最后两个Bar的信号能够保持住。 感谢答复。
还有几个问题望解答。
1、对于3,您指的条件不稳定是不是在模板里指的是早晚收市时的情形。什么时候会出现讯号消失呢?
2、在这个模板里,判断条件一barstatus==2,判断条件二CurrentBar==BarCount-2,判断条件三 else//测试。
请问判断条件三(测试)下的buy不会对真实交易产生影响对吗? 是不是说真实交易下的我们所用的代码会和测试时的有很大的不同。如果我们用测试用的策略代码来交易会怎样呢?
[color=red]另外,这个模板可以用于真实交易吗?日内的交易呢?您可以提供真实交易时日内的比较完备的代码模板吗?[/color]
[color=red]
[/color] 我在1分钟线上使用时最后一个bar会出多个信号! 2、Date!=Date[1]这个条件反应的是当天的第一个Bar,集合竞价出来的价格只有一个,High,Low,Close,Open都相等,我们希望这个时候不进行处理,直到开盘后交易产生更多的Tick之后。
如果开盘停板的话High,Low,Close,Open都相等,这个情况怎么处理? }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"呢? 好久没有人对这个帖子研究了。我有几个问题想请教:
(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] [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的单子。 请问 什么 叫 过夜提前发单? [b]回复 [url=http://www.tradeblazer.net/forum/redirect.php?goto=findpost&pid=67675&ptid=5506]11#[/url] [i]tradingart[/i] [/b]
同问 mark,同问 留个记号,支持一下 比如,30分钟周期,如果下午收盘前最后1个BAR满足条件,程序上以收盘价作为买卖价格,实际上收盘价产生时已经收盘了,当天没法按信号交易,所以要“过夜提前发单”。 好帖 谢谢
页:
[1]
