楼主: Dear_Li
2514 2

[区块链] 量化对冲网格模型基于发明者平台的比特币OKCoin期货交易策略 [推广有奖]

  • 0关注
  • 14粉丝

等待验证会员

已卖:405份资源

博士生

64%

还不是VIP/贵宾

-

威望
0
论坛币
699 个
通用积分
7.9246
学术水平
12 点
热心指数
16 点
信用等级
2 点
经验
4905 点
帖子
186
精华
0
在线时间
246 小时
注册时间
2018-7-21
最后登录
2019-1-16

楼主
Dear_Li 发表于 2018-12-27 16:48:59 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

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

经管之家联合CDA

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

感谢您参与论坛问题回答

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

+2 论坛币

OKCoin期货跨期对冲策略,季度、当周、次周

  • 1、 季度-当周

  • 2、 季度-次周

  • 3、 当周-次周

  • 4、在周五交割前5分钟会自动 平仓, 锁定15分钟 后再正常运行。



作者本人呢 是菜鸟程序猿一个, 平时没什么爱好,就喜欢写代码。最近一年在发明者量化上学到了不少新知识, 模仿Zero 大神的商品期货对冲网格策略,写了一个 电子货币 (BTC期货) 的对冲网格策略。回测一下还行(当然回测只是最初步的检测,不代表任何结论!)


