Skip to content

Instantly share code, notes, and snippets.

@Asoul
Last active October 30, 2023 09:28
Show Gist options
  • Save Asoul/15ffdfb18e135966e36f2e1834345986 to your computer and use it in GitHub Desktop.
Save Asoul/15ffdfb18e135966e36f2e1834345986 to your computer and use it in GitHub Desktop.
Bitfinex lending bot
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()
*/15 * * * * /usr/bin/python3 /opt/apps/run.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment