skywalker 发表于 2008-5-24 13:52:23

一个系统交易的实例:夹板

夹板在实盘中是一个很常见的运用,用于吃住震荡行情。它有个上轨和一个下轨,行情突破上轨就做空;突破下轨就做多,在上下轨之间来回吃。如图:


代码如下:

/* *******************************************************************************************
1、行情从UpperLine和LowerLine之间开始进入
2、大于等于UpperLine开空仓,小于等于LowerLine开多仓
3、从开仓点继续偏离StopInterval止损(意味着最多亏StopInterval)
4、止损一次之后不再开仓
5、下午14:55收盘前平仓
6、运用在TICK图上
******************************************************************************************** */
Params
       Numeric   upperLine(100);
       Numeric   lowerLine(100);
       Numeric   StopInterval(150);

       Numeric    firstLots(4);    // 手数(仅为正数)
       Numeric    today(26);     // 日期(5月22日,则填入22)

Vars
       Numeric   tem;

       Numeric   needPosition;   // 当前需要建立的头寸(正数为多头,负数为空头,零为全部平光)
       Numeric   needPrice;    // 建立头寸时下单的价格
       NumericSeries  wantStopLong;   // 多头止损的位置
       NumericSeries  wantStopShort;   // 空头止损的位置

Begin
       if(currentBar == 0)
       {
            // 初始化序列变量
            wantStopLong = -1;
            wantStopShort = -1;
       }Else
       {
            wantStopLong = wantStopLong;  
            wantStopShort = wantStopShort;  
       }
       if(day != today)
       {
            // 过滤非指定日期的BAR
            return ;
       }

       // 计算多、空头止损的位置
       wantStopLong = lowerLine - stopInterval;  
       wantStopShort = upperLine + stopInterval;


       // 把计算好的值输出来看看(这是调试的重要技巧!!!!!)
       Commentary("wantStopLong:"+Text(wantStopLong));
       Commentary("wantStopShort:"+Text(wantStopShort));
       tem = 0;
       if(NumLosTrades == 0) // 当日从来没有止损过,开始准备计算。开平仓的方法都包装在OpenCoverFor2Lines函数中
       {
            // OpenCoverFor2Lines函数包装了开平仓算法,其用意如下:
            // 1、返回值为零表示不做任何头寸操作,非零表示要操作
            // 2、返回值为非零时,needPosition写入了当前要建立的头寸大小和方向,needPrice写入了以什么价格去建立该头寸
            tem = OpenCoverFor2Lines(MarketPosition(),firstLots,upperLine,lowerLine,wantStopShort,wantStopLong,needPosition,needPrice);
       }

       Commentary("needPosition:"+Text(needPosition));
       Commentary("needPrice:"+Text(needPrice));

       if(tem == 0)
       {
            // 不操作任何东西,返回!
            return ;
       }
       if(MarketPosition == 0)
       {
            if(needPosition > 0)
            {
                 // 当前无仓,开始建立多头
                 buy(abs(needPosition),needPrice);
            }Else
            {
                 // 当前无仓,开始建立空头
                 SellShort(abs(needPosition),needPrice);
            }
            return ;
       }
       if(MarketPosition > 0)
       {
            if(needPosition < 0)
            {
                 // 当前多头,要求反转为空头
                 SellShort(abs(needPosition),needPrice);
            }Else
            {
                 // 当前多头,要求平仓
                 Sell(0,needPrice);
            }
        return ;
       }
       if(MarketPosition < 0)
       {
            if(needPosition > 0)
            {
                 // 当前空头,要求反转为多头
                 buy(abs(needPosition),needPrice);
            }Else
            {
                 // 当前空头,要求平仓
                 BuyToCover(0,needPrice);
            }
       }
       return 0;
End


skywalker 发表于 2008-5-24 14:02:59

OpenCoverFor2Lines函数代码



// 返回值: 1:有所动作,0:没有动作
// 返回值为非零时,把当前要建立的头寸大小和方向写入needPosition,把以什么价格去建立该头寸写入needPrice
// 返回值: 1:有所动作,0:没有动作
// 返回值为非零时,把当前要建立的头寸大小和方向写入needPosition,把以什么价格去建立该头寸写入needPrice

