@@ -15,6 +15,9 @@ import (
1515 "github.com/stretchr/testify/assert"
1616)
1717
18+ var testBaseAsset = txnbuild.NativeAsset {}
19+ var testQuoteAsset txnbuild.CreditAsset = txnbuild.CreditAsset {Code : "QUOTE" , Issuer : "GBGQAGAMK6W6FH6AGGZ2BI2MY5TA5VJEHU2DQRFXACMAZHNRD3SXEV6Z" }
20+
1821func makeWantVolumeFilter (config * VolumeFilterConfig , marketIDs []string , accountIDs []string , action queries.DailyVolumeAction ) * volumeFilter {
1922 query , e := queries .MakeDailyVolumeByDateForMarketIdsAction (& sql.DB {}, marketIDs , action , accountIDs )
2023 if e != nil {
@@ -409,19 +412,20 @@ func TestVolumeFilterFn_BaseCap_Exact(t *testing.T) {
409412 wantTbbQuote : 0 ,
410413 },
411414 }
415+
412416 for _ , k := range testCases {
413417 // convert to common format accepted by runTestVolumeFilterFn
414- // doing this explicitly here is easier to read rather than if we were to add "logic" to convert it to a standard format
415- inputOp := makeSellOpAmtPrice ( k . inputAmount , k . inputPrice )
416-
417- var wantOp * txnbuild.ManageSellOffer
418+ // test sell action
419+ sellName := fmt . Sprintf ( "%s, sell" , k . name )
420+ inputSellOp := makeSellOpAmtPrice ( k . inputAmount , k . inputPrice )
421+ var wantSellOp * txnbuild.ManageSellOffer
418422 if k .wantPrice != nil && k .wantAmount != nil {
419- wantOp = makeSellOpAmtPrice (* k .wantAmount , * k .wantPrice )
423+ wantSellOp = makeSellOpAmtPrice (* k .wantAmount , * k .wantPrice )
420424 }
421425
422426 runTestVolumeFilterFn (
423427 t ,
424- k . name ,
428+ sellName ,
425429 volumeFilterModeExact ,
426430 queries .DailyVolumeActionSell ,
427431 pointy .Float64 (k .cap ), // base cap
@@ -430,8 +434,33 @@ func TestVolumeFilterFn_BaseCap_Exact(t *testing.T) {
430434 nil , // quoteOTB nil because this test is for the BaseCap
431435 pointy .Float64 (k .tbb ), // baseTBB
432436 pointy .Float64 (0 ), // quoteTBB (non-nil since it accumulates)
433- inputOp ,
434- wantOp ,
437+ inputSellOp ,
438+ wantSellOp ,
439+ pointy .Float64 (k .wantTbbBase ),
440+ pointy .Float64 (k .wantTbbQuote ),
441+ )
442+
443+ // test buy action
444+ buyName := fmt .Sprintf ("%s, buy" , k .name )
445+ inputBuyOp := makeBuyOpAmtPrice (k .inputAmount , k .inputPrice )
446+ var wantBuyOp * txnbuild.ManageSellOffer
447+ if k .wantPrice != nil && k .wantAmount != nil {
448+ wantBuyOp = makeBuyOpAmtPrice (* k .wantAmount , * k .wantPrice )
449+ }
450+
451+ runTestVolumeFilterFn (
452+ t ,
453+ buyName ,
454+ volumeFilterModeExact ,
455+ queries .DailyVolumeActionBuy ,
456+ pointy .Float64 (k .cap ), // base cap
457+ nil , // quote cap nil because this test is for the BaseCap
458+ pointy .Float64 (k .otb ), // baseOTB
459+ nil , // quoteOTB nil because this test is for the BaseCap
460+ pointy .Float64 (k .tbb ), // baseTBB
461+ pointy .Float64 (0 ), // quoteTBB (non-nil since it accumulates)
462+ inputBuyOp ,
463+ wantBuyOp ,
435464 pointy .Float64 (k .wantTbbBase ),
436465 pointy .Float64 (k .wantTbbQuote ),
437466 )
@@ -1111,7 +1140,9 @@ func runTestVolumeFilterFn(
11111140 mode : mode ,
11121141 }
11131142
1114- actual , e := volumeFilterFn (dailyOTB , dailyTBBAccumulator , inputOp , utils .NativeAsset , utils .NativeAsset , lp )
1143+ base := utils .Asset2Asset2 (testBaseAsset )
1144+ quote := utils .Asset2Asset2 (testQuoteAsset )
1145+ actual , e := volumeFilterFn (dailyOTB , dailyTBBAccumulator , inputOp , base , quote , lp )
11151146 if ! assert .Nil (t , e ) {
11161147 return
11171148 }
@@ -1126,13 +1157,33 @@ func runTestVolumeFilterFn(
11261157
11271158func makeSellOpAmtPrice (amount float64 , price float64 ) * txnbuild.ManageSellOffer {
11281159 return & txnbuild.ManageSellOffer {
1129- Buying : txnbuild. NativeAsset {} ,
1130- Selling : txnbuild. NativeAsset {} ,
1160+ Buying : testQuoteAsset ,
1161+ Selling : testBaseAsset ,
11311162 Amount : fmt .Sprintf ("%.7f" , amount ),
11321163 Price : fmt .Sprintf ("%.7f" , price ),
11331164 }
11341165}
11351166
1167+ func makeBuyOpAmtPrice (amount float64 , price float64 ) * txnbuild.ManageSellOffer {
1168+ // in Kelp, all actions are performed in context of the base asset
1169+ // a sell op sells base, and a buy op buys base/sells quote
1170+ // I ran this using the buysell strategy with the amount set to 1000.0 units (of base on either side), with the buy op being displayed first:
1171+ // 2020/12/23 02:35:59 submitting the following ops
1172+ // 2020/12/23 02:35:59 &{Selling:{Code:COUPON Issuer:GBMMZMK2DC4FFP4CAI6KCVNCQ7WLO5A7DQU7EC7WGHRDQBZB763X4OQI} Buying:{} Amount:163.4735274 Price:6.1171984 OfferID:0 SourceAccount:0xc00047e5e0}
1173+ // 2020/12/23 02:35:59 &{Selling:{} Buying:{Code:COUPON Issuer:GBMMZMK2DC4FFP4CAI6KCVNCQ7WLO5A7DQU7EC7WGHRDQBZB763X4OQI} Amount:1000.0000000 Price:0.1638006 OfferID:0 SourceAccount:0xc00047e6a0}
1174+ // above, we can see that the selling operation (second op) has amount = 1000.0 and price = 0.16 which is correct
1175+ // the buying op (first op) has amount set to 163.xx and price set to 6.xx, and we need to replicate this.
1176+ // To do so, we need to:
1177+ // set our Amount field on the manageSellOffer here equal to amount * price (so we get 1000 * 0.16 ~= 163.xx like displayed above)
1178+ // set the Price field to 1/price (so we get 1/0.16 ~= 6.xx like displayed above)
1179+ return & txnbuild.ManageSellOffer {
1180+ Buying : testBaseAsset ,
1181+ Selling : testQuoteAsset ,
1182+ Amount : fmt .Sprintf ("%.7f" , amount * price ),
1183+ Price : fmt .Sprintf ("%.7f" , 1 / price ),
1184+ }
1185+ }
1186+
11361187func TestValidateConfig (t * testing.T ) {
11371188 testCases := []struct {
11381189 name string
0 commit comments