Last active
August 20, 2021 15:06
-
-
Save boskiv/de2d788baeb7717db4c37c91259f8209 to your computer and use it in GitHub Desktop.
tvchart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="TVChartContainer" :id="containerId" /> | |
</template> | |
<script> | |
import { BinanceDatafeed } from "@/datafeeds/binance"; | |
import { widget } from "../../../public/charting_library"; | |
function getLanguageFromURL() { | |
const regex = new RegExp("[\\?&]lang=([^&#]*)"); | |
const results = regex.exec(window.location.search); | |
return results === null | |
? null | |
: decodeURIComponent(results[1].replace(/\+/g, " ")); | |
} | |
export default { | |
name: "TVChart", | |
props: { | |
pairChart: { | |
default: false, | |
type: Boolean, | |
}, | |
corIndicator: { | |
default: false, | |
type: Boolean, | |
}, | |
sigmaIndicator: { | |
default: false, | |
type: Boolean, | |
}, | |
watermark: { | |
default: false, | |
type: Boolean, | |
}, | |
symbol: { | |
default: "ADAUSDT", | |
type: String, | |
}, | |
interval: { | |
default: "5", | |
type: String, | |
}, | |
containerId: { | |
default: "tv_container_id", | |
type: String, | |
}, | |
datafeedUrl: { | |
default: "https://demo_feed.tradingview.com", | |
type: String, | |
}, | |
libraryPath: { | |
default: "/charting_library/", | |
type: String, | |
}, | |
chartsStorageUrl: { | |
default: "https://saveload.tradingview.com", | |
type: String, | |
}, | |
chartsStorageApiVersion: { | |
default: "1.1", | |
type: String, | |
}, | |
clientId: { | |
default: "tradingview.com", | |
type: String, | |
}, | |
userId: { | |
default: "public_user_id", | |
type: String, | |
}, | |
fullscreen: { | |
default: false, | |
type: Boolean, | |
}, | |
autosize: { | |
default: true, | |
type: Boolean, | |
}, | |
studiesOverrides: { | |
type: Object, | |
}, | |
}, | |
tvWidget: null, | |
mounted() { | |
let self = this; | |
const widgetOptions = { | |
symbol: this.symbol, | |
// BEWARE: no trailing slash is expected in feed URL | |
datafeed: new BinanceDatafeed({ debug: false }), | |
interval: this.interval, | |
// debug: true, | |
// theme: "Dark", | |
container: this.containerId, | |
library_path: this.libraryPath, | |
locale: getLanguageFromURL() || "en", | |
disabled_features: [ | |
// "left_toolbar", | |
"use_localstorage_for_settings", | |
"save_chart_properties_to_local_storage", | |
"study_templates", | |
"header_widget", | |
"popup_hints", | |
"legend_widget", | |
"control_bar", | |
"context_menus", | |
"display_market_status", | |
"symbol_info", | |
"timezone_menu", | |
], | |
enabled_features: [], | |
custom_css_url: "/css/app.css", | |
charts_storage_url: this.chartsStorageUrl, | |
charts_storage_api_version: this.chartsStorageApiVersion, | |
client_id: this.clientId, | |
user_id: this.userId, | |
fullscreen: this.fullscreen, | |
loading_screen: { backgroundColor: "#1F2937" }, | |
autosize: this.autosize, | |
studies_overrides: { | |
"volume.volume.color.0": "#ff2a6d", | |
"volume.volume.color.1": "#05d9e8", | |
"volume.volume.transparency": 70, | |
}, | |
overrides: { | |
"mainSeriesProperties.style": 1, | |
"mainSeriesProperties.candleStyle.upColor": "#05d9e8", | |
"mainSeriesProperties.candleStyle.downColor": "#ff2a6d", | |
"mainSeriesProperties.showCountdown": false, | |
"paneProperties.backgroundType": "solid", | |
"paneProperties.background": "#1F2937", | |
"scalesProperties.textColor": "#eee", | |
"scalesProperties.showStudyLastValue": true, | |
"paneProperties.legendProperties.showSeriesTitle": true, | |
"paneProperties.vertGridProperties.color": this.pairChart | |
? "rgba(74, 20, 140, 0.9493)" | |
: "#1F2937", | |
}, | |
settings_adapter: { | |
initialSettings: { | |
symbolWatermark: `{ "visibility": "${this.watermark}", "color": "rgba(255, 255, 255, 0.05)" }`, | |
}, | |
setValue: (key, value) => { | |
//console.log("SET", key, value); | |
}, | |
removeValue: (key) => { | |
//console.log("REMOVE", key); | |
}, | |
}, | |
custom_indicators_getter: function (PineJS) { | |
return Promise.resolve([ | |
{ | |
name: "sigma", | |
metainfo: { | |
_metainfoVersion: 40, | |
id: "sigma@tv-basicstudies-1", | |
scriptIdPart: "", | |
name: "sigma", | |
description: "sigma", | |
shortDescription: "sigma", | |
is_hidden_study: true, | |
is_price_study: false, | |
isCustomIndicator: true, | |
plots: [ | |
{ | |
id: "plot_0", | |
type: "area", | |
}, | |
// { | |
// id: "plot_1", | |
// type: "colorer", | |
// palette: "palette_0", | |
// target: "plot_0" | |
// } | |
], | |
defaults: { | |
palettes: { | |
palette_0: { | |
colors: { | |
0: { | |
color: "#05d9e8", | |
width: 1, | |
style: 0, | |
transparency: 30, | |
}, | |
1: { | |
color: "#008000", | |
width: 1, | |
style: 0, | |
}, | |
}, | |
}, | |
}, | |
styles: { | |
plot_0: { | |
linestyle: 0, | |
visible: true, | |
linewidth: 1, | |
plottype: 4, | |
transparency: 70, | |
color: "#05d9e8", | |
}, | |
}, | |
// Precision is set to one digit, e.g. 777.7 | |
precision: 0.1, | |
inputs: {}, | |
}, | |
styles: { | |
plot_0: { | |
title: "Equity value", | |
histogramBase: 0, | |
}, | |
}, | |
inputs: [], | |
}, | |
constructor: function () { | |
this.init = function (context, inputCallback) {}; | |
this.main = function (context, inputCallback) { | |
this._context = context; | |
this._context.new_var(0).get(3000); | |
const period = 240; | |
const close = this._context.new_var( | |
PineJS.Std.close(this._context) | |
); | |
const ma = PineJS.Std.sma(close, period, this._context); | |
const ma15 = PineJS.Std.sma(close, period * 3, this._context); | |
const ma60 = PineJS.Std.sma(close, period * 12, this._context); | |
const rate = this._context.new_var( | |
close < ma | |
? ((ma - close) / ma) * 100 * -1 | |
: PineJS.Std.abs(((ma - close) / ma) * 100) | |
); | |
const std = PineJS.Std.stdev(rate, period, this._context); | |
const rate15 = this._context.new_var( | |
close < ma15 | |
? ((ma15 - close) / ma15) * 100 * -1 | |
: PineJS.Std.abs(((ma15 - close) / ma15) * 100) | |
); | |
const std15 = PineJS.Std.stdev(rate15, period, this._context); | |
const rate60 = this._context.new_var( | |
close < ma60 | |
? ((ma60 - close) / ma60) * 100 * -1 | |
: PineJS.Std.abs(((ma60 - close) / ma60) * 100) | |
); | |
const std60 = PineJS.Std.stdev(rate60, period, this._context); | |
self.$emit("sigma5", rate / std); | |
self.$emit("sigma15", rate15 / std15); | |
self.$emit("sigma60", rate60 / std60); | |
self.$emit("ma5", ma); | |
self.$emit("ma15", ma15); | |
self.$emit("ma60", ma60); | |
self.$emit("closePrice", close); | |
let color = rate >= 0 ? 1 : 0; | |
return [rate / std]; | |
}; | |
}, | |
}, | |
{ | |
name: "btc", | |
metainfo: { | |
_metainfoVersion: 40, | |
id: "btc@tv-basicstudies-1", | |
scriptIdPart: "", | |
name: "btc", | |
description: "btc", | |
shortDescription: "btc", | |
is_hidden_study: true, | |
is_price_study: false, | |
isCustomIndicator: true, | |
plots: [ | |
{ | |
id: "plot_0", | |
type: "area", | |
}, | |
// { | |
// id: "plot_1", | |
// type: "colorer", | |
// palette: "palette_0", | |
// target: "plot_0" | |
// } | |
], | |
defaults: { | |
palettes: { | |
palette_0: { | |
colors: { | |
0: { | |
color: "#05d9e8", | |
width: 1, | |
style: 0, | |
transparency: 30, | |
}, | |
1: { | |
color: "#008000", | |
width: 1, | |
style: 0, | |
}, | |
}, | |
}, | |
}, | |
styles: { | |
plot_0: { | |
linestyle: 0, | |
visible: true, | |
linewidth: 1, | |
plottype: 4, | |
transparency: 70, | |
color: "#05d9e8", | |
}, | |
}, | |
// Precision is set to one digit, e.g. 777.7 | |
precision: 0.1, | |
inputs: {}, | |
}, | |
styles: { | |
plot_0: { | |
title: "Equity value", | |
histogramBase: 0, | |
}, | |
}, | |
inputs: [], | |
}, | |
constructor: function () { | |
this.init = function (context, inputCallback) { | |
this._context = context; | |
this._input = inputCallback; | |
let symbol1 = "BTCUSDT"; | |
this._context.new_sym( | |
symbol1, | |
PineJS.Std.period(this._context), | |
PineJS.Std.period(this._context) | |
); | |
}; | |
this.main = function (context, inputCallback) { | |
this._context = context; | |
this._context.select_sym(1); | |
let btcClose = this._context.new_var( | |
PineJS.Std.close(this._context) | |
); | |
this._context.select_sym(0); | |
let close = this._context.new_var( | |
PineJS.Std.close(this._context) | |
); | |
let cor = PineJS.Std.correlation( | |
btcClose, | |
close, | |
9, | |
this._context | |
); | |
return [cor / 1600]; | |
}; | |
}, | |
}, | |
]); | |
}, | |
}; | |
const tvWidget = new widget(widgetOptions); | |
this.tvWidget = tvWidget; | |
tvWidget.onChartReady(() => { | |
tvWidget.chart().createStudy("Moving Average", false, false, [240], { | |
"plot.color.0": "#c20ffc", | |
}); | |
if (this.pairChart) { | |
tvWidget.chart().createStudy("Moving Average", false, false, [720], { | |
"plot.color.0": "#fc0fc0", | |
"plot.linewidth": 2, | |
}); | |
tvWidget.chart().createStudy("Moving Average", false, false, [48], { | |
"plot.color.0": "#60A5FA", | |
"plot.linestyle": "1", | |
"plot.linewidth": 2, | |
}); | |
} | |
if (this.sigmaIndicator) { | |
tvWidget | |
.chart() | |
.createStudy("sigma") | |
.then((data) => { | |
const panes = tvWidget.chart().getPanes(); | |
panes[1].setHeight(100); | |
// panes[2].setHeight(100); | |
const priceScaleApi1 = panes[1].getRightPriceScales()[0]; | |
priceScaleApi1.setVisiblePriceRange({ from: -5, to: 5 }); | |
tvWidget.chart().createShape( | |
{ time: 0, price: -3 }, | |
{ | |
shape: "horizontal_line", | |
ownerStudyId: data, | |
overrides: { | |
linecolor: "#ff2a6d", | |
}, | |
} | |
); | |
tvWidget.chart().createShape( | |
{ time: 0, price: 3 }, | |
{ | |
shape: "horizontal_line", | |
ownerStudyId: data, | |
overrides: { | |
linecolor: "#ff2a6d", | |
}, | |
} | |
); | |
}); | |
} | |
if (this.corIndicator) { | |
tvWidget | |
.chart() | |
.createStudy("btc") | |
.then((data) => { | |
const panes = tvWidget.chart().getPanes(); | |
tvWidget.chart().setAllPanesHeight([400, 200, 200]); | |
// panes[2].setHeight(100); | |
const priceScaleApi1 = panes[1].getRightPriceScales()[0]; | |
priceScaleApi1.setVisiblePriceRange({ from: -5, to: 5 }); | |
const priceScaleApi2 = panes[2].getRightPriceScales()[0]; | |
priceScaleApi2.setVisiblePriceRange({ from: 0, to: 1.5 }); | |
}); | |
} | |
}); | |
}, | |
destroyed() { | |
if (this.tvWidget !== null) { | |
this.tvWidget.remove(); | |
this.tvWidget = null; | |
} | |
}, | |
}; | |
</script> | |
<style scoped> | |
.TVChartContainer { | |
height: 100%; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment