(Boll)指标是股市技术分析的常用工具之一,通过计算股价的“标准差”,再求股价的“信赖区间”。该指标在图形上画出三条线,其中上下两条线可以分别看成是股价的压力线和支撑线,而在两条线之间还有一条股价平均线,布林线指标的参数最好设为20。一般来说,股价会运行在压力线和支撑线所形成的通道中。
与MACD、RSI、KDJ等指标一样,BOLL指标也是股票市场最实用的技术分析参考指标。
但是这些指标也都是对于历史数据的统计计算形成的,客观的讲是不能绝对预测未来标的物的走势行情的。根据历史的行情数据,计算出的指标,可以作为参考、辅助决策,最终会发现一切都是围绕着概率。
那么 BOLL 指标的实际意义是 标的物价格的 标准差,期货的不同合约之间都有一定的价差,通常情况下 行情平稳的时候价差是保持一定趋势缓慢变动的,遇到“不理性”的订单的时候往往会出现短暂的波动,试想如何抓住这些“不理性”的订单呢?
我们考虑构建一个 《跨期布林对冲策略》 ,从底层撸代码、造车轮 太慢了, 使用 BotVS 分分钟实现你的各种交易思路。
实现这个策略,我们选择标的物为 : OKEX 的 BTC 合约, 稍后我也会写出 标的物 为: 商品期货 合约的该策略 (为什么用BTC 合约? 因为好实现,方便快速写出来 测试!标的物只是一方面,关键是思路 、策略!)
跨期布林对冲策略
var P_isSetOneKLine = true;
var isShowChart = true;
var retrySlidePrice = 2;
// 全局变量
var KPeriod = [PERIOD_M1, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_D1][P_KPeriod];
var DiffData = { // 差价K线数据
plusKLine : [], // 差价K线数组
minusKLine : [],
KPeriod : KPeriod, // 差价K线周期
};
var distance = 0; // 距离
var IDLE = 0;
var PLUS = 1;
var MINUS = 2;
var State = IDLE; // 策略 运行状态状态
var perState = IDLE;
var OPEN = 3; // 用于区分 是那种操作 在 BuyA_SellB 、 SellA_BuyB 函数中
var COVER = 4;
var isTradeOnThisBar = false; // 是否在当前Bar 交易了 废弃
var isCoverOnthisBar = false; // 废弃
var upRatio = 0;
var downRatio = 0;
var P = null; // 交易控制对象
var ManagerData = { // 控制对象
initAccount : null, // 初始账户 信息
Account : null, // 当前账户 信息
perAccount : null,
MaxUsedRatio : MaxUsedRatio, // 最大 保证金使用率
MaxUsedMargin : 0, // 每次 平仓后 重新计算的 最大保证金使用量
APosition : null, // 多头 仓位信息
BPosition : null, // 空头 仓位信息
floatProfit : 0, // 浮动盈亏
CoverProfit : 0, // 平仓盈亏
MarginLevel : MarginLevel, // 杠杆数
Margin : 0, // 当前保证金使用
// 行情数据
DepthA : null, // A 合约的 深度数据
DepthB : null, // B 合约的 深度数据
// 错误信息
ErrorStr : "", // 错误信息字符串
ErrorTimeStamp : 0, // 错误信息 时间戳
}
var DiffDataOneKLine = { // K线结构
KLine : [], // K线数组 ,整理后的差价
KPeriod : KPeriod, // K线周期
}
var test = { // 测试 模式 使用的结构
amount : 4,
ProfitDiff : 0,
ID : 0,
OpenDiff : 0,
};
var perRecordsTime = 0; // 合成的 K线 上一个bar 的时间戳
var PeriodBeginTime = 0; // 周期起始时间
function UpdateDiffData(DepthA, DepthB, RecordsA, RecordsB){ // 处理差价K线数据的更新
var plusDiff = DepthA.Bids[0].Price - DepthB.Asks[0].Price;
var minusDiff = DepthA.Asks[0].Price - DepthB.Bids[0].Price;
if(P_isSetOneKLine){
var Diff = _N((plusDiff + minusDiff) / 2 , 4);
}
if(RecordsA[RecordsA.length - 1].Time == RecordsB[RecordsB.length - 1].Time && RecordsB[RecordsB.length - 1].Time !== PeriodBeginTime){
if(!P_isSetOneKLine){
// 新K线周期出现
var plusBar = {
Open : plusDiff,
Close : plusDiff,
High : plusDiff,
Low : plusDiff,
Time : 0,
};
var minusBar = {
Open : minusDiff,
Close : minusDiff,
High : minusDiff,
Low : minusDiff,
Time : 0,
};
PeriodBeginTime = RecordsB[RecordsB.length - 1].Time;
plusBar.Time = PeriodBeginTime;
minusBar.Time = PeriodBeginTime;
DiffData.plusKLine.push(plusBar);
DiffData.minusKLine.push(minusBar);
}else{
var Bar = {
Open : Diff,
Close : Diff,
High : Diff,
Low : Diff,
Time : 0,
};
PeriodBeginTime = RecordsB[RecordsB.length - 1].Time;
Bar.Time = PeriodBeginTime;
DiffDataOneKLine.KLine.push(Bar);
}
}else{
if(!P_isSetOneKLine){
if(plusDiff > DiffData.plusKLine[DiffData.plusKLine.length - 1].High){
DiffData.plusKLine[DiffData.plusKLine.length - 1].High = plusDiff;
}else if(plusDiff < DiffData.plusKLine[DiffData.plusKLine.length - 1].Low){
DiffData.plusKLine[DiffData.plusKLine.length - 1].Low = plusDiff;
}
DiffData.plusKLine[DiffData.plusKLine.length - 1].Close = plusDiff;
if(minusDiff > DiffData.minusKLine[DiffData.minusKLine.length - 1].High){
DiffData.minusKLine[DiffData.minusKLine.length - 1].High = minusDiff;
}else if(minusDiff < DiffData.minusKLine[DiffData.minusKLine.length