diff --git a/README.md b/README.md index c43332d..b10c8a7 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,12 @@ This library can detect perpetual contract with a large divergence in funding ra ```bash - git clone https://github.com/aoki-h-jp/funding-rate-arbitrage.git pip install funding-rate-arbitrage - ``` ## Usage +### Fetch FR & commission ```python from frarb import FundingRateArbitrage @@ -42,6 +41,18 @@ fr_binance = fr.fetch_all_funding_rate(exchange='binance') cm_binance = fr.get_commission(exchange='binance', trade='futures', taker=False) ``` +### Display large FR divergence on single CEX +```python +# display large funding rate divergence on bybit +>>> fr.display_large_divergence_single_exchange(exchange='bybit', display_num=5) + Funding Rate [%] Commission [%] Revenue [/100 USDT] +CTC/USDT:USDT 0.1794 0.32 -0.1406 +CREAM/USDT:USDT 0.0338 0.32 -0.2862 +TWT/USDT:USDT 0.0295 0.32 -0.2905 +TLM/USDT:USDT 0.0252 0.32 -0.2948 +JASMY/USDT:USDT 0.0100 0.32 -0.3100 +``` + ## Disclaimer This project is for educational purposes only. You should not construe any such information or other material as legal, diff --git a/examples/get_large_divergence_single_exchange.py b/examples/get_large_divergence_single_exchange.py new file mode 100644 index 0000000..4f2aa89 --- /dev/null +++ b/examples/get_large_divergence_single_exchange.py @@ -0,0 +1,13 @@ +""" +An example of getting large divergence by single exchange. +""" +from frarb import FundingRateArbitrage + + +if __name__ == '__main__': + fr = FundingRateArbitrage() + # Display Top 5 large funding rate divergence on binance. + print(fr.display_large_divergence_single_exchange(exchange='binance', display_num=5)) + + # Display Top 5 large funding rate divergence on bybit (minus FR). + print(fr.display_large_divergence_single_exchange(exchange='bybit', display_num=5, minus=True)) diff --git a/frarb/frarb.py b/frarb/frarb.py index 3ca4f9a..f0740ce 100644 --- a/frarb/frarb.py +++ b/frarb/frarb.py @@ -5,6 +5,9 @@ class FundingRateArbitrage: def __init__(self): self.exchanges = ['binance', 'bybit', 'okx', 'bitget', 'gate', 'coinex'] + # commission + self.is_taker = True + self.by_token = False @staticmethod def fetch_all_funding_rate(exchange: str) -> dict: @@ -22,6 +25,37 @@ def fetch_all_funding_rate(exchange: str) -> dict: perp = [p for p in info if info[p]['linear']] return {p: ex.fetch_funding_rate(p)['fundingRate'] for p in perp} + def display_large_divergence_single_exchange(self, exchange: str, minus=False, display_num=10) -> pd.DataFrame: + """ + Display large funding rate divergence on single CEX. + Args: + exchange (str): Name of exchange (binance, bybit, ...) + minus (bool): Sorted by minus FR or plus FR. + display_num (int): Number of display. + + Returns (pd.DataFrame): DataFrame sorted by large funding rate divergence. + + """ + fr = self.fetch_all_funding_rate(exchange=exchange) + columns = ['Funding Rate [%]', 'Commission [%]', 'Revenue [/100 USDT]'] + sr_fr = pd.Series(list(fr.values())) * 100 + if minus: + cm = self.get_commission(exchange=exchange, trade='futures', taker=self.is_taker, by_token=self.by_token)\ + + self.get_commission(exchange=exchange, trade='options', taker=self.is_taker, by_token=self.by_token)\ + + self.get_commission(exchange=exchange, trade='spot', taker=self.is_taker, by_token=self.by_token) + sr_cm = pd.Series([cm * 2 for i in range(len(sr_fr))]) + sr_rv = abs(sr_fr) - sr_cm + else: + cm = self.get_commission(exchange=exchange, trade='futures', taker=self.is_taker, by_token=self.by_token) \ + + self.get_commission(exchange=exchange, trade='spot', taker=self.is_taker, by_token=self.by_token) + sr_cm = pd.Series([cm * 2 for i in range(len(sr_fr))]) + sr_rv = sr_fr - sr_cm + + df = pd.concat([sr_fr, sr_cm, sr_rv], axis=1) + df.index = list(fr.keys()) + df.columns = columns + return df.sort_values(by=columns[0], ascending=minus).head(display_num) + def get_exchanges(self) -> list: """ Get a list of exchanges. @@ -74,6 +108,8 @@ def get_commission(exchange: str, trade: str, taker=True, by_token=False) -> flo return 0.018 else: return 0.02 + elif trade == 'options': + return 0.02 else: raise KeyError @@ -86,6 +122,8 @@ def get_commission(exchange: str, trade: str, taker=True, by_token=False) -> flo return 0.06 else: return 0.01 + elif trade == 'options': + return 0.03 else: raise KeyError @@ -101,6 +139,11 @@ def get_commission(exchange: str, trade: str, taker=True, by_token=False) -> flo return 0.05 else: return 0.02 + elif trade == 'options': + if taker: + return 0.03 + else: + return 0.02 else: raise KeyError