Created
May 21, 2020 06:56
-
-
Save traderbagel/834b7fc79776d810ed83371b528e1035 to your computer and use it in GitHub Desktop.
bitfinex-lending-bot
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
import time | |
import base64 | |
import json | |
import hmac | |
import hashlib | |
import requests | |
URL = 'https://api.bitfinex.com' | |
API_VERSION = '/v1' | |
API_KEY = '' | |
API_SECRET = '' | |
def _post(endpoint, payload=None): | |
payload = payload or {} | |
payload['request'] = API_VERSION + endpoint | |
payload['nonce'] = str(int(time.time() * 1000)) | |
base64_payload = base64.b64encode(json.dumps(payload).encode()) | |
signature = hmac.new(API_SECRET.encode(), base64_payload, digestmod=hashlib.sha384)\ | |
.hexdigest() | |
signed_payload = { | |
'X-BFX-APIKEY': API_KEY, | |
'X-BFX-PAYLOAD': base64_payload, | |
'X-BFX-SIGNATURE': signature | |
} | |
response = requests.post(URL + API_VERSION + endpoint, headers=signed_payload, timeout=10) | |
if not response.ok: | |
print(f'post {endpoint} failed') | |
print(response.content) | |
raise ValueError(response) | |
return response.json() | |
def get_lend_rate(currency): | |
# Get the past 2 hours average | |
data = requests.get(f'https://api-pub.bitfinex.com/v2/candles/trade:15m:f{currency.upper()}:p15/hist?limit=8').json() | |
ma8_ratio = sum(d[2] for d in data) / 8 | |
highest_ratio = max(d[3] for d in data) | |
# Use the average of moving average and highest | |
ratio = (ma8_ratio + highest_ratio) / 2 * 100 | |
ratio = max(ratio, 0.041) | |
# v1 api use yearly raio, v2 use daily ratio | |
return ratio * 365 | |
def create_offer(currency, amount, rate, period): | |
print(f'Lend {currency.upper()} {round(amount)}, {rate:.5}%, {period} days') | |
return _post('/offer/new', { | |
'currency': currency.upper(), | |
'amount': str(int(amount)), | |
'rate': str(rate), | |
'period': period, | |
'direction': 'lend' | |
}) | |
def cancel_offer(offer_id): | |
print(f'Cancel offer {offer_id}') | |
return _post('/offer/cancel', { | |
'offer_id': offer_id | |
}) | |
def get_open_offers(): | |
return _post('/offers') | |
def get_period_by_rate(rate): | |
if rate < 15: | |
return 5 | |
elif rate < 20: | |
return 10 | |
elif rate > 30: | |
return 30 | |
return 20 | |
def main(): | |
offers = get_open_offers() | |
for offer in offers: | |
cancel_offer(offer['id']) | |
currency_pairs = _post('/balances') | |
for currency_pair in currency_pairs: | |
if currency_pair['type'] != 'deposit': | |
continue | |
if currency_pair['currency'] not in ['usd', 'ust']: | |
continue | |
currency = currency_pair['currency'] | |
amount = float(currency_pair['available']) | |
if amount <= 50: | |
continue | |
rate = get_lend_rate(currency) | |
period = get_period_by_rate(rate) | |
create_offer(currency, amount, rate, period) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment