diff --git a/src/shared/charts/tradeChartData.ts b/src/shared/charts/tradeChartData.ts index 9d034e79..d9ea61ee 100644 --- a/src/shared/charts/tradeChartData.ts +++ b/src/shared/charts/tradeChartData.ts @@ -1,6 +1,6 @@ import { formatPercent } from '@/shared/formatters'; import { roundTimeframe } from '@/shared/timemath'; -import { PairHistory, Trade } from '@/types'; +import { Order, PairHistory, Trade } from '@/types'; function buildToolTip(trade: Trade, side: string): string { return `${trade.is_short ? 'Short' : 'Long'} ${side} ${formatPercent( @@ -15,6 +15,11 @@ const ENTRY_SYMB = const EXIT_SYMB = 'path://m 102.20764,19.885384 h 24.1454 v 41.928829 h -24.1454 z m 12.17344,36.423813 8.38665,25.343139 8.38666,25.343134 -16.7315,0.0422 -16.731507,0.0422 8.344847,-25.385386 z'; +const SHORT_COLOR = '#AD00FF'; +const SHORT_ADJUST_COLOR = '#CE3BFF'; +const LONG_COLOR = '#0066FF'; +const LONG_ADJUST_COLOR = '#00A9FF'; + /** Return trade entries for charting */ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { const tradeData: (number | string)[][] = []; @@ -26,43 +31,61 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { // 4: color // 5: label // 6: tooltip - for (let i = 0, len = filteredTrades.length; i < len; i += 1) { const trade: Trade = filteredTrades[i]; if ( trade.open_timestamp >= dataset.data_start_ts && trade.open_timestamp <= dataset.data_stop_ts ) { - // Trade entry - tradeData.push([ - roundTimeframe(dataset.timeframe_ms ?? 0, trade.open_timestamp), - trade.open_rate, - ENTRY_SYMB, - trade.is_short ? 180 : 0, - // (trade.profit_abs ?? 0) > 0 ? '#31e04b' : '#fc0505', - trade.is_short ? '#AD00FF' : '#0066FF', - '', - // trade.profit_abs, - buildToolTip(trade, 'entry'), - ]); - } - if ( - trade.close_timestamp !== undefined && - trade.close_timestamp <= dataset.data_stop_ts && - trade.close_timestamp > dataset.data_start_ts - ) { - if (trade.close_date !== undefined && trade.close_rate !== undefined) { - // Trade exit - tradeData.push([ - roundTimeframe(dataset.timeframe_ms ?? 0, trade.close_timestamp), - trade.close_rate, - EXIT_SYMB, - trade.is_short ? 180 : 0, - trade.is_short ? '#AD00FF' : '#0066FF', - // (trade.profit_abs ?? 0) > 0 ? '#31e04b' : '#fc0505', - formatPercent(trade.profit_ratio, 2), - buildToolTip(trade, 'exit'), - ]); + if (trade.orders) { + for (let i = 0; i < trade.orders.length; i++) { + const order: Order = trade.orders[i]; + if (order.order_filled_timestamp) { + // Trade entry + if (i === 0) { + tradeData.push([ + roundTimeframe(dataset.timeframe_ms ?? 0, trade.open_timestamp), + order.safe_price, + ENTRY_SYMB, + order.ft_order_side == 'sell' ? 180 : 0, + trade.is_short ? SHORT_COLOR : LONG_COLOR, + trade.is_short ? 'Short' : 'Long', + buildToolTip(trade, 'entry'), + ]); + // Trade exit + } else if (i === trade.orders.length - 1 && trade.close_timestamp) { + if ( + trade.close_timestamp <= dataset.data_stop_ts && + trade.close_timestamp > dataset.data_start_ts && + trade.close_date !== undefined && + trade.close_rate !== undefined + ) { + tradeData.push([ + roundTimeframe(dataset.timeframe_ms ?? 0, trade.close_timestamp), + trade.close_rate, + EXIT_SYMB, + trade.is_short ? 180 : 0, + trade.is_short ? SHORT_COLOR : LONG_COLOR, + // (trade.profit_abs ?? 0) > 0 ? '#31e04b' : '#fc0505', + formatPercent(trade.profit_ratio, 2), + buildToolTip(trade, 'exit'), + ]); + } + } + // Position adjustment + else { + tradeData.push([ + roundTimeframe(dataset.timeframe_ms ?? 0, order.order_filled_timestamp), + order.safe_price, + ENTRY_SYMB, + order.ft_order_side == 'sell' ? 180 : 0, + trade.is_short ? SHORT_COLOR : LONG_COLOR, + '', + buildToolTip(trade, 'adjustment'), + ]); + } + } + } } } }