summerXXX 发表于 2016-6-25 09:49:27

国外著名策略 Dual Thrust (转自BotVS)

> 基本原理

- 在当天收盘,计算两个值: 最高价-收盘价,和收盘价-最低价。然后取这两个值较大的那个,乘以k值,结果称为触发值。
- 在第二天开盘,记录开盘价,然后在价格超过(开盘+触发值)时马上买入,或者价格低于(开盘-触发值)时马上卖空。
- 这个系统是反转系统,没有单独止损。也就是说,反向信号也同时就是平仓信号。

> 图解

https://dn-filebox.qbox.me/ab06814528c0ae8c54c6bebaea4438325968fbe5.jpg

`Dual Thrust 策略包含完整的图表显示, 图表动态更新,模板引用等功能, 可做学习模板使用.`

var ChartCfg = {
    __isStock: true,
    title: {
      text: 'Dual Thrust 上下轨图'
    },
    yAxis: {
      plotLines: [{
            value: 0,
            color: 'red',
            width: 2,
            label: {
                text: '上轨',
                align: 'center'
            },
      }, {
            value: 0,
            color: 'green',
            width: 2,
            label: {
                text: '下轨',
                align: 'center'
            },
      }]
    },
    series: [{
      type: 'candlestick',
      name: '当前周期',
      id: 'primary',
      data: []
    }, {
      type: 'flags',
      onSeries: 'primary',
      data: [],
    }]
};

var STATE_IDLE = 0;
var STATE_LONG = 1;
var STATE_SHORT = 2;
var State = STATE_IDLE;

var LastBarTime = 0;
var UpTrack = 0;
var BottomTrack = 0;
var chart = null;
var Counter = {
    w: 0,
    l: 0
};

var manager = null;
var logSuffix = NotifyWX ? '@' : '';

function onTick(exchange) {
    if (!manager) {
      if (_C(exchange.GetPosition).length > 0) {
            throw "策略启动前不能有持仓.";
      }
      Log('交易平台:', exchange.GetName(), _C(exchange.GetAccount));
      var insDetail = _C(exchange.SetContractType, ContractTypeName);
      Log("合约", insDetail.InstrumentName, "一手", insDetail.VolumeMultiple, "份, 最大下单量", insDetail.MaxLimitOrderVolume, "保证金率:", insDetail.LongMarginRatio.toFixed(4), insDetail.ShortMarginRatio.toFixed(4), "交割日期", insDetail.StartDelivDate);
      manager = $.NewPositionManager();
    }

    var records = _C(exchange.GetRecords);
    if (!records || records.length <= NPeriod) {
      return;
    }
    var Bar = records;
    if (LastBarTime !== Bar.Time) {
      var HH = TA.Highest(records, NPeriod, 'High');
      var HC = TA.Highest(records, NPeriod, 'Close');
      var LL = TA.Lowest(records, NPeriod, 'Low');
      var LC = TA.Lowest(records, NPeriod, 'Close');

      var Range = Math.max(HH - LC, HC - LL);

      UpTrack = _N(Bar.Open + (Ks * Range));
      DownTrack = _N(Bar.Open - (Kx * Range));
      if (LastBarTime > 0) {
            var PreBar = records;
            chart.add(0, , -1);
      } else {
            for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) {
                var b = records;
                chart.add(0, );
            }
      }
      chart.add(0, );
      ChartCfg.yAxis.plotLines.value = UpTrack;
      ChartCfg.yAxis.plotLines.value = DownTrack;
      ChartCfg.subtitle = {
            text: '上轨: ' + UpTrack + '下轨: ' + DownTrack
      };
      chart.update(ChartCfg);
      chart.reset(PeriodShow);

      LastBarTime = Bar.Time;
    } else {
      chart.add(0, , -1);
    }

    LogStatus("Price:", Bar.Close, "Up:", UpTrack, "Down:", DownTrack, "Wins: ", Counter.w, "Losses:", Counter.l, "Date:", new Date());
    var msg;
    if (State === STATE_IDLE || State === STATE_SHORT) {
      if (Bar.Close >= UpTrack) {
            msg= '做多 触发价: ' + Bar.Close + ' 上轨:' + UpTrack;
            if (State !== STATE_IDLE) {
                manager.Cover(ContractTypeName);
                var profit = manager.Profit();
                LogProfit(profit);
                msg += ' 平仓利润: ' + profit;
            }
            Log(msg + logSuffix);
            manager.OpenLong(ContractTypeName, AmountOP);
            State = STATE_LONG;
            chart.add(1, {x:Bar.Time, color: 'red', shape: 'flag', title: '多', text: msg});
      }
    }

    if (State === STATE_IDLE || State === STATE_LONG) {
      if (Bar.Close <= DownTrack) {
            msg = '做空 触发价: ' + Bar.Close + ' 下轨:' + DownTrack;
            if (State !== STATE_IDLE) {
                manager.Cover(ContractTypeName);
                var profit = manager.Profit();
                LogProfit(profit);
                msg += ' 平仓利润: ' + profit;
            }
            Log(msg + logSuffix);
            manager.OpenShort(ContractTypeName, AmountOP);
            chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: '空', text: msg});
            State = STATE_SHORT;
      }
    }
}

function onexit() {
    var pos = _C(exchange.GetPosition);
    if (pos.length > 0) {
      Log("警告, 退出时有持仓", pos);
    }
}

function main() {
    if (exchange.GetName() !== 'Futures_CTP') {
      throw "只支持传统商品期货(CTP)";
    }
    SetErrorFilter("login|ready");

    LogStatus("Ready...");
    LogProfitReset();
    chart = Chart(ChartCfg);
    chart.reset();

    LoopInterval = Math.max(LoopInterval, 1);
    while (true) {
      if (exchange.IO("status")) {
            onTick(exchange);
      } else {
            LogStatus("未登录状态");
      }
      Sleep(LoopInterval * 1000);
    }
}

hebpmo 发表于 2016-6-27 07:17:00

谢谢分享!这样的帖子,可谓真正的好帖!不但介绍得很清楚,还贴上源码。支持楼主!

把握商机 发表于 2020-8-2 10:00:37

学习了,不错

▂_▃_▄_▅ 发表于 2020-8-9 11:02:48

学习了,不错

天眼 发表于 2020-9-7 11:23:03

学习了,不错

余斌 发表于 2021-7-22 21:51:35

谢谢

绿光 发表于 2021-8-5 11:38:02

支持下

tc1688 发表于 2022-4-27 15:12:40

{:1_182:}
請問這是甚麼語法?好像不適合MT4?

PHIBRO008 发表于 2023-7-6 00:48:55

国外著名策略 Dual Thrust (转自BotVS)

明月 发表于 2023-10-29 16:26:19

{:1_189:}
页: [1] 2
查看完整版本: 国外著名策略 Dual Thrust (转自BotVS)