Params
        Numeric         currentPosition(0);                // 当前头寸,可正可负
        Numeric        firstLots(0);

        Numeric         wantShort(120);                // 开空仓位置
        Numeric         wantLong(8);                         // 开多仓位置
       
        Numeric        wantStopShort(0);                // 空头止损的位置
        Numeric        wantStopLong(0);                // 多头止损的位置

       
        // 注意:以下两个都是引用变量!!!!
        NumericRef        needPosition;    // 经过计算后的当前头寸,正数:建立多仓,负数:建立空仓,零:平光所有头寸
        NumericRef needPrice;              // 建立needPosition时的价格
       
Vars
        Numeric                         tem;
       
Begin

        // 14:55:00平掉当日所有头寸
        if(time >= 0.1455 && currentPosition != 0)
        {
                needPosition = 0;
                needPrice = close ;
                return 1;
        }
        if(currentPosition == 0)
        {
                // 无仓,准备侍机开仓
                if(close <= wantLong)
                {
                        // 多头
                        needPosition = firstLots;
                        needPrice = wantLong;
                        return 1;
                }
                if(close >= wantShort)
                {
                        // 空头
                        needPosition = -1 * firstLots;
                        needPrice = wantShort;
                        return 1;
               
                }
                return 0;
        }
       
        if(currentPosition > 0)
        {
                // 持多仓,准备止损或反转
                if(close >= wantShort)
                {
                        // 反转
                        needPosition = -1 * firstLots;
                        needPrice = wantShort;
                        return 1;
                }
               
                if(close <= wantStopLong)
                {
                        // 止损
                        needPosition = 0;
                        needPrice = wantStopLong;
                        return 1;
                       
                }
                return 0;
        }
        if(currentPosition < 0)
        {
                // 持空仓,准备止损或反转
                if(close <= wantLong)
                {
                        // 反转
                        needPosition = firstLots;
                        needPrice = wantLong;
                        return 1;
                }
               
                if(close >= wantStopShort)
                {
                        // 止损
                        needPosition = 0;
                        needPrice = wantStopShort;
                        return 1;
                       
                }
                return 0;
        }
          return 0;
End
[ 本帖最后由 skywalker 于 2008-5-24 14:05 编辑 ]

skywalker 发表于 2008-5-24 14:09:23

夹板的公式导入文件

夹板的公式导入文件:

skywalker 发表于 2008-5-24 14:18:59

初学者一定要认真体会OpenCoverFor2Lines函数,为什么需要把开平仓算法包装到函数里。夹板是个半自动的系统,因为上下轨都需要作为参数输入。当你要转换成全自动系统的时候,那么上下轨就需要根据行情动态计算出来。把计算出来的值作为参数输入OpenCoverFor2Lines函数即可,如此程序就可以方便地拓展而不需要大改动。甚至你还可以再做一个函数用于动态计算上下轨。

[ 本帖最后由 skywalker 于 2008-5-24 15:15 编辑 ]

skywalker 发表于 2008-5-24 14:22:44


if(currentBar == 0)
{
    // 初始化序列变量
    wantStopLong = -1;
    wantStopShort = -1;
}Else
{
    wantStopLong = wantStopLong;  
    wantStopShort = wantStopShort;  
}




上一段代码是使用序列变量时的常见用法,非常重要的用法。

[ 本帖最后由 skywalker 于 2008-5-24 14:25 编辑 ]

maodong 发表于 2008-5-24 15:01:22

这种结构值得借鉴,好。

stevenx8 发表于 2008-5-24 19:06:33

得认真学习了:victory:

cqzzbszz 发表于 2008-5-24 22:46:19

谢谢!一定好好学习

糊涂 发表于 2008-5-24 23:41:58

我觉得这个系统实战意义不大,原因我已经在未来函数中介绍了

guotie 发表于 2008-5-25 09:38:24

学习一下。。。thx
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: 一个系统交易的实例:夹板