indicator integration
This commit is contained in:
@@ -3,6 +3,7 @@ import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
||||
import Card from 'primevue/card'
|
||||
import { createTradingViewDatafeed } from '../composables/useTradingViewDatafeed'
|
||||
import { useTradingViewShapes } from '../composables/useTradingViewShapes'
|
||||
import { useTradingViewIndicators } from '../composables/useTradingViewIndicators'
|
||||
import { useChartStore } from '../stores/chart'
|
||||
import type { IChartingLibraryWidget } from '../types/tradingview'
|
||||
|
||||
@@ -12,6 +13,7 @@ let tvWidget: IChartingLibraryWidget | null = null
|
||||
let datafeed: any = null
|
||||
let isUpdatingFromChart = false // Flag to prevent circular updates
|
||||
let shapeCleanup: (() => void) | null = null // Cleanup function for shape sync
|
||||
let indicatorCleanup: (() => void) | null = null // Cleanup function for indicator sync
|
||||
|
||||
onMounted(() => {
|
||||
if (!chartContainer.value) return
|
||||
@@ -39,6 +41,91 @@ onMounted(() => {
|
||||
'symbol_search_hot_key'
|
||||
],
|
||||
enabled_features: ['study_templates'],
|
||||
// Restrict indicators to only those supported by both TA-Lib and TradingView
|
||||
studies_access: {
|
||||
type: 'white',
|
||||
tools: [
|
||||
// Overlap Studies (14)
|
||||
{ name: 'Moving Average' },
|
||||
{ name: 'Moving Average Exponential' },
|
||||
{ name: 'Weighted Moving Average' },
|
||||
{ name: 'DEMA' },
|
||||
{ name: 'TEMA' },
|
||||
{ name: 'Triangular Moving Average' },
|
||||
{ name: 'KAMA' },
|
||||
{ name: 'MESA Adaptive Moving Average' },
|
||||
{ name: 'T3' },
|
||||
{ name: 'Bollinger Bands' },
|
||||
{ name: 'Midpoint' },
|
||||
{ name: 'Midprice' },
|
||||
{ name: 'Parabolic SAR' },
|
||||
{ name: 'Hilbert Transform - Instantaneous Trendline' },
|
||||
// Momentum Indicators (21)
|
||||
{ name: 'Relative Strength Index' },
|
||||
{ name: 'Momentum' },
|
||||
{ name: 'Rate of Change' },
|
||||
{ name: 'TRIX' },
|
||||
{ name: 'Chande Momentum Oscillator' },
|
||||
{ name: 'Directional Movement Index' },
|
||||
{ name: 'Average Directional Movement Index' },
|
||||
{ name: 'Average Directional Movement Index Rating' },
|
||||
{ name: 'Absolute Price Oscillator' },
|
||||
{ name: 'Percentage Price Oscillator' },
|
||||
{ name: 'MACD' },
|
||||
{ name: 'Money Flow Index' },
|
||||
{ name: 'Stochastic' },
|
||||
{ name: 'Stochastic Fast' },
|
||||
{ name: 'Stochastic RSI' },
|
||||
{ name: 'Williams %R' },
|
||||
{ name: 'Commodity Channel Index' },
|
||||
{ name: 'Aroon' },
|
||||
{ name: 'Aroon Oscillator' },
|
||||
{ name: 'Balance Of Power' },
|
||||
{ name: 'Ultimate Oscillator' },
|
||||
// Volume Indicators (3)
|
||||
{ name: 'Chaikin A/D Line' },
|
||||
{ name: 'Chaikin A/D Oscillator' },
|
||||
{ name: 'On Balance Volume' },
|
||||
// Volatility Indicators (3)
|
||||
{ name: 'Average True Range' },
|
||||
{ name: 'Normalized Average True Range' },
|
||||
{ name: 'True Range' },
|
||||
// Price Transform (4)
|
||||
{ name: 'Average Price' },
|
||||
{ name: 'Median Price' },
|
||||
{ name: 'Typical Price' },
|
||||
{ name: 'Weighted Close Price' },
|
||||
// Cycle Indicators (5)
|
||||
{ name: 'Hilbert Transform - Dominant Cycle Period' },
|
||||
{ name: 'Hilbert Transform - Dominant Cycle Phase' },
|
||||
{ name: 'Hilbert Transform - Phasor Components' },
|
||||
{ name: 'Hilbert Transform - SineWave' },
|
||||
{ name: 'Hilbert Transform - Trend vs Cycle Mode' },
|
||||
// Statistic Functions (9)
|
||||
{ name: 'Beta' },
|
||||
{ name: 'Pearson\'s Correlation Coefficient' },
|
||||
{ name: 'Linear Regression' },
|
||||
{ name: 'Linear Regression Angle' },
|
||||
{ name: 'Linear Regression Intercept' },
|
||||
{ name: 'Linear Regression Slope' },
|
||||
{ name: 'Standard Deviation' },
|
||||
{ name: 'Time Series Forecast' },
|
||||
{ name: 'Variance' },
|
||||
// Custom Indicators (12)
|
||||
{ name: 'VWAP' },
|
||||
{ name: 'VWMA' },
|
||||
{ name: 'Hull Moving Average' },
|
||||
{ name: 'SuperTrend' },
|
||||
{ name: 'Donchian Channels' },
|
||||
{ name: 'Keltner Channels' },
|
||||
{ name: 'Chaikin Money Flow' },
|
||||
{ name: 'Vortex Indicator' },
|
||||
{ name: 'Awesome Oscillator' },
|
||||
{ name: 'Accelerator Oscillator' },
|
||||
{ name: 'Choppiness Index' },
|
||||
{ name: 'Mass Index' }
|
||||
]
|
||||
},
|
||||
fullscreen: false,
|
||||
autosize: true,
|
||||
theme: 'Dark',
|
||||
@@ -54,6 +141,7 @@ onMounted(() => {
|
||||
// Setup shape synchronization
|
||||
if (tvWidget) {
|
||||
shapeCleanup = useTradingViewShapes(tvWidget)
|
||||
indicatorCleanup = useTradingViewIndicators(tvWidget)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
@@ -177,6 +265,12 @@ onBeforeUnmount(() => {
|
||||
shapeCleanup = null
|
||||
}
|
||||
|
||||
// Cleanup indicator synchronization
|
||||
if (indicatorCleanup) {
|
||||
indicatorCleanup()
|
||||
indicatorCleanup = null
|
||||
}
|
||||
|
||||
if (tvWidget) {
|
||||
tvWidget.remove()
|
||||
tvWidget = null
|
||||
|
||||
@@ -21,6 +21,7 @@ const newPassword = ref('')
|
||||
const confirmNewPassword = ref('')
|
||||
const isLoading = ref(false)
|
||||
const isChangingPassword = ref(false)
|
||||
const passwordInput = ref<InstanceType<typeof Password> | null>(null)
|
||||
|
||||
const canSubmit = computed(() => {
|
||||
if (!password.value || isLoading.value) return false
|
||||
@@ -69,9 +70,11 @@ const togglePasswordChange = () => {
|
||||
|
||||
onMounted(() => {
|
||||
// Focus on the password input when component mounts
|
||||
const passwordInput = document.querySelector('#password input') as HTMLInputElement
|
||||
if (passwordInput) {
|
||||
passwordInput.focus()
|
||||
if (passwordInput.value?.$el) {
|
||||
const inputElement = passwordInput.value.$el.querySelector('input') as HTMLInputElement
|
||||
if (inputElement) {
|
||||
inputElement.focus()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -105,6 +108,7 @@ onMounted(() => {
|
||||
<div class="form-field">
|
||||
<label for="password">{{ isChangingPassword ? 'Current Password' : 'Password' }}</label>
|
||||
<Password
|
||||
ref="passwordInput"
|
||||
id="password"
|
||||
v-model="password"
|
||||
:feedback="needsConfirmation"
|
||||
|
||||
Reference in New Issue
Block a user