以下代码不能直接运行,需要配置参数(在发明者量化平台)。代码连接: https://www.botvs.com/strategy/34878



  1. var checkTime = 0;
  2. var residualTime = 0;
  3. var checkPreTime = 0;
  4. var JGDate = [];                                     // 交割模拟。 ["BTC1129", "BTC1229", "BTC0316"];
  5. var JGDateIndex = 0;                                 // 模拟交割索引。
  6. var JGHoursCorrect = 8;                              // 检测交割剩余小时,在实盘中需要修正 8小时。 模拟时该值设置为0
  7. var idA = null;
  8. var idB = null;
  9. var A = 1;
  10. var B = 2;
  11. var PRE = 3;
  12. var PLUS = 4;
  13. var MINUS = 5;
  14. var FREE = 6;

  15. function init(){
  16.     if(istry){
  17.         JGHoursCorrect = 0;                          // 模拟中 该值修改为0
  18.         Log("启用模拟 交割,初始化交割日期列表。");
  19.         UpdateJGDate();
  20.     }
  21. }

  22. function UpdateJGDate(){                             
  23.     // 循环31次 遍历出 当前月份的所有 星期5的 日期, 取时间戳, 对比当前时间戳,小于当前的 丢弃,大于当前的第一个即是
  24.     // 在用时间戳恢复日期,拿到 字符串
  25.     var array_JG_stamp = [];
  26.     var date = new Date();
  27.     var nowStamp = date.getTime();
  28.     var nowMonth = date.getMonth();
  29.     var nextJG_Stamp = 0;
  30.     date.setHours(16);                     // 0~23
  31.     date.setMinutes(0);                    // 0~59
  32.     date.setSeconds(0);                    // 0~59
  33.     for(var i = 1 ; i <= 31; i++){
  34.         date.setDate(i);
  35.         var EveryDay = date.getDay();        // 1~6
  36.         if(EveryDay === 5 && nowMonth == date.getMonth()){
  37.             var fridayStamp = date.getTime();
  38.             array_JG_stamp.push(fridayStamp);
  39.         }
  40.     }
  41.     for(var j = 0 ; j < array_JG_stamp.length ; j++){
  42.         if(nowStamp <= array_JG_stamp[j]){
  43.             nextJG_Stamp = array_JG_stamp[j];
  44.             break;
  45.         }
  46.         if(j == array_JG_stamp.length - 1){     
  47.             nextJG_Stamp = array_JG_stamp[j] + 1000 * 7 * 24 * 60 * 60;      
  48.         }
  49.     }
  50.     array_JG_stamp = [];
  51.     for(var n = 1 ; n <= 100; n++){  // 生成 100 个 模拟交割日期。
  52.         if(n == 1){
  53.             array_JG_stamp.push(nextJG_Stamp);
  54.         }else{
  55.             nextJG_Stamp += 1000 * 7 * 24 * 60 * 60;
  56.             array_JG_stamp.push(nextJG_Stamp);
  57.         }
  58.     }
  59.     var date2 = new Date();
  60.     for(var m = 0 ; m < array_JG_stamp.length ; m++){
  61.         date2.setTime(array_JG_stamp[m]);
  62.         var strMonth = date2.getMonth() + 1;
  63.         var strDate = date2.getDate();
  64.         if(strMonth < 10){
  65.             strMonth = '0' + strMonth;
  66.         }
  67.         if(strDate < 10){
  68.             strDate = '0' + strDate;
  69.         }
  70.         JGDate.push("BTC" + strMonth + strDate);
  71.     }
  72.     Log("模拟生成的交割日期:", JGDate);
  73. }

  74. function CheckDelivery(nowTime, Symbol, task) {
  75.     var contractInfo = null;
  76.     if(checkTime <= 0){
  77.         var contractName = "";
  78.         var ContractIndex = 0;
  79.         if(Symbol === "this_week"){
  80.             ContractIndex = 0;
  81.         }else if(Symbol === "next_week"){
  82.             ContractIndex = 1;
  83.         }else if(Symbol === "quarter"){
  84.             ContractIndex = 2;
  85.         }
  86.         if(istry === true){                          // 判断是不是 模拟测试
  87.             try{
  88.                 contractName = JGDate[JGDateIndex];  // 模拟测试 交割日期
  89.                 JGDateIndex++;
  90.             } catch(e){
  91.                 Log("回测模式,更新交割日期错误", e);
  92.                 JGDateIndex--;
  93.             }
  94.         }
  95.         while (contractName == "") {
  96.             //var contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); //只是检测this_week ,避免重复调用提高效率
  97.             switch(ContractIndex){
  98.                 case 0: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week");
  99.                         break;
  100.                 case 1: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week");
  101.                         break;
  102.                 case 2: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter");
  103.                         break;
  104.                 default: Log("contractInfo:", contractInfo);
  105.                          //throw "switch NumContractType Error!";
  106.             }            //根据 contractType 类型 选择读取合约交割日期
  107.             if (!contractInfo || contractInfo.length === 0) {
  108.                 Sleep(100);
  109.                 continue;
  110.             }
  111.             try {
  112.                 contractName = (JSON.parse(contractInfo))[0].contract_name;
  113.             } catch (e) {
  114.                 Log("CheckDelivery Error",contractInfo, e);
  115.                 return 0;
  116.             }
  117.         }
  118.         var nowDateTime = new Date();
  119.         contractName = contractName.split("BTC")[1]; //抽取BTC后的字符串 重新赋值
  120.         var strMonth = contractName[0] + contractName[1];
  121.         var strDay = contractName[2] + contractName[3];
  122.         var strYear = nowDateTime.getFullYear() + ""; //获取 年份字符串
  123.         
  124.         // 处理跨年问题
  125.         var nowMonth = nowDateTime.getMonth(); // 获取月份
  126.         if(strMonth < nowMonth){
  127.             strYear = (strYear - 0) + 1;
  128.             strYear = strYear + "";
  129.         }
  130.         
  131.         var strDate = strYear + '-' + strMonth + '-' + strDay + ' ' + "16:00:00";
  132.         var deliveryTime = (new Date(strDate)).getTime();             // + 16 * 60 * 60 * 1000;
  133.         nowTime = nowDateTime.getTime();
  134.         residualTime = (deliveryTime - nowTime) / 1000 / 60 / 60 - JGHoursCorrect; //单位是小时
  135.         checkTime = (deliveryTime - nowTime) - JGHoursCorrect * 1000 * 60 * 60;    //还差多少毫秒交割
  136.         checkPreTime = nowTime;                                       //记录开始的时间
  137.         Log("合约", Symbol, "交割日期获取:", strDate);
  138.     }else{
  139.         checkTime -= nowTime - checkPreTime;                          //减去消耗的时间
  140.         checkPreTime = nowTime;
  141.         residualTime = checkTime / 1000 / 60 / 60;                    // 计算距离交割多少小时
  142.     }
  143.     if(residualTime < 24){                                            //交割小于24小时
  144.         MSG_String = "  " + Symbol + " 交割时间剩余:" + residualTime + "小时!!#FF0000";
  145.         if((checkTime / 1000 / 60) <= 5 && task.isFrozen == false){   // 每次交割前5分钟 锁定。
  146.             Log("距离交割剩余5分钟,平掉所有仓位!#FF0000");
  147.             for(var index = 0; index < task.dic.length; index++){
  148.                 if(task.dic[index].hold > 0){                                                 // 平空A 平多B
  149.                     task.action = [index, "closesell", "closebuy", task.dic[index].hold];
  150.                     Log(JSON.stringify(task.action));
  151.                     Hedge_Open_Cover(task);
  152.                     $.PlotFlag(nowTime, "C", "closesell-closebuy", "circlepin");
  153.                 }else if(task.dic[index].hold < 0){                                           // 平多A 平空B
  154.                     task.action = [index, "closebuy", "closesell", task.dic[index].hold];
  155.                     Log(JSON.stringify(task.action));
  156.                     Hedge_Open_Cover(task);
  157.                     $.PlotFlag(nowTime, "C", "closebuy-closesell", "circlepin");
  158.                 }
  159.             }
  160.             task.nowAccount = _C(task.e.GetAccount);
  161.             var Positions = _C(task.e.GetPosition);
  162.             UpdatePosition(task, Positions);
  163.             Log("全部仓位已平,检查持仓:", Positions, "程序冻结15分钟!#FF0000");
  164.             task.isFrozen = true;
  165.             task.FrozenStartTime = new Date().getTime();
  166.         }
  167.     }else{
  168.         MSG_String = "  " + Symbol + " 交割时间剩余:" + residualTime + "小时!!";
  169.     }
  170.     return _N(residualTime, 3);
  171. }


  172. function OpenPriceToActual(Price, Piece){
  173.     var OnePieceEquivalentCoin = 100 / Price;
  174.     var OpenFee = Piece * (OnePieceEquivalentCoin) * (0.03 * 0.01);
  175.     var Actual = Price + (OpenFee * Price) / (OnePieceEquivalentCoin * Piece);
  176.     return Actual;
  177.     //Log("Actual:", Actual, "OpenFee:", OpenFee, "OnePieceEquivalentCoin:", OnePieceEquivalentCoin, "保证金:", OpenFee / 0.01 / 0.03 / 10); // 测试
  178.     //var Actual = Price + ((0.03 * 0.01) * Price);
  179. }

  180. function CreateHedgeList(Begin, End, Size, Step, AmountOfPoint, SymbolA, SymbolB){
  181.     // "(this_week&quarter)100:90:1;110:100:1;120:110:1;130:120:1;140:130:1;150:140:1;160:150:1;170:160:1;180:170:1;190:180:1";
  182.     if((SymbolA !== "this_week" && SymbolA !== "next_week" && SymbolA !== "quarter") || (SymbolB !== "this_week" && SymbolB !== "next_week" && SymbolB !== "quarter")){
  183.         throw "合约代码错误: SymbolA " + SymbolA + " SymbolB " + SymbolB;
  184.     }
  185.     var BodyString = "";
  186.     var HeadString = '(' + SymbolA + '&' + SymbolB + ')';
  187.     for(var i = Begin ; i <= End ; i += Step){
  188.         if(i + Step > End){
  189.             BodyString += (i + ':') + (i - Size) + (':' + AmountOfPoint);
  190.         }else{
  191.             BodyString += (i + ':') + (i - Size) + (':' + AmountOfPoint) + ';';
  192.         }
  193.     }
  194.     var HL = HeadString + BodyString;
  195.     Log("按参数生成对冲列表:", HL);
  196.     return HL;
  197. }

  198. function UpdatePosition(task, Positions, onlyAorBorPRE){
  199.     if(Positions.length > 2){
  200.         Log(Positions, "Positions 长度大于2!#FF0000");
  201.         throw "同类型合约不能同时持有多仓空仓。";
  202.     }
  203.     if(onlyAorBorPRE == PRE){
  204.         task.Pre_APositions = task.APositions;
  205.         task.Pre_BPositions = task.BPositions;
  206.     }
  207.     for(var i = 0; i < Positions.length; i++){
  208.         if(Positions[i].ContractType == task.symbolA && onlyAorBorPRE !== B){
  209.             task.APositions = Positions[i];
  210.         }
  211.         if(Positions[i].ContractType == task.symbolB && onlyAorBorPRE !== A){
  212.             task.BPositions = Positions[i];
  213.         }
  214.     }
  215.     if(Positions.length == 0){
  216.         if(onlyAorBorPRE !== B){
  217.             task.APositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
  218.         }
  219.         if(onlyAorBorPRE !== A){
  220.             task.BPositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
  221.         }
  222.         if(onlyAorBorPRE !== A && onlyAorBorPRE !== B){
  223.             task.APositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
  224.             task.BPositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
  225.         }
  226.     }
  227. }

  228. function DealAction(task, AorB, amount){
  229.     if(amount <= 0){
  230.         throw "错误: DealAction 的 amount 参数为:" + amount;
  231.     }
  232.     if(AorB == A){
  233.         task.e.SetContractType(task.symbolA);
  234.         task.e.SetDirection(task.action[1]);
  235.         if(task.action[1] == "buy" || task.action[1] == "closesell"){
  236.             idA = task.e.Buy(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolA);
  237.         }else if(task.action[1] == "sell" || task.action[1] == "closebuy"){
  238.             idA = task.e.Sell(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolA);
  239.         }
  240.     }
  241.     if(AorB == B){
  242.         task.e.SetContractType(task.symbolB);
  243.         task.e.SetDirection(task.action[2]);
  244.         if(task.action[2] == "buy" || task.action[2] == "closesell"){
  245.             idB = task.e.Buy(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolB);
  246.         }else if(task.action[2] == "sell" || task.action[2] == "closebuy"){
  247.             idB = task.e.Sell(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolB);
  248.         }
  249.     }
  250. }
复制代码

字数限制只能上传一下半代码;感兴趣查看源码吧
二维码

扫码加我 拉你入群

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

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

关键词:数字货币 策略源码 量化对冲 网格模型

沙发
带着扫把流浪 学生认证  发表于 2019-1-21 23:28:28
有实战成果么?

藤椅
Joseph-Chan 在职认证  发表于 2019-6-27 10:09:44
带着扫把流浪 发表于 2019-1-21 23:28
有实战成果么?
这个策略复制之后,找个回测框架和可视化框架,就可以看策略收益了

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

本版微信群
加好友,备注jr
拉您进交流群
GMT+8, 2025-12-26 14:52