Created
July 20, 2024 00:19
-
-
Save pyoneerC/5552b3c7da50477f1c6dbf6ab0d3db7c to your computer and use it in GitHub Desktop.
Crypto Sniper Bot Simulator
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
# This is a simple crypto trading bot that buys and sells coins based on their price changes and market cap. | |
# The bot uses the Coinranking website to get the latest prices and market caps of the coins. | |
# The bot starts with a balance of 10,000$ and buys coins according to some rules, and sells them based on other rules. | |
# Remember that this is a simple bot and should not be used for real trading. | |
# It's a simulation to understand how trading works. | |
# At the end of the program, the bot will show a bar chart of the current prices of the coins in your portfolio | |
# and the total profit you have made so far, as well as a line chart of the progression of your profits over time. | |
import matplotlib.pyplot as plt | |
from bs4 import BeautifulSoup | |
import numpy as np | |
import requests | |
import time | |
import re | |
def should_buy(coin, balance): | |
if coin['name'] in ['Tether USD', 'USDC', 'Binance-Peg BSC-USD']: | |
return False | |
# Buy if the coin's price is less than the balance, the price change is more than 3% or less than -3%, | |
# the market cap is more than 1 billion, and the volume is more than 1 million | |
return (coin['change'] > 3 or coin['change'] < -3 and | |
coin['market_cap'] > 10 ** 9) | |
def should_sell(coin, purchase_price): | |
profit_margin = (coin['price'] - purchase_price) / purchase_price | |
# Sell if the profit margin is more than 10% or the price change is negative by more than 3% | |
# or the coin's price drops below 20% of the purchase price | |
# or the market cap is less than 1 billion | |
return (profit_margin > 0.10 or | |
coin['change'] < -3 or | |
coin['price'] < purchase_price * 0.20 or | |
coin['market_cap'] < 10 ** 9) | |
def convert_to_numeric(value): | |
multiplier = 1 | |
if 'trillion' in value: | |
multiplier = 10 ** 12 | |
elif 'billion' in value: | |
multiplier = 10 ** 9 | |
elif 'million' in value: | |
multiplier = 10 ** 6 | |
elif 'thousand' in value: | |
multiplier = 10 ** 3 | |
numeric_part = float(''.join(filter(str.isdigit, value)) + '.' + ''.join(filter(str.isdigit, value.split('.')[-1]))) | |
return numeric_part * multiplier | |
class CryptoSniper: | |
def __init__(self): | |
self.balance = 10000 | |
self.bought_coins = [] | |
def run(self): | |
print(f'Initial balance: {self.balance}$') | |
counter = 0 | |
balances = [] | |
profits = [] | |
try: | |
while True: | |
url = 'https://coinranking.com' | |
headers = { | |
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0', | |
'Pragma': 'no-cache', | |
} | |
response = requests.get(url, headers=headers) | |
soup = BeautifulSoup(response.text, 'html.parser') | |
data = soup.find_all('div', class_='valuta valuta--light') | |
data = [item.text.replace('$', '').replace('\n', '').strip() for item in data] | |
prices = [] | |
market_caps = [] | |
coin_names = soup.find_all('a', class_='profile__link') | |
coin_names = [coin_name.text for coin_name in coin_names] | |
coin_names = [coin_name.replace('\n', '').strip() for coin_name in coin_names] | |
changes_24hr = soup.find_all('div', { | |
'class': ['change change--light change--positive', 'change change--light change--negative']}) | |
changes_24hr = [change.text.replace('\n', '').strip() for change in changes_24hr] | |
for i in range(len(data)): | |
if i % 2 == 0: | |
prices.append(data[i]) | |
else: | |
market_caps.append(data[i]) | |
for name, price, change, market_cap in zip(coin_names, prices, changes_24hr, market_caps): | |
price = re.sub(r'[^\d.,]', '', price) | |
coin = { | |
'name': name, | |
'price': float(price.replace(',', '')), | |
'change': float(change.replace('%', '')), | |
'market_cap': convert_to_numeric(market_cap) | |
} | |
for i, coin_tuple in enumerate(self.bought_coins): | |
if coin_tuple[0]['name'] == coin['name']: | |
updated_coin = coin.copy() | |
updated_coin_tuple = (updated_coin, coin_tuple[1], coin_tuple[2]) | |
self.bought_coins[i] = updated_coin_tuple | |
if should_buy(coin, self.balance) and self.balance >= coin['price']: | |
quantity = self.balance // coin['price'] | |
self.balance -= quantity * coin['price'] | |
self.bought_coins.append((coin, quantity, coin['price'])) # Store the purchase price | |
print(f'Bought {quantity} of {coin["name"]} for {coin["price"]}$ each') | |
for coin_tuple in self.bought_coins: | |
coin, quantity, purchase_price = coin_tuple # Unpack the tuple | |
if should_sell(coin, purchase_price): # Pass the purchase price to should_sell | |
self.balance += coin['price'] * quantity | |
self.bought_coins.remove(coin_tuple) | |
print(f'Sold {quantity} of {coin["name"]} for {coin["price"]}$ each') | |
print(f'Current balance: {self.balance:.3f}$') | |
balances.append(self.balance) | |
print(f'Acquired coins: {[coin_tuple[0]["name"] for coin_tuple in self.bought_coins]}') | |
print('-' * 50) | |
for coin_tuple in self.bought_coins: | |
coin, quantity, purchase_price = coin_tuple | |
print(f'{coin["name"]} price: {coin["price"]:.7f}$, bought {quantity} for {purchase_price:.7f}$, ' | |
f'difference: {coin["price"] - purchase_price:.7f}$') | |
total_profit = sum([coin['price'] - purchase_price for coin, quantity, purchase_price in self.bought_coins]) | |
print(f'Total profit: {total_profit:.7f}$') | |
profits.append(total_profit) | |
print(f'We are in the {counter}th run.') | |
print('-' * 50) | |
counter += 1 | |
time.sleep(61) # Minimum time between price updates. Unfortunately the website updates every 60 seconds | |
except KeyboardInterrupt: | |
labels = [coin_tuple[0]["name"] for coin_tuple in self.bought_coins] | |
purchase_prices = [coin_tuple[2] for coin_tuple in self.bought_coins] | |
current_prices = [coin_tuple[0]['price'] for coin_tuple in self.bought_coins] | |
x = np.arange(len(labels)) | |
width = 0.35 | |
colors = ['g' if current > purchase else 'r' for current, purchase in | |
zip(current_prices, purchase_prices)] | |
fig, ax = plt.subplots() | |
rects1 = ax.bar(x - width / 2, purchase_prices, width, label='Purchase Price', color='b') | |
rects2 = ax.bar(x + width / 2, current_prices, width, label='Current Price', color=colors) | |
ax.set_ylabel('Prices') | |
ax.set_title('Your Portfolio') | |
ax.set_xticks(x) | |
ax.set_xticklabels(labels) | |
ax.legend() | |
# Add prices above the bars | |
for rect, price in zip(rects1, purchase_prices): | |
height = rect.get_height() | |
ax.text(rect.get_x() + rect.get_width() / 2., height, | |
'%d' % int(price), | |
ha='center', va='bottom') | |
for rect, price in zip(rects2, current_prices): | |
height = rect.get_height() | |
ax.text(rect.get_x() + rect.get_width() / 2., height, | |
'%d' % int(price), | |
ha='center', va='bottom') | |
fig.tight_layout() | |
plt.show() | |
# for each run, put in a chart the profits progression | |
plt.figure() | |
color = 'r' if profits[-1] < 0 else 'g' | |
plt.plot(range(counter), profits, label='Profits', color=color) | |
plt.xlabel('Run Number') | |
plt.ylabel('Profits') | |
plt.title('Profits Progression') | |
plt.xticks(range(counter)) | |
plt.show() | |
if __name__ == "__main__": | |
sniper = CryptoSniper() | |
sniper.run() |
Author
pyoneerC
commented
Jul 20, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment