Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
malciller committed Nov 17, 2024
2 parents 16ec4a6 + d00e050 commit 44f7ec6
Show file tree
Hide file tree
Showing 20 changed files with 1,261 additions and 47 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ venv/

# Ignore logs
logs/

#ignore supporting .sh scripts
*.sh

#ignore supporting .py scripts
p_cancel.py
cron.py
31 changes: 0 additions & 31 deletions config.json

This file was deleted.

124 changes: 124 additions & 0 deletions random_scenario_test.py
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()
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
websockets
asyncio
requests
python-dotenv
numpy
120 changes: 120 additions & 0 deletions v1/cancel.py
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()
50 changes: 50 additions & 0 deletions v1/config.json
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.
2 changes: 1 addition & 1 deletion kraken_utils/api.py → v1/kraken_utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
API_SECRET = os.getenv("KRAKEN_API_SECRET")

# Set logging level to ERROR to suppress INFO messages
logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.ERROR)

class KrakenAuthBuilder:
def __init__(self, api_key: str, api_secret: str):
Expand Down
2 changes: 1 addition & 1 deletion kraken_utils/fetcher.py → v1/kraken_utils/fetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .api import KrakenAuthBuilder

# Set logging level to ERROR to suppress INFO messages
logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.ERROR)


class CryptoPriceFetcher:
Expand Down
2 changes: 1 addition & 1 deletion kraken_utils/market.py → v1/kraken_utils/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .fetcher import CryptoPriceFetcher

# Set logging level to ERROR to suppress INFO messages
logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.ERROR)

class PositionTracker:
def __init__(self):
Expand Down
Loading

0 comments on commit 44f7ec6

Please sign in to comment.