Skip to content

Commit 94d9014

Browse files
committed
mtgban/arbit: Add a Profitability index value
Replace Price Ratio in the csv column since it's unused.
1 parent a824133 commit 94d9014

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

mtgban/arbit.go

+29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mtgban
22

33
import (
4+
"math"
45
"strconv"
56
"strings"
67

@@ -72,6 +73,10 @@ type ArbitOpts struct {
7273
// It returns a custom factor to be applied on the buylist price,
7374
// and whether the entry shoul be skipped
7475
CustomCardFilter func(co *mtgmatcher.CardObject) (float64, bool)
76+
77+
// Constant used to offset prices (the higher the value, the less impactful
78+
// lower prices will be)
79+
ProfitabilityConstant float64
7580
}
7681

7782
type ArbitEntry struct {
@@ -98,13 +103,18 @@ type ArbitEntry struct {
98103

99104
// Amount of cards that can be applied
100105
Quantity int
106+
107+
// The higher the number the better the arbit is. Using this formula
108+
// Profitability Index (PI) = (Difference / (Sell Price + 10)) * log(1 + Spread) * sqrt(Units)
109+
Profitability float64
101110
}
102111

103112
func Arbit(opts *ArbitOpts, vendor Vendor, seller Seller) (result []ArbitEntry, err error) {
104113
minDiff := 0.0
105114
minSpread := 0.0
106115
useTrades := false
107116
rate := 1.0
117+
profitabilityConstant := 10.0
108118

109119
minPrice := 0.0
110120
minBuyPrice := 0.0
@@ -134,6 +144,9 @@ func Arbit(opts *ArbitOpts, vendor Vendor, seller Seller) (result []ArbitEntry,
134144
if opts.Rate != 0 {
135145
rate = opts.Rate
136146
}
147+
if opts.ProfitabilityConstant > 0 {
148+
profitabilityConstant = opts.ProfitabilityConstant
149+
}
137150
useTrades = opts.UseTrades
138151

139152
minPrice = opts.MinPrice
@@ -306,6 +319,11 @@ func Arbit(opts *ArbitOpts, vendor Vendor, seller Seller) (result []ArbitEntry,
306319
}
307320
}
308321

322+
profitability := (difference / (price + profitabilityConstant)) * math.Log(1+spread)
323+
if qty > 1 {
324+
profitability *= math.Sqrt(float64(qty))
325+
}
326+
309327
res := ArbitEntry{
310328
CardId: cardId,
311329
BuylistEntry: blEntry,
@@ -314,6 +332,7 @@ func Arbit(opts *ArbitOpts, vendor Vendor, seller Seller) (result []ArbitEntry,
314332
AbsoluteDifference: difference * float64(qty),
315333
Spread: spread,
316334
Quantity: qty,
335+
Profitability: profitability,
317336
}
318337
result = append(result, res)
319338
}
@@ -417,6 +436,7 @@ func Mismatch(opts *ArbitOpts, reference Seller, probe Seller) (result []ArbitEn
417436
maxSpread := 0.0
418437
minPrice := 0.0
419438
minQty := 0
439+
profitabilityConstant := 10.0
420440
filterFoil := false
421441
filterOnlyFoil := false
422442
filterRLOnly := false
@@ -434,6 +454,9 @@ func Mismatch(opts *ArbitOpts, reference Seller, probe Seller) (result []ArbitEn
434454
if opts.MinSpread != 0 {
435455
minSpread = opts.MinSpread
436456
}
457+
if opts.ProfitabilityConstant > 0 {
458+
profitabilityConstant = opts.ProfitabilityConstant
459+
}
437460

438461
minPrice = opts.MinPrice
439462
maxSpread = opts.MaxSpread
@@ -559,13 +582,19 @@ func Mismatch(opts *ArbitOpts, reference Seller, probe Seller) (result []ArbitEn
559582
}
560583
}
561584

585+
profitability := (difference / (price + profitabilityConstant)) * math.Log(1+spread)
586+
if qty > 1 {
587+
profitability *= math.Sqrt(float64(qty))
588+
}
589+
562590
res := ArbitEntry{
563591
CardId: cardId,
564592
InventoryEntry: invEntry,
565593
ReferenceEntry: refEntry,
566594
Difference: difference,
567595
Spread: spread,
568596
Quantity: qty,
597+
Profitability: profitability,
569598
}
570599
result = append(result, res)
571600
}

mtgban/csv.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var (
2828
// The canonical header that will be present in all buylist files
2929
BuylistHeader = append(CardHeader, "Conditions", "Buy Price", "Trade Price", "Quantity", "Price Ratio", "URL", "Vendor")
3030

31-
ArbitHeader = append(CardHeader, "Conditions", "Available", "Sell Price", "Buy Price", "Trade Price", "Difference", "Spread", "Abs Difference", "Price Ratio")
31+
ArbitHeader = append(CardHeader, "Conditions", "Available", "Sell Price", "Buy Price", "Trade Price", "Difference", "Spread", "Abs Difference", "Profitability")
3232

3333
MismatchHeader = append(CardHeader, "Conditions", "Price", "Reference", "Difference", "Spread")
3434

@@ -463,7 +463,7 @@ func WriteArbitrageToCSV(arbitrage []ArbitEntry, w io.Writer) error {
463463
fmt.Sprintf("%0.2f", entry.Difference),
464464
fmt.Sprintf("%0.2f", entry.Spread),
465465
fmt.Sprintf("%0.2f", entry.AbsoluteDifference),
466-
fmt.Sprintf("%0.2f", bl.PriceRatio),
466+
fmt.Sprintf("%0.2f", entry.Profitability),
467467
)
468468
if hasExtraSeller {
469469
record = append(record, inv.SellerName)

0 commit comments

Comments
 (0)