rsi 추가

This commit is contained in:
2025-08-24 22:00:11 +09:00
parent 7cf6f367ea
commit f5059ed0ce
8 changed files with 404 additions and 34 deletions

View File

@@ -10,7 +10,9 @@ import { ref } from 'vue';
*/ */
import LWChart from './components/LWChart.vue'; import LWChart from './components/LWChart.vue';
import {getCandleList} from '/@src/utils/api' import {getCandleList} from '/@src/utils/api'
import {calculateMACD, calculateEMA, calculateBollingerBands} from "./utils/meter.js"; import {calculateMACD, calculateEMA, calculateBollingerBands, calculateRSI} from "./utils/meter.js";
import {entrySignals} from "./utils/cro.js";
import {swingSignal} from "./utils/sig.js";
/** /**
* Generates sample data for the lightweight chart * Generates sample data for the lightweight chart
* @param {Boolean} ohlc Whether generated dat should include open, high, low, and close values * @param {Boolean} ohlc Whether generated dat should include open, high, low, and close values
@@ -21,7 +23,8 @@ const lazyLock = ref(false)
const positionData = ref('') const positionData = ref('')
const contract = ref('BTC_USDT') const contract = ref('BTC_USDT')
const time = ref('15m') /* Interval : "10s", "1m", "5m", "15m", "30m", "1h", "4h", "8h", "1d", "7d"*/
const time = ref('1h')
const chartOptions = ref({ const chartOptions = ref({
layout: { layout: {
textColor: 'black', textColor: 'black',
@@ -42,6 +45,7 @@ const candleTick = ref([])
const ema = ref([]) const ema = ref([])
const macd = ref({}) const macd = ref({})
const bb = ref({}) const bb = ref({})
const rsi = ref({})
const selectCoins = [ const selectCoins = [
{ title: 'BTC_USDT'}, { title: 'BTC_USDT'},
@@ -87,17 +91,20 @@ const candleOptions = ref({
const macdLineOptions = ref({ const macdLineOptions = ref({
lineWidth: 2, lineWidth: 2,
color: '#FFBAB5' color: '#FFBAB5',
title: 'MACD',
}); });
const macdSignalOptions = ref({ const macdSignalOptions = ref({
lineWidth: 2, lineWidth: 2,
color: '#AD81FF' color: '#AD81FF',
title: 'SIGNAL',
}); });
const macdHistogramOptions = ref({ const macdHistogramOptions = ref({
lineWidth: 2, lineWidth: 2,
color: '#27FFE6' color: '#27FFE6',
title: 'HISTOGRAM',
}); });
const upperBbOptions = ref({ const upperBbOptions = ref({
@@ -121,6 +128,12 @@ const lowerBbOptions = ref({
title: 'LowerBB', title: 'LowerBB',
}) })
const rsiLineOptions = ref({
lineWidth: 2,
color: '#AD81FF',
title: 'RSI',
});
const chartType = ref('candlestick'); const chartType = ref('candlestick');
const lwChart = ref(); const lwChart = ref();
@@ -130,14 +143,16 @@ onMounted(() => {
}) })
const init = (cont, ti) => { const init = (cont, ti) => {
socket = new WebSocket("ws://127.0.0.1:8765"); socket = new WebSocket("wss://fx-ws.gateio.ws/v4/ws/usdt");
const dt = new Date() const dt = new Date()
getCandleList(cont, ti, Math.round(dt.getTime()/1000)).then(data => { getCandleList(cont, ti, Math.round(dt.getTime()/1000)).then(data => {
ema.value = calculateEMA(data, 20) ema.value = calculateEMA(data, 20)
macd.value = calculateMACD(data) macd.value = calculateMACD(data)
bb.value = calculateBollingerBands(data) bb.value = calculateBollingerBands(data)
rsi.value = calculateRSI(data)
// console.log(swingSignal(data))
// console.table(entrySignals(data))
candleTick.value = data candleTick.value = data
console.log(bb.value)
}) })
candleSocket(cont, ti) candleSocket(cont, ti)
@@ -145,6 +160,7 @@ const init = (cont, ti) => {
const distroy = (cont) => { const distroy = (cont) => {
candleTick.value = [] candleTick.value = []
socket.close()
} }
const lazyLoad = async (ti) => { const lazyLoad = async (ti) => {
@@ -154,6 +170,7 @@ const lazyLoad = async (ti) => {
ema.value = calculateEMA(data, 20) ema.value = calculateEMA(data, 20)
macd.value = calculateMACD(data) macd.value = calculateMACD(data)
bb.value = calculateBollingerBands(data) bb.value = calculateBollingerBands(data)
rsi.value = calculateRSI(data)
setTimeout(() => {lazyLock.value = false}, 3000) setTimeout(() => {lazyLock.value = false}, 3000)
}) })
@@ -161,12 +178,15 @@ const lazyLoad = async (ti) => {
const candleSocket = (cont, ti) => { const candleSocket = (cont, ti) => {
socket.addEventListener('open', (event) => { socket.addEventListener('open', (event) => {
socket.send(JSON.stringify({"type":"subscribe", "channel": cont, "time": ti})) // socket.send(JSON.stringify({"type":"subscribe", "channel": cont, "time": ti}))
console.log(cont, ti)
socket.send(JSON.stringify({"time" : curToUnix(), "channel" : "futures.candlesticks","event": "subscribe", "payload" : [ti, cont]}))
}) })
socket.addEventListener('message', (message) => { socket.addEventListener('message', (message) => {
const msg = JSON.parse(message.data) const msg = JSON.parse(message.data)
const item = JSON.parse(msg.msg) if(msg.event === 'update') {
const item = msg.result[0]
const ticks = candleTick.value const ticks = candleTick.value
if(item.t === ticks[ticks.length - 1].t) { if(item.t === ticks[ticks.length - 1].t) {
@@ -180,7 +200,12 @@ const candleSocket = (cont, ti) => {
ema.value = calculateEMA(ticks, 20) ema.value = calculateEMA(ticks, 20)
macd.value = calculateMACD(ticks) macd.value = calculateMACD(ticks)
bb.value = calculateBollingerBands(ticks) bb.value = calculateBollingerBands(ticks)
rsi.value = calculateRSI(ticks)
// console.table(entrySignals(ticks))
console.log(swingSignal(ticks))
lazyLock.value = false lazyLock.value = false
}
}) })
} }
@@ -233,23 +258,21 @@ const colorsTypeMap = {
const mouseMove = (data) => { const mouseMove = (data) => {
positionData.value = ` positionData.value = `
<span style="color:red; padding-right:3px;">O</span>${data.open} <span style="color:red; padding-right:3px;">O</span>${data == null ? 0 : data.open}
<span style="color:red; padding-left:5px; padding-right:3px;">C</span>${data.close} <span style="color:red; padding-left:5px; padding-right:3px;">C</span>${data == null ? 0 : data.close}
<span style="color:red; padding-left:5px; padding-right:3px;">L</span>${data.low} <span style="color:red; padding-left:5px; padding-right:3px;">L</span>${data == null ? 0 : data.low}
<span style="color:red; padding-left:5px; padding-right:3px;">H</span>${data.high} <span style="color:red; padding-left:5px; padding-right:3px;">H</span>${data == null ? 0 : data.high}
<span style="color:red; padding-left:5px; padding-right:3px;">T</span>${epochToString(data.time*1000)} <span style="color:red; padding-left:5px; padding-right:3px;">T</span>${data == null ? 0 : epochToString(data.time*1000)}
`; `;
} }
watch(contract, newVal => { watch(contract, newVal => {
distroy() distroy()
console.log(newVal);
init(newVal, time.value) init(newVal, time.value)
}) })
watch(time, newVal => { watch(time, newVal => {
distroy() distroy()
console.log(newVal);
init(contract.value, newVal) init(contract.value, newVal)
}) })
@@ -303,6 +326,7 @@ watch(time, newVal => {
:ema="ema" :ema="ema"
:macd="macd" :macd="macd"
:bb="bb" :bb="bb"
:rsi="rsi"
:autosize="true" :autosize="true"
:chart-options="chartOptions" :chart-options="chartOptions"
:ema-options="emaLineOptions" :ema-options="emaLineOptions"
@@ -313,6 +337,7 @@ watch(time, newVal => {
:lower-bb-options="lowerBbOptions" :lower-bb-options="lowerBbOptions"
:middle-bb-options="middleBbOptions" :middle-bb-options="middleBbOptions"
:upper-bb-options="upperBbOptions" :upper-bb-options="upperBbOptions"
:rsi-line-options="rsiLineOptions"
:lazyLock="lazyLock" :lazyLock="lazyLock"
@lazyLoad="lazyLoad" @lazyLoad="lazyLoad"
@mouseMove="mouseMove" @mouseMove="mouseMove"

View File

@@ -36,6 +36,9 @@ const props = defineProps({
bb: { bb: {
type: Object, type: Object,
}, },
rsi: {
type: Object,
},
autosize: { autosize: {
default: true, default: true,
type: Boolean, type: Boolean,
@@ -58,6 +61,9 @@ const props = defineProps({
macdHistogramOptions: { macdHistogramOptions: {
type: Object, type: Object,
}, },
rsiLineOptions: {
type: Object,
},
upperBbOptions: { upperBbOptions: {
type: Object, type: Object,
}, },
@@ -108,13 +114,15 @@ let chart;
let macdLine; let macdLine;
let macdSignalLine; let macdSignalLine;
let macdHistogram; let macdHistogram;
let mainPane;
let macdPane; let macdPane;
let rsiPane;
let upperBb; let upperBb;
let middleBb; let middleBb;
let lowerBb; let lowerBb;
let rsiLine;
const chartContainer = ref(); const chartContainer = ref();
const fitContent = () => { const fitContent = () => {
@@ -160,7 +168,6 @@ const addSeriesAndData = props => {
emaLine = chart.addSeries(seriesDefinition, props.emaOptions) emaLine = chart.addSeries(seriesDefinition, props.emaOptions)
emaLine.setData(props.ema) emaLine.setData(props.ema)
console.log(Object.keys(props.macd).length)
macdLine = macdPane.addSeries(seriesDefinition, props.macdLineOptions) macdLine = macdPane.addSeries(seriesDefinition, props.macdLineOptions)
macdSignalLine = macdPane.addSeries(seriesDefinition, props.macdSignalOptions) macdSignalLine = macdPane.addSeries(seriesDefinition, props.macdSignalOptions)
macdHistogram = macdPane.addSeries(getChartSeriesDefinition('histogram'), props.macdHistogramOptions) macdHistogram = macdPane.addSeries(getChartSeriesDefinition('histogram'), props.macdHistogramOptions)
@@ -178,6 +185,11 @@ const addSeriesAndData = props => {
middleBb.setData(props.bb.m); middleBb.setData(props.bb.m);
lowerBb.setData(props.bb.l); lowerBb.setData(props.bb.l);
} }
rsiLine = rsiPane.addSeries(seriesDefinition, props.rsiLineOptions)
if(Object.keys(props.macd).length) {
rsiLine.setData(props.rsi)
}
// console.log(3) // console.log(3)
}; };
@@ -186,6 +198,8 @@ onMounted(() => {
chart = createChart(chartContainer.value, props.chartOptions); chart = createChart(chartContainer.value, props.chartOptions);
macdPane = chart.addPane(); macdPane = chart.addPane();
macdPane.setStretchFactor(0.5) macdPane.setStretchFactor(0.5)
rsiPane = chart.addPane();
rsiPane.setStretchFactor(0.4)
addSeriesAndData(props); addSeriesAndData(props);
@@ -325,6 +339,15 @@ watch(
} }
); );
watch(
() => props.rsi,
newData => {
if (!rsiLine) return;
rsiLine.setData(props.rsi);
}
);
watch( watch(
() => props.chartOptions, () => props.chartOptions,
newOptions => { newOptions => {

View File

@@ -1,8 +1,8 @@
import {useAxios} from "@vueuse/integrations/useAxios"; import {useAxios} from "@vueuse/integrations/useAxios";
export const getCandleList = (contact:string, time: string, timestamp: number) => { export const getCandleList = (contract:string, time: string, timestamp: number) => {
return new Promise(resolve => { return new Promise(resolve => {
useAxios(`/api/candle/${contact}/${time}/${timestamp}`).then((res) => { useAxios(`/api/v4/futures/usdt/candlesticks?contract=${contract}&interval=${time}&to=${timestamp}&limit=1500`).then((res) => {
resolve(res.data.value) resolve(res.data.value)
}) })
}) })

145
src/utils/cro.ts Normal file
View File

@@ -0,0 +1,145 @@
function mean(arr: any) {
return arr.reduce((a: number, b: any) => a + b, 0) / arr.length;
}
function sum(arr: any) {
return arr.reduce((a: number, b: any) => a + b, 0)
}
function atr(data:any, period: number) {
const trs = [];
for (let i = 1; i < data.length; i++) {
const prev = data[i - 1];
const cur = data[i];
const tr = Math.max(
cur.h - cur.l,
Math.abs(cur.h - prev.c),
Math.abs(cur.l - prev.c)
);
trs.push(tr);
}
const atrArr = [];
for (let i = period - 1; i < trs.length; i++) {
const slice = trs.slice(i - period + 1, i + 1);
atrArr.push(mean(slice));
}
return atrArr;
}
function vwap(data:any, period: number) {
// 일반 VWAP = ∑(typical * volume) / ∑volume
const vwaps = [];
for (let i = period - 1; i < data.length; i++) {
const slice = data.slice(i - period + 1, i + 1);
let num = 0,
den = 0;
slice.forEach((c: any) => {
const typical = (Number(c.h) + Number(c.l) + Number(c.c)) / 3;
num += typical * Number(c.v);
den += Number(c.v);
});
vwaps.push(num / den);
}
return vwaps;
}
function rsi(data: any, period: number) {
const gains = [],
losses = [];
for (let i = 1; i < data.length; i++) {
const diff = Number(data[i].c) - Number(data[i - 1].c);
gains.push(diff > 0 ? diff : 0);
losses.push(diff < 0 ? -diff : 0);
}
const rsiArr = [];
for (let i = period; i < gains.length; i++) {
const avgGain = mean(gains.slice(i - period, i));
const avgLoss = mean(losses.slice(i - period, i));
const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
rsiArr.push(100 - 100 / (1 + rs));
}
return rsiArr;
}
function bb(data: any, period: number, mult = 2) {
const up = [],
mid = [],
low = [];
for (let i = period - 1; i < data.length; i++) {
const slice = data.slice(i - period + 1, i + 1).map((x: any) => Number(x.c));
const m = mean(slice);
const stdev =
Math.sqrt(sum(slice.map((p: any) => Math.pow(p - m, 2))) / period) || 0;
mid.push(m);
up.push(m + mult * stdev);
low.push(m - mult * stdev);
}
return { upper: up, middle: mid, lower: low };
}
function calculateCRO(data: any) {
const n = data.length;
const vw = vwap(data, 20);
const mom = [];
for (let i = 20; i < n; i++) {
mom.push(data[i].c / data[i - 20].c - 1);
}
const divergences = [];
for (let i = 0; i < mom.length; i++) {
const idx20 = 19 + i;
const v = Math.abs(mom[i]) - Math.abs((vw[i] - data[idx20].c) / data[idx20].c);
divergences.push(v);
}
const atr14 = atr(data, 14);
const atr63 = atr(data, 63);
const vsr = [];
for (let i = 0; i < atr14.length; i++) {
const a63 = atr63[i] || 1;
vsr.push(atr14[i] / a63);
}
// offset 맞추기
const offset = 63 - 1;
const cro = [];
for (let i = offset; i < n; i++) {
const di = i - offset;
const d = divergences[di] || 0;
const v = vsr[di - (63 - 14)] || 1;
let val = 0;
if (d >= 0.015 && v >= 1.2) val = 1;
if (d <= -0.015 && v >= 1.2) val = -1;
cro.push({ t: data[i].t, cro: val, divergence: d, vsr: v });
}
return cro;
}
function entrySignals(data: any) {
const cro = calculateCRO(data);
const rsi14 = rsi(data, 14);
const bbands = bb(data, 20, 2);
const signals = [];
const croOffset = data.length - cro.length;
const rsiOffset = data.length - rsi14.length;
const bbOffset = data.length - bbands.lower.length;
for (let i = 0; i < cro.length; i++) {
const idx = croOffset + i;
const cur = data[idx];
const r = rsi14[i - (croOffset - rsiOffset)];
const bbl = bbands.lower[i - (croOffset - bbOffset)];
const bbu = bbands.upper[i - (croOffset - bbOffset)];
if (cro[i].cro === 1 && r <= 35 && cur.c <= bbl) {
signals.push({ t: cro[i].t, side: 'LONG', price: cur.c });
}
if (cro[i].cro === -1 && r >= 65 && cur.c >= bbu) {
signals.push({ t: cro[i].t, side: 'SHORT', price: cur.c });
}
}
return signals;
}
export {entrySignals}

View File

@@ -24,6 +24,33 @@ function calculateBollingerBands(data: any, period = 20, stdDevMultiplier = 2) {
return { u, m, l }; return { u, m, l };
} }
function calculateRSI(data: any, period = 14) {
function mean(arr: any) {
return arr.reduce((a: number, b: any) => a + b, 0) / arr.length;
}
const gains = [],
losses = [];
for (let i = 1; i < data.length; i++) {
const diff = Number(data[i].c) - Number(data[i - 1].c);
gains.push(diff > 0 ? diff : 0);
losses.push(diff < 0 ? -diff : 0);
}
const rsiArr = [];
for (let i = 0; i < gains.length; i++) {
const avgGain = mean(gains.slice(i - period, i));
const avgLoss = mean(losses.slice(i - period, i));
const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;
if(isNaN(rs)) {
rsiArr.push({time: data[i].t ?? data[i].time, value: 0});
} else {
rsiArr.push({time: data[i].t ?? data[i].time, value: 100 - 100 / (1 + rs)});
}
}
return rsiArr;
}
function calculateEMA(data:any, period:any) { function calculateEMA(data:any, period:any) {
const ema = []; const ema = [];
const k = 2 / (period + 1); const k = 2 / (period + 1);
@@ -73,4 +100,4 @@ function calculateMACD(data: any, fastPeriod = 12, slowPeriod = 26, signalPeriod
}; };
} }
export { calculateBollingerBands, calculateEMA, calculateMACD }; export { calculateBollingerBands, calculateEMA, calculateMACD, calculateRSI };

146
src/utils/sig.ts Normal file
View File

@@ -0,0 +1,146 @@
// ---------- 헬퍼 ----------
const mean = (arr: any) => arr.reduce((a:number, b:number) => a + b, 0) / arr.length;
const sum = (arr: any) => arr.reduce((a:number, b:number) => a + b, 0);
// ---------- 기술지표 ----------
const atr = (data: any, period: number) => {
const trs = [];
for (let i = 1; i < data.length; i++) {
const prev = data[i-1], cur = data[i];
const tr = Math.max(Number(cur.h)-Number(cur.l), Math.abs(Number(cur.h)-Number(prev.c)), Math.abs(Number(cur.l)-Number(prev.c)));
trs.push(tr);
}
const res = [];
for (let i=period-1;i<trs.length;i++){
res.push(mean(trs.slice(i-period+1,i+1)));
}
return res;
};
const rsi = (data: any, period: number) => {
const gains=[], losses=[];
for(let i=1;i<data.length;i++){
const d = Number(data[i].c) - Number(data[i-1].c);
gains.push(d>0?d:0); losses.push(d<0?-d:0);
}
const res=[];
for(let i=period;i<gains.length;i++){
const ag=mean(gains.slice(i-period,i));
const al=mean(losses.slice(i-period,i));
const rs = al===0?100:ag/al;
res.push(100-100/(1+rs));
}
return res;
};
const bb = (data: any, period: number, mult=2) => {
const up=[], mid=[], low=[];
for(let i=period-1;i<data.length;i++){
const slice=data.slice(i-period+1,i+1).map((x: any)=>Number(x.c));
const m=mean(slice);
const stdev=Math.sqrt(sum(slice.map((p: number)=>(p-m)**2))/period);
mid.push(m); up.push(m+mult*stdev); low.push(m-mult*stdev);
}
return {upper:up, middle:mid, lower:low};
};
const macd = (data: any) => {
const fast = 12, slow = 26, sig = 9;
// 1) EMA 헬퍼
const ema = (arr: any, len: number) => {
const k = 2 / (len + 1);
const out = [arr[0]];
for (let i = 1; i < arr.length; i++) {
out.push(arr[i] * k + out[i - 1] * (1 - k));
}
return out;
};
// 2) MACD-Signal-Histogram
const closes = data.map((x: any) => Number(x.c));
const emaFast = ema(closes, fast);
const emaSlow = ema(closes, slow);
// 두 EMA 길이 맞추기 (slow 기준으로 잘라내기)
const alignedFast = emaFast.slice(slow - 1);
const alignedSlow = emaSlow.slice(slow - 1);
const macdLine = alignedFast.map((v, i) => v - alignedSlow[i]);
const signalLine = ema(macdLine, sig);
const hist = macdLine.slice(sig - 1)
.map((v, i) => v - signalLine[i]);
return { macdLine, signalLine, hist };
};
// ---------- 시그널 ----------
// const swingSignal = (data: any) => {
// const macdHist = macd(data).hist;
// const rsi14 = rsi(data, 14);
// const bbands = bb(data, 20, 2);
//
// const offsetMacd = data.length - macdHist.length;
// const offsetRsi = data.length - rsi14.length;
// const offsetBb = data.length - bbands.lower.length;
//
// const latest = data.length-1;
// const hist = macdHist[latest-offsetMacd];
// const prev = macdHist[latest-offsetMacd-1];
// const rsiVal = rsi14[latest-offsetRsi];
// const close = Number(data[latest].c);
// const bbl = bbands.lower[latest-offsetBb];
// const bbu = bbands.upper[latest-offsetBb];
// console.log(prev, hist, rsiVal, close, bbl)
// if(prev<0 && hist>=0 && rsiVal<=35 && close<=bbl) return 'LONG';
// if(prev>0 && hist<=0 && rsiVal>=65 && close>=bbu) return 'SHORT';
// return 'HOLD';
// };
const swingSignal = (data: any) => {
// 1) 기존 지표
const macdHist = macd(data).hist;
const rsi14 = rsi(data, 14);
const bbands = bb(data, 20, 2);
// 2) ATR 변동성 필터
const atr14 = atr(data, 14);
const atr63 = atr(data, 63);
// const offsetAtr = data.length - atr14.length;
const currentATR14 = atr14[atr14.length - 1];
const currentATR63 = atr63[atr63.length - 1] || 1;
// 변동성 급등 조건
const volatilityBreak = currentATR14 > currentATR63 * 1.2;
// 3) 기존 offset 계산
const offsetMacd = data.length - macdHist.length;
const offsetRsi = data.length - rsi14.length;
const offsetBb = data.length - bbands.lower.length;
const latest = data.length - 1;
const hist = macdHist[latest - offsetMacd];
const prev = macdHist[latest - offsetMacd - 1];
const rsiVal = rsi14[latest - offsetRsi];
const close = Number(data[latest].c);
const bbl = bbands.lower[latest - offsetBb];
const bbu = bbands.upper[latest - offsetBb];
console.log(volatilityBreak, prev, hist, rsiVal, close, bbl)
// 4) 최종 조건
if (volatilityBreak &&
prev < 0 && hist >= 0 &&
rsiVal <= 35 && close <= bbl)
return 'LONG';
if (volatilityBreak &&
prev > 0 && hist <= 0 &&
rsiVal >= 65 && close >= bbu)
return 'SHORT';
return 'HOLD';
};
export {swingSignal}

4
types/imports.d.ts vendored
View File

@@ -10,8 +10,10 @@ declare global {
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
const calculateBollingerBands: typeof import('../src/utils/meter')['calculateBollingerBands'] const calculateBollingerBands: typeof import('../src/utils/meter')['calculateBollingerBands']
const calculateCRO: typeof import('../src/utils/meter')['calculateCRO']
const calculateEMA: typeof import('../src/utils/meter')['calculateEMA'] const calculateEMA: typeof import('../src/utils/meter')['calculateEMA']
const calculateMACD: typeof import('../src/utils/meter')['calculateMACD'] const calculateMACD: typeof import('../src/utils/meter')['calculateMACD']
const calculateRSI: typeof import('../src/utils/meter')['calculateRSI']
const computed: typeof import('vue')['computed'] const computed: typeof import('vue')['computed']
const computedAsync: typeof import('@vueuse/core')['computedAsync'] const computedAsync: typeof import('@vueuse/core')['computedAsync']
const computedEager: typeof import('@vueuse/core')['computedEager'] const computedEager: typeof import('@vueuse/core')['computedEager']
@@ -36,6 +38,7 @@ declare global {
const defineComponent: typeof import('vue')['defineComponent'] const defineComponent: typeof import('vue')['defineComponent']
const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
const effectScope: typeof import('vue')['effectScope'] const effectScope: typeof import('vue')['effectScope']
const entrySignals: typeof import('../src/utils/cro')['entrySignals']
const extendRef: typeof import('@vueuse/core')['extendRef'] const extendRef: typeof import('@vueuse/core')['extendRef']
const getCandleList: typeof import('../src/utils/api')['getCandleList'] const getCandleList: typeof import('../src/utils/api')['getCandleList']
const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentInstance: typeof import('vue')['getCurrentInstance']
@@ -95,6 +98,7 @@ declare global {
const shallowReactive: typeof import('vue')['shallowReactive'] const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly'] const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef'] const shallowRef: typeof import('vue')['shallowRef']
const swingSignal: typeof import('../src/utils/sig')['swingSignal']
const syncRef: typeof import('@vueuse/core')['syncRef'] const syncRef: typeof import('@vueuse/core')['syncRef']
const syncRefs: typeof import('@vueuse/core')['syncRefs'] const syncRefs: typeof import('@vueuse/core')['syncRefs']
const templateRef: typeof import('@vueuse/core')['templateRef'] const templateRef: typeof import('@vueuse/core')['templateRef']

View File

@@ -44,8 +44,8 @@ export default defineConfig(({ isSsrBuild }) => ({
host: '0.0.0.0', host: '0.0.0.0',
port: 3000, port: 3000,
proxy: { proxy: {
'/api': { '/api/v4': {
target: 'http://localhost:7010', target: 'https://fx-api.gateio.ws',
changeOrigin: true, changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api/, ''), // rewrite: (path) => path.replace(/^\/api/, ''),
}, },