-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
1,261 additions
and
47 deletions.
There are no files selected for viewing
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 file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
from tabulate import tabulate | ||
|
||
def run_trade_simulation(trades, usd_amount, scenario_name, sell_key): | ||
""" | ||
Run a trading simulation for a specific scenario | ||
Args: | ||
trades (list): List of trade dictionaries containing buy/sell prices | ||
usd_amount (float): USD amount to trade with | ||
scenario_name (str): Name of the scenario for printing | ||
sell_key (str): Dictionary key to use for sell price ('sell1' or 'sell2') | ||
Returns: | ||
tuple: (total_profit, total_btc) | ||
""" | ||
total_profit = 0 | ||
total_btc = 0 | ||
trade_rows = [] | ||
|
||
for trade in trades: | ||
buy_price = trade["buy"] | ||
sell_price = trade[sell_key] | ||
|
||
asset_amount = usd_amount / buy_price | ||
total_btc += asset_amount | ||
|
||
profit = (asset_amount * sell_price) - usd_amount | ||
total_profit += profit | ||
|
||
return_percent = ((sell_price - buy_price) / buy_price) * 100 | ||
|
||
trade_rows.append([ | ||
f"${buy_price:,}", | ||
f"${sell_price:,}", | ||
f"{return_percent:,.1f}%", | ||
f"${profit:,.2f}", | ||
f"${total_profit:,.2f}", | ||
f"{total_btc:.8f}" | ||
]) | ||
|
||
print(f"\n{scenario_name} (${usd_amount:,.2f} per trade):") | ||
print(tabulate( | ||
trade_rows, | ||
headers=["Buy Price", "Sell Price", "Return", "Profit", "Total Profit", "Total BTC"], | ||
tablefmt="grid" | ||
)) | ||
|
||
return total_profit, total_btc | ||
|
||
def print_summary(scenarios_results): | ||
""" | ||
Print summary of all scenarios | ||
Args: | ||
scenarios_results (dict): Dictionary of scenario results | ||
""" | ||
summary_rows = [ | ||
[name, f"${profit:,.2f}", f"{btc:.8f}"] | ||
for name, (profit, btc) in scenarios_results.items() | ||
] | ||
|
||
print("\nFinal Summary:") | ||
print(tabulate( | ||
summary_rows, | ||
headers=["Scenario", "Total Profit", "Total BTC"], | ||
tablefmt="grid" | ||
)) | ||
|
||
# Global trade settings | ||
BUY_PRICES = [75000, 70000, 65000, 60000, 55000, 50000] | ||
SELL_SCENARIOS = { | ||
"conservative": [85000, 80000, 75000, 70000, 65000, 60000], | ||
"moderate": [95000, 90000, 85000, 80000, 75000, 70000], | ||
"aggressive": [130000, 120000, 110000, 100000, 90000, 80000] | ||
} | ||
|
||
def generate_trades(): | ||
"""Generate trade dictionaries from global settings""" | ||
trades = [] | ||
for i, buy_price in enumerate(BUY_PRICES): | ||
trade = {"buy": buy_price} | ||
for scenario_name, sell_prices in SELL_SCENARIOS.items(): | ||
trade[scenario_name] = sell_prices[i] | ||
trades.append(trade) | ||
return trades | ||
|
||
PARAMETERS = { | ||
"usd_amount": 125, | ||
"trades": generate_trades(), | ||
"scenarios": [ | ||
{ | ||
"name": "Conservative Strategy", | ||
"sell_key": "conservative", | ||
"usd_amount": 125 | ||
}, | ||
{ | ||
"name": "Aggressive Strategy", | ||
"sell_key": "aggressive", | ||
"usd_amount": 250 | ||
}, | ||
{ | ||
"name": "Moderate Strategy", | ||
"sell_key": "moderate", | ||
"usd_amount": 175 | ||
} | ||
] | ||
} | ||
|
||
def main(): | ||
# Run all scenarios | ||
results = {} | ||
for scenario in PARAMETERS["scenarios"]: | ||
results[scenario["name"]] = run_trade_simulation( | ||
PARAMETERS["trades"], | ||
scenario["usd_amount"], | ||
scenario["name"], | ||
scenario["sell_key"] | ||
) | ||
|
||
# Print final summary | ||
print_summary(results) | ||
|
||
if __name__ == "__main__": | ||
main() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
websockets | ||
asyncio | ||
requests | ||
python-dotenv | ||
numpy |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#!/usr/bin/env python3 | ||
|
||
''' | ||
Handles canceling buy orders that fall out of the defined range | ||
''' | ||
|
||
|
||
import os | ||
import ccxt | ||
import logging | ||
import argparse | ||
import time | ||
from dotenv import load_dotenv | ||
|
||
# Load API keys from .env file | ||
load_dotenv() | ||
|
||
API_KEY = os.getenv("KRAKEN_API_KEY") | ||
API_SECRET = os.getenv("KRAKEN_API_SECRET") | ||
|
||
# Set up logging | ||
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s') | ||
|
||
# Kraken asset pairs mapping (optional if needed) | ||
ASSET_PAIRS = { | ||
"XXBTZUSD": "BTC/USD", | ||
"XETHZUSD": "ETH/USD", | ||
"XXRPZUSD": "XRP/USD", | ||
"SOLUSD": "SOL/USD", | ||
"ADAUSD": "ADA/USD", | ||
"AVAXUSD": "AVAX/USD", | ||
"TRXUSD": "TRX/USD", | ||
"XMRUSD": "XMR/USD", | ||
"FETUSD": "FET/USD" | ||
} | ||
|
||
|
||
# Initialize Kraken exchange | ||
kraken = ccxt.kraken({ | ||
'apiKey': API_KEY, | ||
'secret': API_SECRET, | ||
}) | ||
|
||
# Function to get current price of an asset pair | ||
def get_current_price(pair): | ||
ticker = kraken.fetch_ticker(pair) | ||
return ticker['last'] | ||
|
||
# Function to check if order is within the threshold | ||
def is_within_threshold(order_price, current_price, threshold_percent): | ||
price_diff = abs(order_price - current_price) | ||
return price_diff <= (current_price * (threshold_percent / 100)) | ||
|
||
# Function to cancel orders | ||
def cancel_order(order_id, pair): | ||
try: | ||
kraken.cancel_order(order_id) | ||
logging.info(f"Cancelled order {order_id} for {pair}") | ||
except ccxt.BaseError as e: | ||
logging.error(f"Error cancelling order {order_id}: {str(e)}") | ||
|
||
# Function to process orders and apply the new check for multiple open buy orders per asset pair | ||
def process_orders(threshold_percent): | ||
logging.info("Fetching open orders...") | ||
try: | ||
open_orders = kraken.fetch_open_orders() | ||
except ccxt.BaseError as e: | ||
logging.error(f"Error fetching open orders: {str(e)}") | ||
return | ||
|
||
# Dictionary to track buy orders per asset pair | ||
buy_orders_by_pair = {} | ||
|
||
# First, collect all buy orders per asset pair | ||
for order in open_orders: | ||
pair = order['symbol'] | ||
side = order['side'] | ||
if side == 'buy': | ||
if pair not in buy_orders_by_pair: | ||
buy_orders_by_pair[pair] = [] | ||
buy_orders_by_pair[pair].append(order) | ||
|
||
# Now process the buy orders for each pair | ||
for pair, orders in buy_orders_by_pair.items(): | ||
# If more than 1 buy order is open for this pair, cancel all buy orders for the pair | ||
if len(orders) > 1: | ||
logging.info(f"Found more than 1 open buy order for {pair}, cancelling all buy orders for this pair.") | ||
for order in orders: | ||
cancel_order(order['id'], pair) | ||
else: | ||
# If only 1 buy order, check if it's within the threshold | ||
order = orders[0] | ||
order_id = order['id'] | ||
order_price = float(order['price']) | ||
try: | ||
current_price = get_current_price(pair) | ||
logging.info(f"Order {order_id} for {pair}: order price={order_price}, current price={current_price}") | ||
|
||
if not is_within_threshold(order_price, current_price, threshold_percent): | ||
logging.info(f"Order {order_id} for {pair} is outside the {threshold_percent}% threshold, cancelling...") | ||
cancel_order(order_id, pair) | ||
else: | ||
logging.info(f"Order {order_id} for {pair} is within the threshold.") | ||
except ccxt.BaseError as e: | ||
logging.error(f"Error fetching price for {pair}: {str(e)}") | ||
|
||
def main(): | ||
# Set up argument parser to allow threshold configuration | ||
parser = argparse.ArgumentParser(description="Cancel Kraken orders outside of a price threshold.") | ||
parser.add_argument('--threshold', type=float, default=1.5, help="Percentage threshold to cancel orders outside the current price.") | ||
args = parser.parse_args() | ||
|
||
threshold_percent = args.threshold # Use the threshold passed in as an argument | ||
logging.info(f"Starting py_cancel.py with a {threshold_percent}% threshold.") | ||
|
||
process_orders(threshold_percent) | ||
|
||
if __name__ == "__main__": | ||
main() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
{ | ||
"kraken_pairs": { | ||
"kraken_pairs": { | ||
"BTCUSD": "XXBTZUSD", | ||
"ETHUSD": "XETHZUSD", | ||
"XRPUSD": "XXRPZUSD", | ||
"SOLUSD": "SOLUSD", | ||
"ADAUSD": "ADAUSD", | ||
"AVAXUSD": "AVAXUSD", | ||
"XMRUSD": "XMRUSD", | ||
"TRXUSD": "TRXUSD", | ||
"FETUSD": "FETUSD" | ||
} | ||
}, | ||
"price_precisions": { | ||
"BTC/USD": 1, | ||
"ETH/USD": 2, | ||
"XRP/USD": 4, | ||
"SOL/USD": 2, | ||
"ADA/USD": 5, | ||
"AVAX/USD": 2, | ||
"XMR/USD": 2, | ||
"TRX/USD": 6, | ||
"FET/USD": 4 | ||
|
||
}, | ||
"volume_precisions": { | ||
"BTC/USD": 4, | ||
"ETH/USD": 4, | ||
"XRP/USD": 0, | ||
"SOL/USD": 2, | ||
"ADA/USD": 0, | ||
"AVAX/USD": 2, | ||
"XMR/USD": 2, | ||
"TRX/USD": 0, | ||
"FET/USD": 4 | ||
}, | ||
"min_trade_sizes": { | ||
"BTC/USD": 0.0001, | ||
"ETH/USD": 0.002, | ||
"XRP/USD": 10.0, | ||
"SOL/USD": 0.04, | ||
"ADA/USD": 20.0, | ||
"AVAX/USD": 0.2, | ||
"XMR/USD": 0.03, | ||
"TRX/USD": 40, | ||
"FET/USD": 2.5 | ||
} | ||
} | ||
|
File renamed without changes.
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 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 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
Oops, something went wrong.