This repository has been archived by the owner on Feb 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 262
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new priceFeedFilter, refactor filterOps, remove dedupeRedundantUpdate…
…sFilter, closes #329 (#335) * 1 - priceFeedFilter.go * 2 - better function and var names for priceFeedFilter * 3 - add filterPriceFeed to filterFactory.go * 4 - add sample price feed filter in sample_trader.cfg * 5 - add a log line per op in the priceFeedFilter * 6 - refactor filterFn to remove keep return var returning a nil newOp means we don't want to keep it, and returning a non-nil newOp means we want to keep it. Not keeping is handled differently for ops that have existing offers vs. those that do not * f 6 - need to copy original offer * 7 - remove dedupeRedundantUpdatesFilter * 8 - filterOps to fetch original offer if exists for all ops * 9 - simplify runInnerFilterFn by figuring out filterCounterToIncrement in caller * 10 - rename !isNewOpNil -> keep * 11 - consolidate drop case for volumeFilter and makerModeFilter * 12 - return newOpToPrepend before the newOpToAppend value
- Loading branch information
1 parent
afb5628
commit 3e0c240
Showing
10 changed files
with
242 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package plugins | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strconv" | ||
|
||
hProtocol "github.com/stellar/go/protocols/horizon" | ||
"github.com/stellar/go/txnbuild" | ||
"github.com/stellar/kelp/api" | ||
"github.com/stellar/kelp/support/utils" | ||
) | ||
|
||
type comparisonMode int8 | ||
|
||
const ( | ||
comparisonModeOutsideExclude comparisonMode = iota // gt for sell, lt for buy | ||
comparisonModeOutsideInclude // gte for sell, lte for buy | ||
) | ||
|
||
func (c comparisonMode) keepSellOp(threshold float64, price float64) bool { | ||
if c == comparisonModeOutsideExclude { | ||
return price > threshold | ||
} else if c == comparisonModeOutsideInclude { | ||
return price >= threshold | ||
} | ||
panic("unidentified comparisonMode") | ||
} | ||
|
||
// TODO implement passesBuy() where we use < and <= operators | ||
|
||
type priceFeedFilter struct { | ||
name string | ||
baseAsset hProtocol.Asset | ||
quoteAsset hProtocol.Asset | ||
pf api.PriceFeed | ||
cm comparisonMode | ||
} | ||
|
||
// MakeFilterPriceFeed makes a submit filter that limits orders placed based on the value of the price feed | ||
func MakeFilterPriceFeed(baseAsset hProtocol.Asset, quoteAsset hProtocol.Asset, comparisonModeString string, pf api.PriceFeed) (SubmitFilter, error) { | ||
var cm comparisonMode | ||
if comparisonModeString == "outside-exclude" { | ||
cm = comparisonModeOutsideExclude | ||
} else if comparisonModeString == "outside-include" { | ||
cm = comparisonModeOutsideInclude | ||
} else { | ||
return nil, fmt.Errorf("invalid comparisonMode ('%s') used for priceFeedFilter", comparisonModeString) | ||
} | ||
|
||
return &priceFeedFilter{ | ||
name: "priceFeedFilter", | ||
baseAsset: baseAsset, | ||
quoteAsset: quoteAsset, | ||
cm: cm, | ||
pf: pf, | ||
}, nil | ||
} | ||
|
||
var _ SubmitFilter = &priceFeedFilter{} | ||
|
||
func (f *priceFeedFilter) Apply(ops []txnbuild.Operation, sellingOffers []hProtocol.Offer, buyingOffers []hProtocol.Offer) ([]txnbuild.Operation, error) { | ||
ops, e := filterOps(f.name, f.baseAsset, f.quoteAsset, sellingOffers, buyingOffers, ops, f.priceFeedFilterFn) | ||
if e != nil { | ||
return nil, fmt.Errorf("could not apply filter: %s", e) | ||
} | ||
return ops, nil | ||
} | ||
|
||
func (f *priceFeedFilter) priceFeedFilterFn(op *txnbuild.ManageSellOffer) (*txnbuild.ManageSellOffer, error) { | ||
isSell, e := utils.IsSelling(f.baseAsset, f.quoteAsset, op.Selling, op.Buying) | ||
if e != nil { | ||
return nil, fmt.Errorf("error when running the isSelling check: %s", e) | ||
} | ||
|
||
sellPrice, e := strconv.ParseFloat(op.Price, 64) | ||
if e != nil { | ||
return nil, fmt.Errorf("could not convert price (%s) to float: %s", op.Price, e) | ||
} | ||
|
||
thresholdFeedPrice, e := f.pf.GetPrice() | ||
if e != nil { | ||
return nil, fmt.Errorf("could not get price from priceFeed: %s", e) | ||
} | ||
|
||
var opRet *txnbuild.ManageSellOffer | ||
// for the sell side we keep only those ops that meet the comparison mode using the value from the price feed as the threshold | ||
if isSell { | ||
if f.cm.keepSellOp(thresholdFeedPrice, sellPrice) { | ||
opRet = op | ||
} else { | ||
opRet = nil | ||
} | ||
} else { | ||
// for the buy side we keep only those ops that meet the comparison mode using the value from the price feed as the threshold | ||
// TODO for buy side (after considering whether sellPrice needs to be inverted or not) | ||
opRet = op | ||
} | ||
log.Printf("priceFeedFilter: isSell=%v, sellPrice=%.10f, thresholdFeedPrice=%.10f, keep=%v", isSell, sellPrice, thresholdFeedPrice, opRet != nil) | ||
return opRet, nil | ||
} |
Oops, something went wrong.