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

楼主  收藏   举报   帖子创建时间:  2019-05-05 13:52 回复:0 关注量:898
> 基本原理

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

> 图解

nclick="zoom(this, this.src, 0, 0, 0)" class="zoom" width="600" height="240" src="https://dn-filebox.qbox.me/ab06814528c0ae8c54c6bebaea4438325968fbe5.jpg" border="0" alt="" />

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

  1. var ChartCfg = {
  2.     __isStock: true,
  3.     title: {
  4.         text: 'Dual Thrust 上下轨图'
  5.     },
  6.     yAxis: {
  7.         plotLines: [{
  8.             value: 0,
  9.             color: 'red',
  10.             width: 2,
  11.             label: {
  12.                 text: '上轨',
  13.                 align: 'center'
  14.             },
  15.         }, {
  16.             value: 0,
  17.             color: 'green',
  18.             width: 2,
  19.             label: {
  20.                 text: '下轨',
  21.                 align: 'center'
  22.             },
  23.         }]
  24.     },
  25.     series: [{
  26.         type: 'candlestick',
  27.         name: '当前周期',
  28.         id: 'primary',
  29.         data: []
  30.     }, {
  31.         type: 'flags',
  32.         onSeries: 'primary',
  33.         data: [],
  34.     }]
  35. };

  36. var STATE_IDLE = 0;
  37. var STATE_LONG = 1;
  38. var STATE_SHORT = 2;
  39. var State = STATE_IDLE;

  40. var LastBarTime = 0;
  41. var UpTrack = 0;
  42. var BottomTrack = 0;
  43. var chart = null;
  44. var Counter = {
  45.     w: 0,
  46.     l: 0
  47. };

  48. var manager = null;
  49. var logSuffix = NotifyWX ? '@' : '';

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

  60.     var records = _C(exchange.GetRecords);
  61.     if (!records || records.length <= NPeriod) {
  62.         return;
  63.     }
  64.     var Bar = records[records.length - 1];
  65.     if (LastBarTime !== Bar.Time) {
  66.         var HH = TA.Highest(records, NPeriod, 'High');
  67.         var HC = TA.Highest(records, NPeriod, 'Close');
  68.         var LL = TA.Lowest(records, NPeriod, 'Low');
  69.         var LC = TA.Lowest(records, NPeriod, 'Close');

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

  71.         UpTrack = _N(Bar.Open + (Ks * Range));
  72.         DownTrack = _N(Bar.Open - (Kx * Range));
  73.         if (LastBarTime > 0) {
  74.             var PreBar = records[records.length - 2];
  75.             chart.add(0, [PreBar.Time, PreBar.Open, PreBar.High, PreBar.Low, PreBar.Close], -1);
  76.         } else {
  77.             for (var i = Math.min(records.length, NPeriod * 3); i > 1; i--) {
  78.                 var b = records[records.length - i];
  79.                 chart.add(0, [b.Time, b.Open, b.High, b.Low, b.Close]);
  80.             }
  81.         }
  82.         chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close]);
  83.         ChartCfg.yAxis.plotLines[0].value = UpTrack;
  84.         ChartCfg.yAxis.plotLines[1].value = DownTrack;
  85.         ChartCfg.subtitle = {
  86.             text: '上轨: ' + UpTrack + '  下轨: ' + DownTrack
  87.         };
  88.         chart.update(ChartCfg);
  89.         chart.reset(PeriodShow);

  90.         LastBarTime = Bar.Time;
  91.     } else {
  92.         chart.add(0, [Bar.Time, Bar.Open, Bar.High, Bar.Low, Bar.Close], -1);
  93.     }

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

  111.     if (State === STATE_IDLE || State === STATE_LONG) {
  112.         if (Bar.Close <= DownTrack) {
  113.             msg = '做空 触发价: ' + Bar.Close + ' 下轨:' + DownTrack;
  114.             if (State !== STATE_IDLE) {
  115.                 manager.Cover(ContractTypeName);
  116.                 var profit = manager.Profit();
  117.                 LogProfit(profit);
  118.                 msg += ' 平仓利润: ' + profit;
  119.             }
  120.             Log(msg + logSuffix);
  121.             manager.OpenShort(ContractTypeName, AmountOP);
  122.             chart.add(1, {x:Bar.Time, color: 'green', shape: 'circlepin', title: '空', text: msg});
  123.             State = STATE_SHORT;
  124.         }
  125.     }
  126. }

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

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

  138.     LogStatus("Ready...");
  139.     LogProfitReset();
  140.     chart = Chart(ChartCfg);
  141.     chart.reset();

  142.     LoopInterval = Math.max(LoopInterval, 1);
  143.     while (true) {
  144.         if (exchange.IO("status")) {
  145.             onTick(exchange);
  146.         } else {
  147.             LogStatus("未登录状态");
  148.         }
  149.         Sleep(LoopInterval * 1000);
  150.     }
  151. }
打赏