You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
327 lines
12 KiB
327 lines
12 KiB
var tvBlackBgColor = '#f5f5f5' // 黑色背景色
|
|
var tvIntervalList = ['1', '5', '15', '30', '60', '240', 'D', 'W'] // 所有周期
|
|
var tvIntradayMultipliers = ['1', '5', '15', '30', '60', '240'] // 日内周期
|
|
var realtimeFlag = false;
|
|
var kcCurrentData = {};
|
|
var lastBarTime = parseInt(Date.now() / 1000);
|
|
var loadMoreFlag = false;
|
|
/**
|
|
* 一个对象,往上面挂[id]: callback;
|
|
* id为键,对应一个请求历史数据的请求,
|
|
* callback是该请求历史数据返回的回调函数,
|
|
* 且回调函数会延时清理自身过期id callback
|
|
* {
|
|
* 1: function(){}
|
|
* 2: function(){}
|
|
* }
|
|
*/
|
|
var kcHistoryKeyId = 1 // 自增id,本地维护
|
|
var kcHistoryCallbackMap = {}
|
|
|
|
var kcSocket = null // websocket 实例
|
|
var kcSubscribeId = 3601 // 自增id, 本地维护
|
|
var kcChart = null;
|
|
|
|
// 获取当前交易对 如BTC/USDT
|
|
function getSymbol() {
|
|
return kcCurrentData.symbol || (kcCurrentData.coinSymbol + '/' + kcCurrentData.baseSymbol)
|
|
}
|
|
|
|
|
|
// 设置可见K线范围
|
|
function setKLineVisibleRange(lastBarTime_t, barsCount) {
|
|
var count = barsCount || 300 // 显示几条k线
|
|
var interval = kcCurrentData.interval
|
|
var to = parseInt(lastBarTime_t) // 历史数据的最后一条柱子的时间
|
|
var toNum = 20 // 多显示几条k线距离
|
|
var seconds = getSecondsByInterval(interval); // 秒数
|
|
var options = {
|
|
from: to - (seconds * count),
|
|
to: to, // 可见的结束时间,因为结束时间可能不是当前时间,为了与右边价格刻度有一点距离所以加toNum条柱子的时间
|
|
interval: seconds
|
|
}
|
|
return options;
|
|
}
|
|
|
|
// 周期转换为秒
|
|
function getSecondsByInterval(interval) {
|
|
// 周期 ['1', '5', '15', '30', '60', '240', 'D', 'W']
|
|
interval = interval || kcCurrentData.interval;
|
|
var map = {
|
|
'1': 60,
|
|
'5': 60 * 5,
|
|
'15': 60 * 15,
|
|
'30': 60 * 30,
|
|
'60': 60 * 60,
|
|
'240': 60 * 240,
|
|
'D': 60 * 60 * 24,
|
|
'W': 60 * 60 * 24 * 7
|
|
}
|
|
return map[interval + '']
|
|
}
|
|
|
|
function loadMoreKline(data, is_first, key){
|
|
if(key == kcHistoryKeyId) {
|
|
is_first = is_first || false;
|
|
if (is_first) {
|
|
kcChart.clearData();
|
|
}
|
|
if (data != null || data != '' || data != undefined) {
|
|
var dataArr = [];
|
|
var dataArr_index = 0;
|
|
$.each(data, function (index, item) {
|
|
try {
|
|
if (typeof item == 'string') {
|
|
item = JSON.parse(item);
|
|
}
|
|
dataArr[dataArr_index] = {
|
|
timestamp: Number(item[0] * 1000),
|
|
open: Number(item[1]),
|
|
high: Number(item[3]),
|
|
low: Number(item[4]),
|
|
close: Number(item[2]),
|
|
volume: Number(item[5])
|
|
};
|
|
// if(kcCurrentData.interval == 'D' || kcCurrentData.interval == 'W') dataArr[dataArr_index].timestamp += 57600000;
|
|
dataArr_index++;
|
|
} catch (e) {
|
|
|
|
}
|
|
})
|
|
console.log(dataArr);
|
|
// kcHistoryKeyId++;
|
|
if (dataArr.length <= 0) {
|
|
kcChart.applyMoreData(dataArr, false);
|
|
} else {
|
|
lastBarTime = (dataArr[0].timestamp / 1000) - getSecondsByInterval();
|
|
console.log(lastBarTime);
|
|
kcChart.applyMoreData(dataArr, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// $('.interval_btn').on('click', function(){
|
|
// console.log('11111');
|
|
// if(kcChart != null || kcChart != undefined){
|
|
// var _this = $(this);
|
|
// kcCurrentData.interval = _this.attr('data-interval');
|
|
// // 请求历史数据
|
|
// kcHistoryKeyId = 1;
|
|
// var rang = setKLineVisibleRange(parseInt(Date.now() / 1000));
|
|
// $.ajax({
|
|
// url: "https://dfmg.dficoins.com/api/getkkline",
|
|
// type: 'get',
|
|
// async: false,
|
|
// data: {
|
|
// symbol: getSymbol(),
|
|
// interval: getSecondsByInterval(kcCurrentData.interval),
|
|
// times: kcHistoryKeyId,
|
|
// from: rang.from,
|
|
// to: rang.to + (365 * 86400)
|
|
// },
|
|
// beforeSend: function(){
|
|
// loading_index = layer.load(1, {
|
|
// shade: [0.1, '#fff'] //0.1透明度的白色背景
|
|
// });
|
|
// },
|
|
// success:function (result) { //成功回调
|
|
// console.log(result);
|
|
// if(result.status){
|
|
// loadMoreKline(result.data, true, result.code);
|
|
// $('.interval_btn').removeClass('active');
|
|
// _this.addClass('active');
|
|
// }else{
|
|
|
|
// }
|
|
// layer.close(loading_index);
|
|
// },
|
|
// error: function(xhr){
|
|
// layer.close(loading_index);
|
|
// }
|
|
// });
|
|
// }
|
|
// })
|
|
|
|
|
|
// 初始化tv
|
|
function initKlineChart() {
|
|
|
|
kcChart = klinecharts.init(kcCurrentData.containerId);
|
|
kcChart.setTimezone(kcCurrentData.timezone);
|
|
kcChart.setOffsetRightSpace(20);
|
|
// 创建一个主图指标
|
|
kcChart.createTechnicalIndicator({ name: 'VOL', calcParams: [10], styles: { margin: { top: 0.2, bottom: 2 } } })
|
|
kcChart.createTechnicalIndicator({
|
|
name: 'MA',
|
|
shortName: 'MA',
|
|
calcParams: [10, 20, 30],
|
|
dragEnabled: true,
|
|
plots: [
|
|
{ key: 'ma1', title: 'MA10: ', type: 'line' },
|
|
{ key: 'ma2', title: 'MA20: ', type: 'line' },
|
|
{ key: 'ma3', title: 'MA30: ', type: 'line' }
|
|
],
|
|
// 当计算参数改变时,希望提示的和参数一样,即title的值需要改变
|
|
regeneratePlots: (params) => {
|
|
return params.map((p, i) => {
|
|
return { key: `ma${i + 1}`, title: `MA${p}: `, type: 'line' }
|
|
})
|
|
},
|
|
// 计算结果
|
|
calcTechnicalIndicator: (kLineDataList, { params, plots }) => {
|
|
// 注意:返回数据个数需要和kLineDataList的数据个数一致,如果无值,用{}代替即可。
|
|
// 计算参数最好取回调参数params,如果不是,后续计算参数发生变化的时候,这里计算不能及时响应
|
|
const closeSums = []
|
|
return kLineDataList.map((kLineData, i) => {
|
|
const ma = {}
|
|
const close = kLineData.close
|
|
params.forEach((param, j) => {
|
|
closeSums[j] = (closeSums[j] || 0) + close
|
|
if (i >= param - 1) {
|
|
ma[plots[j].key] = closeSums[j] / param
|
|
closeSums[j] -= dataList[i - (param - 1)].close
|
|
}
|
|
})
|
|
// 如果有值的情况下,这里每一项的数据格式应该是 { ma1: xxx, ma2: xxx }
|
|
// 每个key需要和plots中的子项key对应的值一致
|
|
return ma
|
|
})
|
|
}
|
|
}, true, {
|
|
id: 'candle_pane',
|
|
dragEnabled: true
|
|
});
|
|
kcChart.setPriceVolumePrecision(kcCurrentData.coinScale, kcCurrentData.volumeScale);
|
|
kcChart.loadMore(function () {
|
|
setTimeout(function(){
|
|
if(loadMoreFlag) {
|
|
loadMoreFlag = false;
|
|
var rang = setKLineVisibleRange(lastBarTime);
|
|
$.ajax({
|
|
url: "https://dfmg.dficoins.com/api/getkkline",
|
|
type: 'get',
|
|
async: false,
|
|
data: {
|
|
symbol: getSymbol(),
|
|
interval: getSecondsByInterval(kcCurrentData.interval),
|
|
times: kcHistoryKeyId,
|
|
from: rang.from,
|
|
to: rang.to
|
|
},
|
|
success: function (result) { //成功回调
|
|
console.log(result);
|
|
if (result.status) {
|
|
loadMoreKline(result.data, false, result.code);
|
|
loadMoreFlag = true;
|
|
} else {
|
|
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}, kcHistoryKeyId == 1 ? 500 : 10);
|
|
|
|
})
|
|
kcChart.setStyleOptions({
|
|
// 蜡烛图
|
|
candle: {
|
|
// 提示
|
|
tooltip: {
|
|
// 'always' | 'follow_cross' | 'none'
|
|
showRule: 'always',
|
|
// 'standard' | 'rect'
|
|
showType: 'rect',
|
|
labels: [
|
|
langData[kcCurrentData.language].time,
|
|
langData[kcCurrentData.language].open,
|
|
langData[kcCurrentData.language].close,
|
|
langData[kcCurrentData.language].high,
|
|
langData[kcCurrentData.language].low,
|
|
langData[kcCurrentData.language].volume
|
|
],
|
|
values: null,
|
|
defaultValue: '--',
|
|
rect: {
|
|
paddingLeft: 0,
|
|
paddingRight: 0,
|
|
paddingTop: 0,
|
|
paddingBottom: 6,
|
|
offsetLeft: 8,
|
|
offsetTop: 20,
|
|
offsetRight: 8,
|
|
borderRadius: 4,
|
|
borderSize: 1,
|
|
borderColor: '#3f4254',
|
|
backgroundColor: 'rgba(17, 17, 17, .3)'
|
|
},
|
|
text: {
|
|
size: 12,
|
|
family: 'Helvetica Neue',
|
|
weight: 'normal',
|
|
color: '#fff',
|
|
marginLeft: 8,
|
|
marginTop: 6,
|
|
marginRight: 8,
|
|
marginBottom: 0
|
|
}
|
|
}
|
|
}
|
|
});
|
|
var rang = setKLineVisibleRange(lastBarTime);
|
|
$.ajax({
|
|
url: "https://dfmg.dficoins.com/api/getkkline",
|
|
type: 'get',
|
|
async: false,
|
|
data: {
|
|
symbol: getSymbol(),
|
|
interval: getSecondsByInterval(kcCurrentData.interval),
|
|
times: kcHistoryKeyId,
|
|
from: rang.from,
|
|
to: rang.to + (365 * 86400)
|
|
},
|
|
beforeSend: function(){
|
|
loading_index = layer.load(1, {
|
|
shade: [0.1, '#fff'] //0.1透明度的白色背景
|
|
});
|
|
},
|
|
success:function (result) { //成功回调
|
|
console.log(result);
|
|
if(result.status){
|
|
loadMoreKline(result.data, true, result.code);
|
|
loadMoreFlag = true;
|
|
$('.interval_btn').removeClass('active');
|
|
$('.interval_btn[data-interval="' + result.msg + '"]').addClass('active');
|
|
}else{
|
|
layer.msg(result.msg, {icon: 2});
|
|
}
|
|
layer.close(loading_index);
|
|
},
|
|
error: function(xhr){
|
|
layer.close(loading_index);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 先引入这个JS文件,然后在websocket连接成功后,调用这个方法,启动TradingView
|
|
/**
|
|
* 启动
|
|
* @param {Object} _ws 已经连接成功的Websocket对象
|
|
* @param {Object} _config Tv配置项,计价币种和交易币种必须要传入
|
|
*/
|
|
function kcStart(_config){
|
|
// 重要:k线图配置的重要数据,当前k线维护的一份数据,k线切换时,改变周期时都要变对应的值
|
|
kcCurrentData = {
|
|
containerId: _config.containerId,
|
|
baseSymbol: _config.baseSymbol, // 计价币种
|
|
coinSymbol: _config.coinSymbol, // 交易币种
|
|
symbol: _config.symbol || '--',
|
|
coinScale: _config.coinScale || 2, // 计价币种精度
|
|
volumeScale: _config.volumeScale || 2, // 成交量精度保留
|
|
interval: _config.interval || '15', // 15分钟
|
|
bgColor: _config.bgColor || tvBlackBgColor, // 当前选择背景色
|
|
language: _config.language || 'en',
|
|
timezone: _config.timezone || 'Asia/Shanghai'
|
|
}
|
|
initKlineChart()
|
|
}
|
|
|