Fix: Add symbol format conversion for A-Share/HK stocks in TradingView widgets
This commit is contained in:
parent
10e8c1a261
commit
294d0b98e9
|
|
@ -12,9 +12,11 @@ import {
|
||||||
import { auth } from '@/lib/better-auth/auth';
|
import { auth } from '@/lib/better-auth/auth';
|
||||||
import { headers } from 'next/headers';
|
import { headers } from 'next/headers';
|
||||||
import { isStockInWatchlist } from '@/lib/actions/watchlist.actions';
|
import { isStockInWatchlist } from '@/lib/actions/watchlist.actions';
|
||||||
|
import { formatSymbolForTradingView } from '@/lib/utils';
|
||||||
|
|
||||||
export default async function StockDetails({ params }: StockDetailsPageProps) {
|
export default async function StockDetails({ params }: StockDetailsPageProps) {
|
||||||
const { symbol } = await params;
|
const { symbol } = await params;
|
||||||
|
const tvSymbol = formatSymbolForTradingView(symbol);
|
||||||
const scriptUrl = `https://s3.tradingview.com/external-embedding/embed-widget-`;
|
const scriptUrl = `https://s3.tradingview.com/external-embedding/embed-widget-`;
|
||||||
|
|
||||||
const session = await auth.api.getSession({
|
const session = await auth.api.getSession({
|
||||||
|
|
@ -30,13 +32,13 @@ export default async function StockDetails({ params }: StockDetailsPageProps) {
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
scriptUrl={`${scriptUrl}symbol-info.js`}
|
scriptUrl={`${scriptUrl}symbol-info.js`}
|
||||||
config={SYMBOL_INFO_WIDGET_CONFIG(symbol)}
|
config={SYMBOL_INFO_WIDGET_CONFIG(tvSymbol)}
|
||||||
height={170}
|
height={170}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
scriptUrl={`${scriptUrl}advanced-chart.js`}
|
scriptUrl={`${scriptUrl}advanced-chart.js`}
|
||||||
config={CANDLE_CHART_WIDGET_CONFIG(symbol)}
|
config={CANDLE_CHART_WIDGET_CONFIG(tvSymbol)}
|
||||||
className="custom-chart"
|
className="custom-chart"
|
||||||
height={600}
|
height={600}
|
||||||
allowExpand={true}
|
allowExpand={true}
|
||||||
|
|
@ -44,7 +46,7 @@ export default async function StockDetails({ params }: StockDetailsPageProps) {
|
||||||
|
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
scriptUrl={`${scriptUrl}advanced-chart.js`}
|
scriptUrl={`${scriptUrl}advanced-chart.js`}
|
||||||
config={BASELINE_WIDGET_CONFIG(symbol)}
|
config={BASELINE_WIDGET_CONFIG(tvSymbol)}
|
||||||
className="custom-chart"
|
className="custom-chart"
|
||||||
height={600}
|
height={600}
|
||||||
allowExpand={true}
|
allowExpand={true}
|
||||||
|
|
@ -64,19 +66,19 @@ export default async function StockDetails({ params }: StockDetailsPageProps) {
|
||||||
|
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
scriptUrl={`${scriptUrl}technical-analysis.js`}
|
scriptUrl={`${scriptUrl}technical-analysis.js`}
|
||||||
config={TECHNICAL_ANALYSIS_WIDGET_CONFIG(symbol)}
|
config={TECHNICAL_ANALYSIS_WIDGET_CONFIG(tvSymbol)}
|
||||||
height={400}
|
height={400}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
scriptUrl={`${scriptUrl}company-profile.js`}
|
scriptUrl={`${scriptUrl}company-profile.js`}
|
||||||
config={COMPANY_PROFILE_WIDGET_CONFIG(symbol)}
|
config={COMPANY_PROFILE_WIDGET_CONFIG(tvSymbol)}
|
||||||
height={440}
|
height={440}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TradingViewWidget
|
<TradingViewWidget
|
||||||
scriptUrl={`${scriptUrl}financials.js`}
|
scriptUrl={`${scriptUrl}financials.js`}
|
||||||
config={COMPANY_FINANCIALS_WIDGET_CONFIG(symbol)}
|
config={COMPANY_FINANCIALS_WIDGET_CONFIG(tvSymbol)}
|
||||||
height={800}
|
height={800}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import React, { useEffect, useRef, memo } from 'react';
|
import React, { useEffect, useRef, memo } from 'react';
|
||||||
import { useTheme } from "next-themes";
|
import { useTheme } from "next-themes";
|
||||||
|
import { formatSymbolForTradingView } from '@/lib/utils';
|
||||||
|
|
||||||
interface TradingViewWatchlistProps {
|
interface TradingViewWatchlistProps {
|
||||||
symbols: string[];
|
symbols: string[];
|
||||||
|
|
@ -26,7 +27,7 @@ function TradingViewWatchlist({ symbols }: TradingViewWatchlistProps) {
|
||||||
// Since we don't have exchange data easily, we'll try raw symbol.
|
// Since we don't have exchange data easily, we'll try raw symbol.
|
||||||
// Ideally we'd prefix "NASDAQ:" or "NYSE:" but let's test without first.
|
// Ideally we'd prefix "NASDAQ:" or "NYSE:" but let's test without first.
|
||||||
const symbolList = symbols.map(s => ({
|
const symbolList = symbols.map(s => ({
|
||||||
name: s,
|
name: formatSymbolForTradingView(s),
|
||||||
displayName: s
|
displayName: s
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
24
lib/utils.ts
24
lib/utils.ts
|
|
@ -152,4 +152,26 @@ export const getFormattedTodayDate = () => new Date().toLocaleDateString('en-US'
|
||||||
month: 'long',
|
month: 'long',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
timeZone: 'UTC',
|
timeZone: 'UTC',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function formatSymbolForTradingView(symbol: string): string {
|
||||||
|
if (!symbol) return symbol;
|
||||||
|
const upperSymbol = symbol.toUpperCase();
|
||||||
|
|
||||||
|
// Shanghai
|
||||||
|
if (upperSymbol.endsWith('.SS')) {
|
||||||
|
return `SSE:${upperSymbol.replace('.SS', '')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shenzhen
|
||||||
|
if (upperSymbol.endsWith('.SZ')) {
|
||||||
|
return `SZSE:${upperSymbol.replace('.SZ', '')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hong Kong
|
||||||
|
if (upperSymbol.endsWith('.HK')) {
|
||||||
|
return `HKEX:${upperSymbol.replace('.HK', '')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return upperSymbol;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue