Every crypto exchange wants my passport, my address, and a selfie. I said no. Here's how I manage and rebalance my portfolio without KYC.
The Problem
Traditional portfolio trackers like CoinGecko and Delta work fine — until you want to actually act on the data. Then you need an exchange account, which means KYC verification, which means handing over your identity to a company that might get hacked next year.
I wanted: automated tracking + automated rebalancing + zero identity verification.
The Stack
- Data: CoinGecko API (free tier, no account needed for basic calls)
- Execution: SimpleSwap API (no KYC exchanges)
- Orchestration: Python + cron
- Storage: Local SQLite database
Step 1: Price Tracking
import requests, sqlite3, time
def get_prices(coins):
ids = ",".join(coins)
resp = requests.get(
"https://api.coingecko.com/api/v3/simple/price",
params={"ids": ids, "vs_currencies": "usd"}
)
return resp.json()
# Store in SQLite
def log_prices(prices):
conn = sqlite3.connect("portfolio.db")
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS prices
(timestamp INTEGER, coin TEXT, price REAL)""")
for coin, data in prices.items():
c.execute("INSERT INTO prices VALUES (?, ?, ?)",
(int(time.time()), coin, data["usd"]))
conn.commit()
conn.close()
Step 2: Rebalancing Logic
My target allocation: 50% BTC, 30% ETH, 20% XMR. When any asset drifts more than 5% from target, I rebalance.
TARGET = {"bitcoin": 0.50, "ethereum": 0.30, "monero": 0.20}
DRIFT_THRESHOLD = 0.05
def check_rebalance(holdings, prices):
total_value = sum(holdings[c] * prices[c]["usd"] for c in holdings)
for coin in holdings:
current_pct = (holdings[coin] * prices[coin]["usd"]) / total_value
target_pct = TARGET[coin]
drift = abs(current_pct - target_pct)
if drift > DRIFT_THRESHOLD:
return True, coin, current_pct, target_pct
return False, None, None, None
Step 3: Execute via SimpleSwap
When rebalancing is needed, I use SimpleSwap's API:
def execute_swap(from_coin, to_coin, amount):
resp = requests.post("https://api.simpleswap.io/create_exchange", json={
"api_key": SWAP_API_KEY,
"currency_from": from_coin,
"currency_to": to_coin,
"amount": amount,
"address_to": MY_WALLETS[to_coin],
})
return resp.json()
No accounts. No verification. Just API key + crypto addresses.
Step 4: The Main Loop
import schedule
def portfolio_check():
coins = list(TARGET.keys())
prices = get_prices(coins)
log_prices(prices)
needs_rebal, coin, current, target = check_rebalance(HOLDINGS, prices)
if needs_rebal:
print(f"Rebalancing needed: {coin} at {current:.1%} (target: {target:.1%})")
# Calculate and execute swap
# ...
schedule.every(1).hours.do(portfolio_check)
The Results
Running this for 6 months:
- Total rebalances triggered: 14
- Average drift before rebalance: 6.2%
- Total fees paid: ~$45 (mostly SimpleSwap's spread)
- Identity information shared: Zero
Compare this to using a centralized exchange for the same strategy. You'd pay similar fees but hand over your ID, bank details, and transaction history to a third party.
Security Notes
- Private keys stay on my hardware wallet — the bot only has view-only access to check balances
- Swap amounts are capped at 5% of total portfolio per transaction
- All API keys are stored in environment variables, not in code
- The bot runs on a dedicated VPS, not my personal machine
Getting Started
Check no-kyc-exchanges.vercel.app for a comparison of all major no-KYC exchanges — fees, speed, supported coins, everything you need to pick the right one.
If you want to try SimpleSwap specifically, here's a link that supports this blog at no extra cost to you.
Privacy isn't about hiding. It's about controlling who gets your data. This setup gives me full control.
Top comments (0)