beatzxbt / bybit-smm

bybit simple market maker
MIT License
389 stars 123 forks source link

Unintended complex numbers output #19

Open OfferLifted opened 1 month ago

OfferLifted commented 1 month ago

Just as a heads up in the v2 alpha branch in smm/quote_generators/plain.py. You allow negative numbers as input.

    def generate_orders(self, skew: float, spread: float) -> List:
        if skew > 0.0:
            return self.generate_positive_skew_quotes(skew, spread)
        elif skew <= 0.0:
            return self.generate_negative_skew_quotes(skew, spread)

Negative skew values will be used in:

        half_spread = spread / 2
        aggressiveness = self.params["aggressiveness"] * (skew**0.5)

        best_bid_price = self.mid - (half_spread * (1.0 - aggressiveness))
        best_ask_price = best_bid_price + spread

This will cause unintended issues. Best shown by an example.

skew = -0.99
with_skew_var = 0.5 * (skew**0.5)

print("with skew var", with_skew_var)
print("with skew var",type(with_skew_var))

without_skew_var = 0.5 * (-0.99**0.5)
print("\n")
print("without skew var", without_skew_var)
print("without skew var",type(without_skew_var))

Output:

with skew var (3.0462704501111267e-17+0.49749371855331j)
with skew var <class 'complex'>

without skew var -0.49749371855331
without skew var <class 'float'>

Afaik interprets python the one with the skew variable used as: (-0.99)**0.5. While interpreting the one without the var used as: -(0.99**0.5). Raising a negative number to a fractional exponent results in a complex number rather than the expected float.

Have you not yet encountered this? I haven't looked at the skew calcs in depth yet and I know it's still a WIP maybe the current skew calcs will never output negative skew or the skew value is coming from somewhere else idk.

OfferLifted commented 1 month ago

Something else to note.

        clipped_r = 0.5 + nbclip(skew, 0.0, 0.5)  # NOTE: Geometric ratio cant exceed 1.0

        bid_sizes = self.max_position * generate_geometric_weights(
            num=self.total_orders // 2, r=clipped_r, reverse=True
        )

        ask_sizes = self.max_position * generate_geometric_weights(
            num=self.total_orders // 2,
            r=0.5 + (clipped_r ** (2 + aggressiveness)),
            reverse=True,
        )

This clipped ratio value will be 1 if skew >= 0.5. Which is fine for bid_sizes however in ask_sizes you add 0.5 + clipped_r squared by some value. If clipped ratio == 1 which it will be for skew >= 0.5. The geometric ratio in ask_sizes will be 1.5 so exceeding 1.0. This might cause issues down the line.

beatzxbt commented 1 month ago

oop, im surprised i didnt encounter these in my few hours of running it...

will make fixes for this, many thanks for point it out!

OfferLifted commented 1 month ago

No worries. I had a brief look at your feature calcs. Not sure if you're running the same ones live but there are some that cannot return negative values. Like the weighted mids and stuff can only return negative values if there are negative prices. So that might be why you didn't encounter the negative skew one as perhaps the skew never got negative because half of the features only output postive values?

Anyways I'll have a deeper look at everything later.

beatzxbt commented 1 month ago

yeah there is missing stuff to in the feature calcs, the mids are supposed to be np.log(wmid/mid), not just plain wmid/mid...

all still WIP of course but clearly theres a lot more missing stuff than expected (found some more unintended behaviour in the quote gen, will push soon).

thanks again!

beatzxbt commented 1 month ago

addressed the issue here (and more missing stuffs): https://github.com/beatzxbt/bybit-smm/commit/80900f21e8a5be1f249cf6c3e2133d77c823340e

hope this fixes it, will close this issue once i get time to run it live and monitor quoting logic w/feat values