From de92ac94597b6f97e2e8e5930b1287d4c4e0495c Mon Sep 17 00:00:00 2001 From: Tako Date: Wed, 23 Nov 2022 16:02:51 +0000 Subject: [PATCH 1/4] show orders on chart --- src/shared/charts/tradeChartData.ts | 87 ++++++++++++++++++----------- 1 file changed, 55 insertions(+), 32 deletions(-) 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'), + ]); + } + } + } } } } From 561db06b39caafe21f3fd7186c8e5d1d46e54603 Mon Sep 17 00:00:00 2001 From: Tako Date: Thu, 24 Nov 2022 18:10:02 +0000 Subject: [PATCH 2/4] make sure order is within dataset bounds --- src/shared/charts/tradeChartData.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/shared/charts/tradeChartData.ts b/src/shared/charts/tradeChartData.ts index d9ea61ee..9e2fde35 100644 --- a/src/shared/charts/tradeChartData.ts +++ b/src/shared/charts/tradeChartData.ts @@ -40,7 +40,11 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { if (trade.orders) { for (let i = 0; i < trade.orders.length; i++) { const order: Order = trade.orders[i]; - if (order.order_filled_timestamp) { + if ( + order.order_filled_timestamp && + order.order_filled_timestamp <= dataset.data_stop_ts && + order.order_filled_timestamp > dataset.data_start_ts + ) { // Trade entry if (i === 0) { tradeData.push([ From b21f7d9d0751385e1dc695e62d8121a7469176b4 Mon Sep 17 00:00:00 2001 From: Tako Date: Fri, 25 Nov 2022 19:07:07 +0000 Subject: [PATCH 3/4] tweaked symbols --- src/shared/charts/tradeChartData.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/shared/charts/tradeChartData.ts b/src/shared/charts/tradeChartData.ts index 9e2fde35..caf2eef1 100644 --- a/src/shared/charts/tradeChartData.ts +++ b/src/shared/charts/tradeChartData.ts @@ -10,15 +10,15 @@ function buildToolTip(trade: Trade, side: string): string { // const ENTRY_SYMB = 'circle'; // const EXIT_SYMB = 'rect'; -const ENTRY_SYMB = +const ADJUSTMENT_SYMBOL = 'path://m 52.444161,104.1909 8.386653,25.34314 8.386651,25.34313 -16.731501,0.0422 -16.731501,0.0422 8.344848,-25.38539 z m 0.08656,-48.368126 8.386652,25.343139 8.386652,25.343137 -16.731501,0.0422 -16.731502,0.0422 8.344848,-25.385389 z'; -const EXIT_SYMB = +const OPEN_CLOSE_SYMBOL = '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 SHORT_ADJUST_COLOR = '#CE3BFF'; const LONG_COLOR = '#0066FF'; -const LONG_ADJUST_COLOR = '#00A9FF'; +//const LONG_ADJUST_COLOR = '#00A9FF'; /** Return trade entries for charting */ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { @@ -50,7 +50,7 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { tradeData.push([ roundTimeframe(dataset.timeframe_ms ?? 0, trade.open_timestamp), order.safe_price, - ENTRY_SYMB, + OPEN_CLOSE_SYMBOL, order.ft_order_side == 'sell' ? 180 : 0, trade.is_short ? SHORT_COLOR : LONG_COLOR, trade.is_short ? 'Short' : 'Long', @@ -67,8 +67,8 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { tradeData.push([ roundTimeframe(dataset.timeframe_ms ?? 0, trade.close_timestamp), trade.close_rate, - EXIT_SYMB, - trade.is_short ? 180 : 0, + OPEN_CLOSE_SYMBOL, + trade.is_short ? 0 : 180, trade.is_short ? SHORT_COLOR : LONG_COLOR, // (trade.profit_abs ?? 0) > 0 ? '#31e04b' : '#fc0505', formatPercent(trade.profit_ratio, 2), @@ -81,7 +81,7 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { tradeData.push([ roundTimeframe(dataset.timeframe_ms ?? 0, order.order_filled_timestamp), order.safe_price, - ENTRY_SYMB, + ADJUSTMENT_SYMBOL, order.ft_order_side == 'sell' ? 180 : 0, trade.is_short ? SHORT_COLOR : LONG_COLOR, '', From 445837a471cccc58defadd9d0a17479c44f3e539 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 26 Nov 2022 13:45:14 +0100 Subject: [PATCH 4/4] Improve Adjustment tooltip --- src/shared/charts/tradeChartData.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/shared/charts/tradeChartData.ts b/src/shared/charts/tradeChartData.ts index caf2eef1..4d39d25a 100644 --- a/src/shared/charts/tradeChartData.ts +++ b/src/shared/charts/tradeChartData.ts @@ -1,4 +1,4 @@ -import { formatPercent } from '@/shared/formatters'; +import { formatPercent, formatPriceCurrency } from '@/shared/formatters'; import { roundTimeframe } from '@/shared/timemath'; import { Order, PairHistory, Trade } from '@/types'; @@ -7,6 +7,15 @@ function buildToolTip(trade: Trade, side: string): string { trade.profit_ratio, )} \nEnter-tag: ${trade.enter_tag ?? ''} \nExit-Tag: ${trade.exit_reason ?? ''}`; } + +function buildAdjustmentToolTip(trade: Trade, order: Order): string { + return `${trade.is_short ? 'Short' : 'Long'} adjustment + ${order.ft_order_side === 'buy' ? '+' : '-'}${formatPriceCurrency( + order.cost, + trade.quote_currency ?? '', + )}\nEnter-tag: ${trade.enter_tag ?? ''}`; +} + // const ENTRY_SYMB = 'circle'; // const EXIT_SYMB = 'rect'; @@ -61,12 +70,11 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { if ( trade.close_timestamp <= dataset.data_stop_ts && trade.close_timestamp > dataset.data_start_ts && - trade.close_date !== undefined && - trade.close_rate !== undefined + trade.is_open === false ) { tradeData.push([ roundTimeframe(dataset.timeframe_ms ?? 0, trade.close_timestamp), - trade.close_rate, + order.safe_price, OPEN_CLOSE_SYMBOL, trade.is_short ? 0 : 180, trade.is_short ? SHORT_COLOR : LONG_COLOR, @@ -85,7 +93,7 @@ export function getTradeEntries(dataset: PairHistory, filteredTrades: Trade[]) { order.ft_order_side == 'sell' ? 180 : 0, trade.is_short ? SHORT_COLOR : LONG_COLOR, '', - buildToolTip(trade, 'adjustment'), + buildAdjustmentToolTip(trade, order), ]); } }