Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

Prevent unnecessary balanced strategy re-randomization #60

Closed
wants to merge 12 commits into from

Conversation

Reidmcc
Copy link
Contributor

@Reidmcc Reidmcc commented Nov 17, 2018

Here's the update to balancedLevelProvider to have it remember what its balances were last run and not mess with the levels if they didn't really change.

The code creates a very small range of balances to consider "the same" because the maxAsset variables come back slightly different every run-through, even if no levels were touched. My guess is that it's a floating-point math problem.

@Reidmcc
Copy link
Contributor Author

Reidmcc commented Nov 17, 2018

This pr is to implement issue #52

@Reidmcc Reidmcc changed the title Balanced no rerand Prevent unnecessary balanced strategy re-randomization Nov 21, 2018
Copy link
Contributor

@nikhilsaraf nikhilsaraf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some style comments inline -- review looks good besides that except for addressing the jitter (see comment inline).

@@ -30,6 +30,12 @@ type balancedLevelProvider struct {

// precomputed before construction
randGen *rand.Rand

//keeps the starting balances from the previous run to check if anything has changed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments explaining the use of variables should be on the right side of the declaration (like for the variables above)

In general for comments in the code:
as a convention it should have a space after // and should begin with a lowercase character

@@ -30,6 +30,12 @@ type balancedLevelProvider struct {

// precomputed before construction
randGen *rand.Rand

//keeps the starting balances from the previous run to check if anything has changed
lastMaxAssetBase float64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these three variables can be in a new section of: // uninitialized.
this section will come after randGen

@@ -68,8 +74,14 @@ func makeBalancedLevelProvider(
validateSpread(carryoverInclusionProbability)

randGen := rand.New(rand.NewSource(time.Now().UnixNano()))

//set starting values for the previous-run variables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this (and it's usage below) is not needed since these are uninitialized based on the comment above -- it's sometimes better to be specific but the uninitialized concept is used in a few places in kelp right now.

@@ -93,6 +108,26 @@ func validateSpread(spread float64) {

// GetLevels impl.
func (p *balancedLevelProvider) GetLevels(maxAssetBase float64, maxAssetQuote float64) ([]api.Level, error) {
log.Printf("Last base balance was: %v", p.lastMaxAssetBase)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • we typically start these log lines with a lowercase character
  • use %.7f instead of %v
  • add \n after %.7f -- we always add newlines to printf statements as that will help immensely when we add a new logging framework
  • we should also print the current balances for easy viewing

putting this all together, it should be:

log.Printf("balance for base asset: last=%.7f, current=%.7f\n", p.lastMaxAssetBase, maxAssetBase)


//Checking whether balances have changed meaningfully
//We have to give the balances some room to move because slightly different balance values come back from Horizon even if nothing changed
//Probably because floating point math is the worst
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should try and address this jitter, adding this error buffer as a solution should only be the last resort.

we're using 7 units of precision everywhere which is also used in horizon so we should be able to fix this. Can you give me details on when we're getting different results from horizon?

log.Println("Balances remain essentially the same as the previous cycle, leave levels as they are.")
return p.lastLevels, nil
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the code that is unchanged should be extracted into a new function:
func (p *balancedLevelProvider) recomputeLevels(maxAssetBase float64, maxAssetQuote float64) ([]api.Level, error) -- this will allow us to easily test it (whenever we get to that)

we can return p.recomputeLevels(...) after we set the 3 last values as you've done below

@Reidmcc
Copy link
Contributor Author

Reidmcc commented Nov 30, 2018

@nikhilsaraf I've made the style edits and implemented the new function.

I figured out the balance jitter. It's not a precision problem, it's a transaction fee problem.
I don't have a separate source account set up so my fees are coming out of my trading account, which legitimately shrinks my XLM balance. There's no jitter for the non-XLM asset.

For example, my XLM balance values for two consecutive cycles were:

721.8387960
721.8383860

There's a couple ways we could deal with this:

  • Require the use of a source account for the balanced strategy
  • Check balance change to a lower than 7 precision, using your Number struct instead of multiplication. Unfortunately the best we could do would be precision 2 since the third decimal could be rounded. This is probably a bad idea, especially for expensive assets like BTC.
  • Track how many operations we do each cycle and pass that into the level provider along with whether the asset is XLM. This would change a lot of code throughout Kelp, so also probably a bad idea.

For now I've slimmed down the error buffer to only allow balance reductions. I agree that it's not optimal.

@nikhilsaraf
Copy link
Contributor

@Reidmcc I'm adding support for handling trades/fills on an account for use in the mirror strategy. This will be added as general infrastructure for the whole bot so any strategy can be set up to be "notified" of a trade on the account.

With that infrastructure in place we could actually use it to set a boolean flag on the balancedLevelProvider anytime we encounter a trade for the account. If you want to wait for that (end of next week at the very latest) then it may be a more elegant solution that would eliminate us having to worry about XLM fees.

@Reidmcc
Copy link
Contributor Author

Reidmcc commented Nov 30, 2018

@nikhilsaraf implementing the checks with the upcoming trade flag sounds good. I'm in no hurry; I've been running this live since I submitted it two weeks ago :-D

Seems like we'll still need the level-retention and re-submission part of this. I can remove the balance check parts and slim it down to just level keeping.

@Reidmcc
Copy link
Contributor Author

Reidmcc commented Dec 1, 2018

@nikhilsaraf I've merged in the new commits post repo move. It doesn't seemed to have fixed the Travis issue. Those commits are showing as changes now.

@nikhilsaraf
Copy link
Contributor

@Reidmcc I've fixed the travis checks.

The commits are probably showing up as separate changes because they were merged from the balanced_no_rerand branch instead of from the master branch of https://github.com/interstellar/kelp. I'm wondering if you can do a quick fix by reverting the last change and re-merging from the master of https://github.com/interstellar/kelp branch?

If that's not possible then it may just be easier to open a new PR. In that case it would be easier to do this towards the end of next week once I've merged the fill tracking changes.

@Reidmcc
Copy link
Contributor Author

Reidmcc commented Dec 1, 2018

@nikhilsaraf yeah, that's what I was trying to do; I merged the commits to my local branch from interstellar/master and pushed to the remote. Anyway, I'll do a new pull request rather than try to salvage this mess. It will be different code anyway using the fill tracking.

@Reidmcc Reidmcc closed this Dec 1, 2018
@nikhilsaraf
Copy link
Contributor

@Reidmcc I've uploaded the fill tracking, you can take a look at how that works for the mirror strategy as an example: https://github.com/interstellar/kelp/blob/master/plugins/mirrorStrategy.go#L300

@Reidmcc Reidmcc deleted the balanced_no_rerand branch January 11, 2019 00:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants