From da561325d780cf95b7e209cf18f25269b11af4bd Mon Sep 17 00:00:00 2001 From: jackyu66git Date: Sun, 3 May 2026 17:55:39 +0800 Subject: [PATCH] Revert B#6: netProfit must NOT delegate to CalcNetProfit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CalcNetProfit (helpers.go) has internal price-swap logic — when price2 < price1 it swaps buy/sell sides. ScanArbWithFees relies on netProfit being a pure strict-direction calculation (callers try both directions via addPair). Delegation caused double-swap: both netProfit calls in addPair returned positive profit, but direction1's struct reported wrong exchange pair, leading to potential loss-making trades. Keep both formulas as independent implementations with explicit comments warning against future merging attempts. --- scanner.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/scanner.go b/scanner.go index 5ca81f2..2612ae7 100644 --- a/scanner.go +++ b/scanner.go @@ -4,8 +4,6 @@ import ( "log" "sort" "time" - - "exchange-monitor/exchange" ) // Exchange names @@ -43,9 +41,18 @@ var TrackedCoins = []TrackedCoin{ } // netProfit calculates net profit % after fees for a complete round trip (entry + exit). -// B#6: Delegates to exchange.CalcNetProfit to eliminate formula duplication. +// NOTE: Does NOT swap prices — callers (ScanArbWithFees) pass prices in explicit buy/sell order +// and try both directions via addPair. Using exchange.CalcNetProfit would double-swap (B#6). func netProfit(buyPrice, sellPrice, buyFee, sellFee float64) float64 { - return exchange.CalcNetProfit(buyPrice, sellPrice, buyFee, sellFee, buyFee, sellFee) + if buyPrice <= 0 || sellPrice <= 0 { + return 0 + } + // Entry: buy at buyPrice (pay buyFee), sell short at sellPrice (pay sellFee) + cost := buyPrice * (1 + buyFee/100) + revenue := sellPrice * (1 - sellFee/100) + // Exit: sell long (pay sellFee), buy back short (pay buyFee) + // Total fees = 2 * (buyFee + sellFee), first round already in formula above + return (revenue/cost - 1)*100 - (buyFee + sellFee) } // ScanArbWithFees checks all coins for arbitrage opportunities using a custom fee map.