楼主: 挖矿专家
2565 2

[源码分享] 【每日一策】Matlab量化交易策略之 布林带突破+头寸管理 [推广有奖]

  • 0关注
  • 74粉丝

讲师

22%

还不是VIP/贵宾

-

威望
0
论坛币
2016 个
通用积分
5.2622
学术水平
21 点
热心指数
21 点
信用等级
21 点
经验
6055 点
帖子
403
精华
0
在线时间
151 小时
注册时间
2017-2-8
最后登录
2017-6-27

楼主
挖矿专家 发表于 2017-3-29 16:40:30 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
策略说明:

经典布林带突破思想,加上由20日ATR控制的止损和加仓,并且限制新头寸的增加必须在原有头寸平仓或盈利。


策略源码:

  1. function Strategyn(freq)%

  2. targetList = traderGetTargetList();
  3. %获取目标资产信息
  4. HandleList = traderGetHandleList();
  5. %获取账户句柄
  6. global record;
  7. global state;
  8. for k=1:length(targetList);
  9.    
  10.     %--------------------仓位、K线、当前bar的提取-----------------------------%
  11.     %获取当前仓位
  12.     [marketposition,~,~]=traderGetAccountPosition(HandleList(1),targetList(k).Market,targetList(k).Code);
  13.     %策略中每次取数据的长度
  14.     lags=60;
  15.     dlags=21;
  16.     barnum=traderGetCurrentBar(targetList(k).Market,targetList(k).Code);
  17.     %数据长度限制
  18.     if(barnum<lags)
  19.         continue;
  20.     end
  21.     %获取K线数据
  22.     [time,open,high,low,close,volume,~,~] = traderGetKData(targetList(k).Market,targetList(k).Code,'min',freq, 0-lags, 0,false,'FWard');
  23.     [Dtime,Dopen,Dhigh,Dlow,Dclose,Dvolume,~,~] = traderGetKData(targetList(k).Market,targetList(k).Code,'day',1, 0-dlags, 0,false,'FWard');
  24.     if length(close)<lags|| length(Dclose)<dlags
  25.         continue;
  26.     end;
  27.     % 每天的第一个bar将state全局变量复原,state的作用是保证每天只buy or sellshort 一次(后续的加仓没有限制)
  28.     if floor(time(end))~=floor(time(end-1))
  29.         state(k)=0;
  30.     end;
  31.     % 未平仓的订单提取
  32.     remain_num=find(record{k}.isopen==1);
  33.     remain.isopen=record{k}.isopen(remain_num);
  34.     remain.isearn=record{k}.isearn(remain_num);
  35.     remain.pivotprice=record{k}.pivotprice(remain_num);
  36.     remain.entrybar=record{k}.entrybar(remain_num);
  37.     remain.unit=record{k}.unit(remain_num);
  38.     remain.direction=record{k}.direction(remain_num);
  39.    
  40.     % ------------------- 计算购买手数 ----------------------------- %
  41.     % 提取剩余可用资金
  42.     [ValidCash,MarketCap,~,~,~] = traderGetAccountInfo(HandleList(1));
  43.     [~,~,Multiple,~,~,~,~,LongMargin,ShortMargin] = traderGetFutureInfo(targetList(k).Market,targetList(k).Code);
  44.     % 计算当前还有几分资金没使用
  45.     num=0;                             % isopen==1 表示未平仓的资金
  46.     for i=1:length(record)
  47.         aa=find(record{i}.isopen==1);
  48.         num=num+length(aa);
  49.     end;
  50.     n=5;
  51.     remain_share=n*length(targetList)-num;    % 资金总共分为 n*length(targetList)份,已经用了num 份
  52.    
  53.     % con1:当n份资金都使用完了,con1=0,不继续开仓,因为没有足够的资金了
  54.     con1=0;
  55.     if remain_share~=0;
  56.         con1=1;
  57.         %openunit=fix(MarketCap/close(end)/Multiple/length(targetList)/n);  % 一份资金可以购买的手数(没有带杠杆买)
  58.         openunit=fix(ValidCash/close(end)/Multiple/length(targetList)/remain_share/LongMargin);  % 一份资金可以购买的手数(带杠杆买)
  59.     end;
  60.     %------------------- 判断当前是多头持仓还是空头持仓 --------------------%
  61.     posdir=0;
  62.     if ~isempty(remain.direction)
  63.         if remain.direction(end)>0     % 有多头持仓只进多头,空头持仓只进空头,因此只需察看remain.direction数组的任意元素的值
  64.             posdir=1;
  65.         elseif remain.direction(end)<0
  66.             posdir=-1;
  67.         end;
  68.     end;
  69.    
  70.    

  71.     stds=std(Dclose(end-dlags+1:end-1));
  72.     means=mean(Dclose(end-dlags+1:end-1));
  73.    
  74.     %---------------------------------对未平仓的订单进行平仓或者调整止损线--------------------------------------------%
  75.     for i=1:length(remain_num)
  76.         index=remain_num(i);
  77. %         conbar=barnum-remain.entrybar(i)>10;         %十根bar后,仍无操作,强制平仓
  78.         if remain.direction(i)==1
  79.             if (close(end)<remain.pivotprice(i)-stds)  % 触发止损线
  80.                 orderID3=traderDirectSell(HandleList(1),targetList(k).Market,targetList(k).Code,remain.unit(i),0,'market','sell');
  81.                 if orderID3==0
  82.                     continue;
  83.                 end;
  84.                 record{k}.isopen(index)=0;
  85.             elseif close(end)>remain.pivotprice(i)+2*stds % 触发止盈线
  86.                 record{k}.pivotprice(index)=close(end);
  87.                 record{k}.isearn(index)=2;
  88.             end;
  89.         elseif remain.direction(i)==-1
  90.             if (close(end)>remain.pivotprice(i)+stds) % 触发止损线
  91.                 orderID4=traderDirectBuy(HandleList(1),targetList(k).Market,targetList(k).Code,remain.unit(i),0,'market','buy');
  92.                 if orderID4==0
  93.                     continue;
  94.                 end;
  95.                 record{k}.isopen(index)=0;
  96.             elseif close(end)<remain.pivotprice(i)-2*stds % 触发止盈线
  97.                 record{k}.pivotprice(index)=close(end);
  98.                 record{k}.isearn(index)=2;
  99.             end;
  100.         end;
  101.     end;
  102.     %    %--------------------- 止损/入场条件计算 ------------------------------------%
  103.     con2=isempty(find(remain.isearn==1,1));              % 所有头寸都是盈利的才考虑进新的头寸
  104.     upline=means+0.5*stds;
  105.     dnline=means-0.5*stds;
  106.     bcon=close(end)>upline && state(k)==0;
  107.     scon=close(end)<dnline && state(k)==0;
  108.     buycon=con1 && con2 && bcon && posdir==0;           % 突破布林带上轨道做多(每天只做一手)
  109.     sellshortcon=con1 && con2 && scon && posdir==0;     % 突破布林带下轨道做空(每天只做一手)
  110.     addbuycon=con1 && con2 && posdir>0;                 % 盈利了直接加仓
  111.     addsellshortcon=con1 && con2 && posdir<0;           % 盈利了直接加仓
  112.     %---------------------------入场操作--------------------------------%
  113.     if buycon       % 无仓时买进
  114.         orderID1=traderDirectBuy(HandleList(1),targetList(k).Market,targetList(k).Code,openunit,0,'market','buy');
  115.         if orderID1==0
  116.             continue;
  117.         end;
  118.         record{k}.pivotprice=[record{k}.pivotprice,close(end)];
  119.         record{k}.isearn=[record{k}.isearn,1];
  120.         record{k}.isopen=[record{k}.isopen,1];
  121.         record{k}.unit=[record{k}.unit,openunit];
  122.         record{k}.entrybar=[record{k}.entrybar,barnum];
  123.         record{k}.direction=[record{k}.direction,1];
  124.         state(k)=1;                 % state==1 则当天不再采取空仓买进的操作
  125.     end;
  126.     if sellshortcon    % 无仓时卖空
  127.         orderID2=traderDirectSell(HandleList(1),targetList(k).Market,targetList(k).Code,openunit,0,'market','sell');
  128.         if orderID2==0
  129.             continue;
  130.         end;
  131.         record{k}.pivotprice=[record{k}.pivotprice,close(end)];
  132.         record{k}.isearn=[record{k}.isearn,1];
  133.         record{k}.isopen=[record{k}.isopen,1];
  134.         record{k}.unit=[record{k}.unit,openunit];
  135.         record{k}.entrybar=[record{k}.entrybar,barnum];
  136.         record{k}.direction=[record{k}.direction,-1];
  137.         state(k)=1;                % state==1 则当天不再采取空仓卖空的操作
  138.     end;
  139.     if addbuycon   % 多仓时买进
  140.         orderID1=traderDirectBuy(HandleList(1),targetList(k).Market,targetList(k).Code,openunit,0,'market','buy');
  141.         if orderID1==0
  142.             continue;
  143.         end;
  144.         record{k}.pivotprice=[record{k}.pivotprice,close(end)];
  145.         record{k}.isearn=[record{k}.isearn,1];
  146.         record{k}.isopen=[record{k}.isopen,1];
  147.         record{k}.unit=[record{k}.unit,openunit];
  148.         record{k}.entrybar=[record{k}.entrybar,barnum];
  149.         record{k}.direction=[record{k}.direction,1];
  150.     end;
  151.     if addsellshortcon   % 空仓时卖空
  152.         orderID2=traderDirectSell(HandleList(1),targetList(k).Market,targetList(k).Code,openunit,0,'market','sell');
  153.         if orderID2==0
  154.             continue;
  155.         end;
  156.         record{k}.pivotprice=[record{k}.pivotprice,close(end)];
  157.         record{k}.isearn=[record{k}.isearn,1];
  158.         record{k}.isopen=[record{k}.isopen,1];
  159.         record{k}.unit=[record{k}.unit,openunit];
  160.         record{k}.entrybar=[record{k}.entrybar,barnum];
  161.         record{k}.direction=[record{k}.direction,-1];
  162.     end;
  163. end
  164. end
复制代码


更多免费策略源码下载请登录DigQuant社区-策略资源下载~
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝


沙发
lightnight_lee 发表于 2017-3-29 17:05:36 来自手机
挖矿专家 发表于 2017-3-29 16:40
策略说明:

经典布林带突破思想,加上由20日ATR控制的止损和加仓,并且限制新头寸的增加必须在原有头寸平 ...
想看收益

藤椅
ghjktdf 发表于 2017-3-29 18:59:44
楼主应该没有实盘吧

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jr
拉您进交流群
GMT+8, 2026-1-28 21:04