OKCoin期货跨期对冲策略,季度、当周、次周
1、 季度-当周
2、 季度-次周
3、 当周-次周
4、在周五交割前5分钟会自动 平仓, 锁定15分钟 后再正常运行。
作者本人呢 是菜鸟程序猿一个, 平时没什么爱好,就喜欢写代码。最近一年在发明者量化上学到了不少新知识, 模仿Zero 大神的商品期货对冲网格策略,写了一个 电子货币 (BTC期货) 的对冲网格策略。回测一下还行(当然回测只是最初步的检测,不代表任何结论!)
以下代码不能直接运行,需要配置参数(在发明者量化平台)。代码连接: https://www.botvs.com/strategy/34878


- var checkTime = 0;
- var residualTime = 0;
- var checkPreTime = 0;
- var JGDate = []; // 交割模拟。 ["BTC1129", "BTC1229", "BTC0316"];
- var JGDateIndex = 0; // 模拟交割索引。
- var JGHoursCorrect = 8; // 检测交割剩余小时,在实盘中需要修正 8小时。 模拟时该值设置为0
- var idA = null;
- var idB = null;
- var A = 1;
- var B = 2;
- var PRE = 3;
- var PLUS = 4;
- var MINUS = 5;
- var FREE = 6;
- function init(){
- if(istry){
- JGHoursCorrect = 0; // 模拟中 该值修改为0
- Log("启用模拟 交割,初始化交割日期列表。");
- UpdateJGDate();
- }
- }
- function UpdateJGDate(){
- // 循环31次 遍历出 当前月份的所有 星期5的 日期, 取时间戳, 对比当前时间戳,小于当前的 丢弃,大于当前的第一个即是
- // 在用时间戳恢复日期,拿到 字符串
- var array_JG_stamp = [];
- var date = new Date();
- var nowStamp = date.getTime();
- var nowMonth = date.getMonth();
- var nextJG_Stamp = 0;
- date.setHours(16); // 0~23
- date.setMinutes(0); // 0~59
- date.setSeconds(0); // 0~59
- for(var i = 1 ; i <= 31; i++){
- date.setDate(i);
- var EveryDay = date.getDay(); // 1~6
- if(EveryDay === 5 && nowMonth == date.getMonth()){
- var fridayStamp = date.getTime();
- array_JG_stamp.push(fridayStamp);
- }
- }
- for(var j = 0 ; j < array_JG_stamp.length ; j++){
- if(nowStamp <= array_JG_stamp[j]){
- nextJG_Stamp = array_JG_stamp[j];
- break;
- }
- if(j == array_JG_stamp.length - 1){
- nextJG_Stamp = array_JG_stamp[j] + 1000 * 7 * 24 * 60 * 60;
- }
- }
- array_JG_stamp = [];
- for(var n = 1 ; n <= 100; n++){ // 生成 100 个 模拟交割日期。
- if(n == 1){
- array_JG_stamp.push(nextJG_Stamp);
- }else{
- nextJG_Stamp += 1000 * 7 * 24 * 60 * 60;
- array_JG_stamp.push(nextJG_Stamp);
- }
- }
- var date2 = new Date();
- for(var m = 0 ; m < array_JG_stamp.length ; m++){
- date2.setTime(array_JG_stamp[m]);
- var strMonth = date2.getMonth() + 1;
- var strDate = date2.getDate();
- if(strMonth < 10){
- strMonth = '0' + strMonth;
- }
- if(strDate < 10){
- strDate = '0' + strDate;
- }
- JGDate.push("BTC" + strMonth + strDate);
- }
- Log("模拟生成的交割日期:", JGDate);
- }
- function CheckDelivery(nowTime, Symbol, task) {
- var contractInfo = null;
- if(checkTime <= 0){
- var contractName = "";
- var ContractIndex = 0;
- if(Symbol === "this_week"){
- ContractIndex = 0;
- }else if(Symbol === "next_week"){
- ContractIndex = 1;
- }else if(Symbol === "quarter"){
- ContractIndex = 2;
- }
- if(istry === true){ // 判断是不是 模拟测试
- try{
- contractName = JGDate[JGDateIndex]; // 模拟测试 交割日期
- JGDateIndex++;
- } catch(e){
- Log("回测模式,更新交割日期错误", e);
- JGDateIndex--;
- }
- }
- while (contractName == "") {
- //var contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week"); //只是检测this_week ,避免重复调用提高效率
- switch(ContractIndex){
- case 0: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=this_week");
- break;
- case 1: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=next_week");
- break;
- case 2: contractInfo = HttpQuery("https://www.okcoin.com/api/v1/future_hold_amount.do?symbol=btc_usd&contract_type=quarter");
- break;
- default: Log("contractInfo:", contractInfo);
- //throw "switch NumContractType Error!";
- } //根据 contractType 类型 选择读取合约交割日期
- if (!contractInfo || contractInfo.length === 0) {
- Sleep(100);
- continue;
- }
- try {
- contractName = (JSON.parse(contractInfo))[0].contract_name;
- } catch (e) {
- Log("CheckDelivery Error",contractInfo, e);
- return 0;
- }
- }
- var nowDateTime = new Date();
- contractName = contractName.split("BTC")[1]; //抽取BTC后的字符串 重新赋值
- var strMonth = contractName[0] + contractName[1];
- var strDay = contractName[2] + contractName[3];
- var strYear = nowDateTime.getFullYear() + ""; //获取 年份字符串
-
- // 处理跨年问题
- var nowMonth = nowDateTime.getMonth(); // 获取月份
- if(strMonth < nowMonth){
- strYear = (strYear - 0) + 1;
- strYear = strYear + "";
- }
-
- var strDate = strYear + '-' + strMonth + '-' + strDay + ' ' + "16:00:00";
- var deliveryTime = (new Date(strDate)).getTime(); // + 16 * 60 * 60 * 1000;
- nowTime = nowDateTime.getTime();
- residualTime = (deliveryTime - nowTime) / 1000 / 60 / 60 - JGHoursCorrect; //单位是小时
- checkTime = (deliveryTime - nowTime) - JGHoursCorrect * 1000 * 60 * 60; //还差多少毫秒交割
- checkPreTime = nowTime; //记录开始的时间
- Log("合约", Symbol, "交割日期获取:", strDate);
- }else{
- checkTime -= nowTime - checkPreTime; //减去消耗的时间
- checkPreTime = nowTime;
- residualTime = checkTime / 1000 / 60 / 60; // 计算距离交割多少小时
- }
- if(residualTime < 24){ //交割小于24小时
- MSG_String = " " + Symbol + " 交割时间剩余:" + residualTime + "小时!!#FF0000";
- if((checkTime / 1000 / 60) <= 5 && task.isFrozen == false){ // 每次交割前5分钟 锁定。
- Log("距离交割剩余5分钟,平掉所有仓位!#FF0000");
- for(var index = 0; index < task.dic.length; index++){
- if(task.dic[index].hold > 0){ // 平空A 平多B
- task.action = [index, "closesell", "closebuy", task.dic[index].hold];
- Log(JSON.stringify(task.action));
- Hedge_Open_Cover(task);
- $.PlotFlag(nowTime, "C", "closesell-closebuy", "circlepin");
- }else if(task.dic[index].hold < 0){ // 平多A 平空B
- task.action = [index, "closebuy", "closesell", task.dic[index].hold];
- Log(JSON.stringify(task.action));
- Hedge_Open_Cover(task);
- $.PlotFlag(nowTime, "C", "closebuy-closesell", "circlepin");
- }
- }
- task.nowAccount = _C(task.e.GetAccount);
- var Positions = _C(task.e.GetPosition);
- UpdatePosition(task, Positions);
- Log("全部仓位已平,检查持仓:", Positions, "程序冻结15分钟!#FF0000");
- task.isFrozen = true;
- task.FrozenStartTime = new Date().getTime();
- }
- }else{
- MSG_String = " " + Symbol + " 交割时间剩余:" + residualTime + "小时!!";
- }
- return _N(residualTime, 3);
- }
- function OpenPriceToActual(Price, Piece){
- var OnePieceEquivalentCoin = 100 / Price;
- var OpenFee = Piece * (OnePieceEquivalentCoin) * (0.03 * 0.01);
- var Actual = Price + (OpenFee * Price) / (OnePieceEquivalentCoin * Piece);
- return Actual;
- //Log("Actual:", Actual, "OpenFee:", OpenFee, "OnePieceEquivalentCoin:", OnePieceEquivalentCoin, "保证金:", OpenFee / 0.01 / 0.03 / 10); // 测试
- //var Actual = Price + ((0.03 * 0.01) * Price);
- }
- function CreateHedgeList(Begin, End, Size, Step, AmountOfPoint, SymbolA, SymbolB){
- // "(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";
- if((SymbolA !== "this_week" && SymbolA !== "next_week" && SymbolA !== "quarter") || (SymbolB !== "this_week" && SymbolB !== "next_week" && SymbolB !== "quarter")){
- throw "合约代码错误: SymbolA " + SymbolA + " SymbolB " + SymbolB;
- }
- var BodyString = "";
- var HeadString = '(' + SymbolA + '&' + SymbolB + ')';
- for(var i = Begin ; i <= End ; i += Step){
- if(i + Step > End){
- BodyString += (i + ':') + (i - Size) + (':' + AmountOfPoint);
- }else{
- BodyString += (i + ':') + (i - Size) + (':' + AmountOfPoint) + ';';
- }
- }
- var HL = HeadString + BodyString;
- Log("按参数生成对冲列表:", HL);
- return HL;
- }
- function UpdatePosition(task, Positions, onlyAorBorPRE){
- if(Positions.length > 2){
- Log(Positions, "Positions 长度大于2!#FF0000");
- throw "同类型合约不能同时持有多仓空仓。";
- }
- if(onlyAorBorPRE == PRE){
- task.Pre_APositions = task.APositions;
- task.Pre_BPositions = task.BPositions;
- }
- for(var i = 0; i < Positions.length; i++){
- if(Positions[i].ContractType == task.symbolA && onlyAorBorPRE !== B){
- task.APositions = Positions[i];
- }
- if(Positions[i].ContractType == task.symbolB && onlyAorBorPRE !== A){
- task.BPositions = Positions[i];
- }
- }
- if(Positions.length == 0){
- if(onlyAorBorPRE !== B){
- task.APositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
- }
- if(onlyAorBorPRE !== A){
- task.BPositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
- }
- if(onlyAorBorPRE !== A && onlyAorBorPRE !== B){
- task.APositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
- task.BPositions = {MarginLevel: 0, Amount: 0, FrozenAmount: 0, Price: 0, Profit: 0, Type: 0, ContractType: ""};
- }
- }
- }
- function DealAction(task, AorB, amount){
- if(amount <= 0){
- throw "错误: DealAction 的 amount 参数为:" + amount;
- }
- if(AorB == A){
- task.e.SetContractType(task.symbolA);
- task.e.SetDirection(task.action[1]);
- if(task.action[1] == "buy" || task.action[1] == "closesell"){
- idA = task.e.Buy(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolA);
- }else if(task.action[1] == "sell" || task.action[1] == "closebuy"){
- idA = task.e.Sell(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolA);
- }
- }
- if(AorB == B){
- task.e.SetContractType(task.symbolB);
- task.e.SetDirection(task.action[2]);
- if(task.action[2] == "buy" || task.action[2] == "closesell"){
- idB = task.e.Buy(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolB);
- }else if(task.action[2] == "sell" || task.action[2] == "closebuy"){
- idB = task.e.Sell(-1, typeof(amount) == "undefined" ? Math.abs(task.action[3]) : amount, task.symbolB);
- }
- }
- }
字数限制只能上传一下半代码;感兴趣查看源码吧


雷达卡




京公网安备 11010802022788号







