- Quadrado
- Gráfico de lucros
Gráfico de lucros
Autora:
ChaoZhang, Data: 2024-07-02 15:56:41
Tags:
// 这个chart在JavaScript语言中是对象,在使用Chart函数之前我们需要声明一个配置图表的对象变量chart
let PERIODARR = [PERIOD_M1, PERIOD_M3, PERIOD_M5, PERIOD_M15, PERIOD_M30, PERIOD_H1, PERIOD_H2, PERIOD_H4, PERIOD_H6, PERIOD_H12, PERIOD_D1, PERIOD_D3, PERIOD_W1];
/**
* 计算简单移动平均线 (SMA)
* @param {Array<number>} data - 输入数据数组
* @param {number} period - 移动平均线的周期
* @returns {Array<number>} - 包含SMA值的数组
*/
function calculateSMA(data, period) {
let sma = [];
let sum = 0;
for (let i = 0; i < data.length; i++) {
sum += data[i];
if (i >= period - 1) {
sma.push(sum / period);
sum -= data[i - period + 1];
} else {
sma.push(null); // 如果数据点不足以计算SMA,返回null
}
}
// 填充null值
let firstNonNull = sma.find(value => value !== null);
for (let i = 0; i < sma.length; i++) {
if (sma[i] === null) {
sma[i] = firstNonNull;
}
}
return sma;
}
/**
* 计算标准差 (Standard Deviation)
* @param {Array<number>} data - 输入数据数组
* @param {number} period - 标准差计算的周期
* @returns {Array<number>} - 包含标准差值的数组
*/
function calculateStdev(data, period) {
let stdev = [];
for (let i = 0; i < data.length; i++) {
if (i >= period - 1) {
let subset = data.slice(i - period + 1, i + 1);
let mean = subset.reduce((a, b) => a + b, 0) / period;
let variance = subset.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / period;
stdev.push(Math.sqrt(variance));
} else {
stdev.push(null); // 如果数据点不足以计算标准差,返回null
}
}
// 填充null值
let firstNonNull = stdev.find(value => value !== null);
for (let i = 0; i < stdev.length; i++) {
if (stdev[i] === null) {
stdev[i] = firstNonNull;
}
}
return stdev;
}
function main() {
exchange.SetContractType("swap");
// exchange.SetMaxBarLen(200);
let chart = {
// 该字段标记图表是否为一般图表,有兴趣的可以改成false运行看看
__isStock: false, // 缩放工具
tooltip: {
xDateFormat: "%Y-%m-%d %H:%M:%S, %A",
shared: true,
crosshairs: true, // 启用十字线
formatter: function () {
let s = "<b>" + Highcharts.dateFormat("%Y-%m-%d %H:%M:%S, %A", this.x) + "</b>";
this.points.forEach(function (point) {
s += "<br/>" + point.series.name + ": " + point.y.toFixed(2);
});
return s;
}
}, // 标题
title: { text: "价差分析图" }, // 选择范围
rangeSelector: {
buttons: [
{ type: "hour", count: 1, text: "1h" },
{ type: "hour", count: 3, text: "3h" },
{
type: "hour",
count: 8,
text: "8h"
},
{ type: "all", text: "All" }
],
selected: 0,
inputEnabled: false
}, // 坐标轴横轴即:x轴,当前设置的类型是:时间
xAxis: {
type: "datetime",
crosshair: {
color: "#cccccc", // 十字线颜色
dashStyle: "shortdash", // 虚线样式
width: 1, // 线宽
zIndex: 5 // 确保线显示在其他元素之上
}
}, // 坐标轴纵轴即:y轴,默认数值随数据大小调整
yAxis: {
// 标题
title: { text: "差价" }, // 是否启用右边纵轴
opposite: false
}, // 数据系列,该属性保存的是各个数据系列(线,K线图,标签等...)
series: [
// 索引为0,data数组内存放的是该索引系列的数据
//指定颜色为blue
{ name: "spread", id: "spread", data: [], color: "blue" }, // 索引为1,设置了dashStyle:'shortdash'即:设置虚线
{ name: "basis", id: "basis", data: [], color: "orange" },
{
name: "upper",
id: "upper",
data: [],
color: "red"
},
{ name: "lower", id: "lower", data: [], color: "green" }
]
};
let symbol1Trades = exchange.GetRecords(SYMBOL1 , PERIODARR[PERIOD]);
let symbol2Trades = exchange.GetRecords(SYMBOL2 , PERIODARR[PERIOD]);
let baseTrades = exchange.GetRecords(BASESYBMOL , PERIODARR[PERIOD]);
Log(symbol1Trades.length, symbol2Trades.length, baseTrades.length);
Log(symbol1Trades[0], symbol2Trades[0], baseTrades[0]);
//取到最小的长度做为循环次数
let len = Math.min(symbol1Trades.length, symbol2Trades.length, baseTrades.length);
let spreadRecords = [];
//循环遍历
for (let i = 0; i < len; i++) {
//取到每个交易对的价格
let symbol1Price = symbol1Trades[i].Close;
let symbol2Price = symbol2Trades[i].Close;
let basePrice = baseTrades[i].Close;
//计算差价
let diff1 = symbol1Price / basePrice;
let diff2 = symbol2Price / basePrice;
let spread = diff1 / diff2;
spreadRecords.push(spread);
let basis = calculateSMA(spreadRecords, 20);
let calculateStdevs = calculateStdev(spreadRecords, 20);
let dev = 2 * calculateStdevs[i];
let upper = basis[i] + dev;
let lower = basis[i] - dev;
//将差价数据添加到图表中
chart.series[0].data.push([symbol1Trades[i].Time, spread]);
chart.series[1].data.push([symbol1Trades[i].Time, basis[i]]);
chart.series[2].data.push([symbol1Trades[i].Time, upper]);
chart.series[3].data.push([symbol1Trades[i].Time, lower]);
}
return chart;
}
Mais.