Revert B#6: netProfit must NOT delegate to CalcNetProfit

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.
This commit is contained in:
jackyu66git
2026-05-03 17:55:39 +08:00
parent 277c34c3bd
commit da561325d7
+11 -4
View File
@@ -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.