Wednesday, May 27, 2026Tech HubAboutContactAdvertiseNewsletter
Back to Home
How to Build a Crypto Trading Bot with CoinGlass API

How to Build a Crypto Trading Bot with CoinGlass API

Building a crypto trading bot is not just about writing a script that buys when price goes up and sells when price goes down. That kind of bot may work for a simple demo, but it is usually not enough for real crypto markets, especially if the bot trades futures, perpetual contracts, or leveraged...

B
Blizine Admin
·26 min read·0 views
Building a crypto trading bot is not just about writing a script that buys when price goes up and sells when price goes down. That kind of bot may work for a simple demo, but it is usually not enough for real crypto markets, especially if the bot trades futures, perpetual contracts, or leveraged positions. Crypto markets are heavily influenced by derivatives. A large price move may be caused by spot buying, but it may also be caused by: Open interest expansion Funding rate imbalance Short liquidations Long liquidations Leverage build-up Forced deleveraging Order book liquidity gaps Aggressive taker buy or sell pressure Cross-exchange positioning This is why a serious crypto trading bot needs more than price data. It needs market structure data. CoinGlass API is useful in this context because it provides access to key crypto derivatives data such as open interest, funding rates, liquidations, long/short ratios, order book data, options data, ETF flow data, and other market indicators. CoinGlass API V4 is the current recommended version, while V1–V3 are deprecated and mainly kept for backward compatibility. ([coinglass][1]) In this guide, we will walk through how to build a crypto trading bot using CoinGlass API as a market intelligence layer. The goal is not to build a perfect money-printing machine. The goal is to design a more market-aware trading bot that can understand when a signal is strong, when risk is elevated, and when it is better to stay out. 1. What Kind of Trading Bot Are We Building? Before writing code, we need to define the bot. A crypto trading bot can mean many different things: Bot Type Description Data Needed Price alert bot Sends alerts when price reaches a level Price data Trend-following bot Buys breakouts and sells breakdowns Price, volume, OI Grid bot Places buy and sell orders in a range Price, volatility, risk filters Funding rate bot Monitors funding rate opportunities Funding rate, OI, exchange data Liquidation alert bot Detects abnormal liquidation events Liquidation data Risk management bot Reduces exposure during extreme market stress OI, funding, liquidations Quant strategy bot Uses multiple factors to generate signals Historical and real-time data In this article, we will build a derivatives-aware trading bot framework. The bot will: Fetch market data from CoinGlass API Read open interest, funding rate, and liquidation data Convert raw data into trading features Generate market state signals Combine derivatives signals with a simple price signal Output a trading decision Adjust position size based on market risk This is a realistic architecture because CoinGlass API is best used as a market intelligence layer, while exchange APIs are usually used as the execution layer. 2. CoinGlass API vs Exchange API Many developers ask: Why not just use Binance API, OKX API, Bybit API, or another exchange API? The answer is simple: exchange APIs and CoinGlass API solve different problems. Function Exchange API CoinGlass API Place orders Yes No Manage account balance Yes No Read current position Yes No Get exchange-specific price Yes Sometimes, depending on endpoint Compare multiple exchanges Manual work needed More suitable Get aggregated derivatives data Harder Designed for this Get funding rate context Limited to exchange Broader derivatives view Get liquidation data Exchange-specific or limited More useful as an aggregated market signal Build market structure signals Requires heavy engineering More direct Execute trades Yes No A good trading system usually uses both: Exchange API = execution layer CoinGlass API = market intelligence layer The exchange API answers: Can I place this order? What is my account balance? What is my current position? CoinGlass API helps answer: Should I place this order? Is the market crowded? Is leverage building up? Are traders being liquidated? Is this breakout healthy? That distinction is important. A trading bot should not only know how to trade. It should also know when not to trade. 3. Why CoinGlass API Is Useful for Trading Bots CoinGlass provides a broad set of crypto market data. According to CoinGlass public API materials, its crypto API covers derivatives, spot, options, ETF markets, order book data, and market snapshot data such as price, volume, open interest, and funding rates. ([coinglass][2]) For trading bots, the most useful data categories are: Data Type Why It Matters Open Interest Shows whether leveraged capital is entering or leaving Funding Rate Measures long/short cost and crowding Liquidations Shows forced position closures Long/Short Ratio Helps detect positioning imbalance Taker Buy/Sell Volume Shows aggressive buying or selling pressure Order Book Data Helps analyze liquidity and execution risk Liquidation Heatmap Helps identify potential liquidation zones ETF Flow Data Useful for broader market flow analysis Options Data Useful for volatility and institutional positioning CoinGlass API official materials list futures modules such as open interest, funding rate, liquidation data, global long/short ratios, top trader long/short ratios, and taker buy/sell volume. Some example endpoint categories include /api/futures/openInterest/ohlc-history, /api/futures/fundingRate/oi-weight-ohlc-history, and /api/futures/liquidation/aggregated-history. ([coinglass][3]) These data points help the bot understand market state instead of only reacting to price. 4. Trading Bot Architecture A simple crypto trading bot architecture looks like this: Data Layer ↓ Feature Layer ↓ Signal Layer ↓ Risk Layer ↓ Execution Layer ↓ Logging / Monitoring Layer Let’s define each layer. Layer Purpose Data Layer Fetch raw market data from APIs Feature Layer Convert raw data into useful indicators Signal Layer Generate buy, sell, or hold signals Risk Layer Adjust position size and filter bad trades Execution Layer Place orders through exchange API Logging Layer Store decisions, errors, and performance data CoinGlass API sits mainly in the Data Layer, but its output is used heavily in the Feature, Signal, and Risk layers. A practical bot architecture may look like this: CoinGlass API - Open Interest - Funding Rate - Liquidation Data - Long/Short Ratio - Order Flow Exchange API - Price Candles - Account Balance - Order Placement - Position Management Trading Bot - Feature Engineering - Signal Generation - Risk Filtering - Position Sizing - Execution This article will focus on the CoinGlass API side and the strategy framework. You can connect the final decision output to your preferred exchange API. 5. Core Strategy Idea A common beginner bot does this: If price breaks above moving average → BUY If price breaks below moving average → SELL This is simple, but it ignores derivatives market structure. A better bot does this: If price gives BUY signal AND funding rate is not extremely high AND open interest supports the move AND liquidation risk is not extreme THEN allow the trade Otherwise, reduce size or skip the trade This is more realistic. The bot does not simply ask: Did price go up? It asks: Is this price move healthy? Is leverage supporting it? Is one side too crowded? Is the market entering a liquidation cascade? That is the main difference between a basic bot and a market-aware bot. 6. Key CoinGlass Data for the Bot For this trading bot, we will focus on three core data types: Open Interest Funding Rate Liquidation Data These three are enough to build a strong first version. 6.1 Open Interest Open Interest, or OI, measures the total open futures or perpetual contract positions. It helps answer: Is new leverage entering the market? Price Open Interest Possible Interpretation Price up OI up New positions support the move Price up OI down Shorts may be closing Price down OI up New shorts may be entering Price down OI down Longs may be closing or liquidated Price flat OI up Leverage is building before a possible breakout For bots, OI is useful because it helps confirm whether a price movement is supported by new market participation. Example: BTC price rises 3%. Open interest also rises. Funding rate remains neutral. This may be a healthier bullish trend. But: BTC price rises 3%. Open interest rises sharply. Funding rate becomes extremely positive. Long/short ratio becomes heavily long. This may be a crowded long environment. 6.2 Funding Rate Funding rate is the periodic payment between longs and shorts in perpetual futures. Funding Rate Meaning Positive Longs pay shorts Negative Shorts pay longs Extremely positive Longs may be crowded Extremely negative Shorts may be crowded Neutral Market is more balanced Funding rate is not a direct buy or sell signal. A common mistake is: Funding high = short Funding low = long That is too simple. A better interpretation is: Funding high = long side may be crowded Funding low = short side may be crowded Funding rate is best used as a filter. Examples: Price Signal Funding Rate Bot Action BUY Neutral Allow trade BUY Extremely positive Reduce size or skip SELL Neutral Allow trade SELL Extremely negative Reduce size or skip BUY Negative + short liquidations rising Possible short squeeze setup 6.3 Liquidation Data Liquidation data shows forced position closures. It helps answer: Which side is being forced out? Liquidation Event Interpretation Long liquidation spike Longs are being forced out Short liquidation spike Shorts are being squeezed Both sides liquidated Extreme volatility Liquidations decline Leverage pressure may be cooling Liquidation spike + price recovery Possible false breakdown or liquidity sweep Liquidation data is extremely useful for risk management. A bot can use it to: Avoid trading during liquidation cascades Detect short squeeze conditions Detect long squeeze conditions Reduce position size during market stress Avoid buying or selling after a move is already exhausted 7. API Setup CoinGlass API V4 uses the following base URL in public documentation and examples: https://open-api-v4.coinglass.com Requests generally use the CG-API-KEY header for authentication. CoinGlass documentation states that API V4 brings improved performance, faster response times, and optimized data retrieval. ([coinglass][4]) First, install the required Python packages: pip install requests pandas python-dotenv Create a .env file: COINGLASS_API_KEY=your_api_key_here Then create a Python file named: bot.py Basic API client: import os import requests import pandas as pd from dotenv import load_dotenv load_dotenv() BASE_URL = "https://open-api-v4.coinglass.com" API_KEY = os.getenv("COINGLASS_API_KEY") if not API_KEY: raise RuntimeError("Missing COINGLASS_API_KEY environment variable") HEADERS = { "CG-API-KEY": API_KEY, "Accept": "application/json" } def request_coinglass(endpoint, params=None): """ Send a GET request to CoinGlass API. """ url = f"{BASE_URL}{endpoint}" response = requests.get( url, headers=HEADERS, params=params, timeout=10 ) response.raise_for_status() return response.json() This function will be reused for all CoinGlass API requests. 8. Add Safe Request Handling Production bots should not crash because one API request fails. Let’s improve the request function with retries: import time def safe_request_coinglass(endpoint, params=None, retries=3, sleep_seconds=2): """ Send a GET request with retry logic. """ last_error = None for attempt in range(retries): try: return request_coinglass(endpoint, params) except requests.RequestException as error: last_error = error print(f"Request failed: attempt {attempt + 1}/{retries}: {error}") time.sleep(sleep_seconds) raise last_error This is important because live bots must handle: Network errors Timeout errors Temporary API issues Rate limits Invalid responses Missing data A trading bot should fail safely, not blindly continue with broken data. 9. Fetch Open Interest Data CoinGlass public API materials list Open Interest endpoints such as: /api/futures/openInterest/ohlc-history /api/futures/openInterest/aggregated-history /api/futures/openInterest/exchange-list For this example, we will use an OHLC-style history endpoint. Always verify endpoint names and parameters with the latest official documentation before production use. def fetch_open_interest(symbol="BTC", interval="1h", limit=100): endpoint = "/api/futures/openInterest/ohlc-history" params = { "symbol": symbol, "interval": interval, "limit": limit } return safe_request_coinglass(endpoint, params) Convert the response into a DataFrame: def to_dataframe(raw): """ Convert a CoinGlass API response to a pandas DataFrame. Adjust this function based on the actual response shape. """ data = raw.get("data", []) if isinstance(data, dict): # Some APIs may return nested structures. # Adjust based on actual response. rows = data.get("list", []) else: rows = data df = pd.DataFrame(rows) if df.empty: return df if "time" in df.columns: df["time"] = pd.to_datetime(df["time"], unit="ms", errors="coerce") return df Add OI features: def add_open_interest_features(df): data = df.copy() # Adjust field names based on actual API response. if "close" in data.columns: data["oi_close"] = pd.to_numeric(data["close"], errors="coerce") elif "openInterest" in data.columns: data["oi_close"] = pd.to_numeric(data["openInterest"], errors="coerce") else: raise ValueError("No recognizable open interest field found") data["oi_change"] = data["oi_close"].pct_change() data["oi_change_24"] = data["oi_close"].pct_change(24) return data 10. Fetch Funding Rate Data CoinGlass public materials list funding rate endpoints such as: /api/futures/fundingRate/ohlc-history /api/futures/fundingRate/oi-weight-ohlc-history /api/futures/fundingRate/exchange-list A bot can use funding rate to detect crowded long or short conditions. def fetch_funding_rate(symbol="BTC", interval="1h", limit=100): endpoint = "/api/futures/fundingRate/oi-weight-ohlc-history" params = { "symbol": symbol, "interval": interval, "limit": limit } return safe_request_coinglass(endpoint, params) Add funding rate features: def zscore(series, window=24): mean = series.rolling(window).mean() std = series.rolling(window).std() return (series - mean) / std def add_funding_features(df, window=24): data = df.copy() # Adjust field name based on actual API response. if "close" in data.columns: data["funding_close"] = pd.to_numeric(data["close"], errors="coerce") elif "fundingRate" in data.columns: data["funding_close"] = pd.to_numeric(data["fundingRate"], errors="coerce") else: raise ValueError("No recognizable funding rate field found") data["funding_z"] = zscore(data["funding_close"], window) return data Interpretation: Funding Z-score Meaning Above 2 Extremely positive funding 1 to 2 Moderately positive funding -1 to 1 Neutral -2 to -1 Moderately negative funding Below -2 Extremely negative funding This lets the bot detect whether the market is unusually long-heavy or short-heavy. 11. Fetch Liquidation Data CoinGlass public materials list liquidation endpoints such as: /api/futures/liquidation/history /api/futures/liquidation/aggregated-history /api/futures/liquidation/heatmap/model2 For this example: def fetch_liquidation_history( symbol="BTC", exchanges="Binance,OKX,Bybit", interval="1h", limit=100 ): endpoint = "/api/futures/liquidation/aggregated-history" params = { "exchange_list": exchanges, "symbol": symbol, "interval": interval, "limit": limit } return safe_request_coinglass(endpoint, params) Add liquidation features: def add_liquidation_features(df, window=24): data = df.copy() rename_map = { "longLiquidation": "long_liquidation", "shortLiquidation": "short_liquidation", "long_liq": "long_liquidation", "short_liq": "short_liquidation" } data = data.rename(columns=rename_map) if "long_liquidation" not in data.columns: raise ValueError("No long liquidation field found") if "short_liquidation" not in data.columns: raise ValueError("No short liquidation field found") data["long_liquidation"] = pd.to_numeric( data["long_liquidation"], errors="coerce" ) data["short_liquidation"] = pd.to_numeric( data["short_liquidation"], errors="coerce" ) data["long_liq_z"] = zscore(data["long_liquidation"], window) data["short_liq_z"] = zscore(data["short_liquidation"], window) data["total_liquidation"] = ( data["long_liquidation"] + data["short_liquidation"] ) data["total_liq_z"] = zscore(data["total_liquidation"], window) return data Interpretation: Liquidation Signal Meaning Long liquidation z-score > 2 Longs are being liquidated unusually Short liquidation z-score > 2 Shorts are being liquidated unusually Total liquidation z-score > 3 Extreme risk environment Liquidation z-score near 0 Normal environment 12. Merge Data into One Market Table Now we need to merge open interest, funding rate, and liquidation data by timestamp. def prepare_time_column(df): data = df.copy() if "time" not in data.columns: raise ValueError("Missing time column") data = data.dropna(subset=["time"]) data = data.sort_values("time") return data def merge_market_data(oi_df, funding_df, liquidation_df): oi = prepare_time_column(oi_df) funding = prepare_time_column(funding_df) liquidation = prepare_time_column(liquidation_df) merged = pd.merge_asof( oi, funding, on="time", direction="nearest", tolerance=pd.Timedelta("10min"), suffixes=("_oi", "_funding") ) merged = pd.merge_asof( merged, liquidation, on="time", direction="nearest", tolerance=pd.Timedelta("10min") ) return merged The merged table may include: Column Meaning time Timestamp oi_close Open interest value oi_change Short-term OI change oi_change_24 24-period OI change funding_close Funding rate funding_z Funding rate z-score long_liquidation Long liquidation amount short_liquidation Short liquidation amount long_liq_z Long liquidation z-score short_liq_z Short liquidation z-score total_liq_z Total liquidation z-score This table becomes the bot’s derivatives market state table. 13. Build a Simple Price Signal CoinGlass API can provide market data, but many bots still combine derivatives data with price signals. For simplicity, let’s create a moving average signal. In production, you may get price candles from: Your exchange API CoinGlass spot or futures market endpoints Your own database Another market data provider Example: def generate_price_signal(price_df): """ Simple moving average signal. price_df must contain a 'close' column. """ data = price_df.copy() data["close"] = pd.to_numeric(data["close"], errors="coerce") data["ma_fast"] = data["close"].rolling(20).mean() data["ma_slow"] = data["close"].rolling(60).mean() latest = data.iloc[-1] if latest["ma_fast"] > latest["ma_slow"]: return "BUY" if latest["ma_fast"] < latest["ma_slow"]: return "SELL" return "HOLD" This signal is intentionally simple. The purpose of the article is not to create a perfect price model, but to show how CoinGlass API data can improve the bot’s market awareness. 14. Build a Derivatives Signal Now let’s convert the merged derivatives data into a market state signal. def classify_derivatives_state(row): funding_z = row.get("funding_z", 0) long_liq_z = row.get("long_liq_z", 0) short_liq_z = row.get("short_liq_z", 0) total_liq_z = row.get("total_liq_z", 0) oi_change = row.get("oi_change", 0) if pd.isna(funding_z): funding_z = 0 if pd.isna(long_liq_z): long_liq_z = 0 if pd.isna(short_liq_z): short_liq_z = 0 if pd.isna(total_liq_z): total_liq_z = 0 if pd.isna(oi_change): oi_change = 0 if total_liq_z > 3: return "RISK_OFF" if funding_z > 2 and oi_change > 0: return "LONG_CROWDED" if funding_z < -2 and oi_change > 0: return "SHORT_CROWDED" if short_liq_z > 2 and funding_z < 0: return "SHORT_SQUEEZE" if long_liq_z > 2 and funding_z > 0: return "LONG_SQUEEZE" return "NEUTRAL" Signal meanings: Signal Meaning NEUTRAL Market structure is normal LONG_CROWDED Long side may be overcrowded SHORT_CROWDED Short side may be overcrowded SHORT_SQUEEZE Shorts may be getting forced out LONG_SQUEEZE Longs may be getting forced out RISK_OFF Extreme liquidation environment This is the core logic of a derivatives-aware bot. 15. Combine Price Signal and Derivatives Signal Now combine the basic price signal with the CoinGlass-driven market state. def final_trading_decision(price_signal, derivatives_state): """ Combine price signal with derivatives market state. """ if derivatives_state == "RISK_OFF": return "HOLD" if price_signal == "BUY" and derivatives_state == "LONG_CROWDED": return "HOLD" if price_signal == "SELL" and derivatives_state == "SHORT_CROWDED": return "HOLD" if price_signal == "BUY" and derivatives_state == "SHORT_SQUEEZE": return "BUY" if price_signal == "SELL" and derivatives_state == "LONG_SQUEEZE": return "SELL" if derivatives_state in ["NEUTRAL", "SHORT_SQUEEZE", "LONG_SQUEEZE"]: return price_signal return "HOLD" Examples: Price Signal Derivatives State Final Decision BUY NEUTRAL BUY BUY LONG_CROWDED HOLD SELL SHORT_CROWDED HOLD BUY SHORT_SQUEEZE BUY SELL LONG_SQUEEZE SELL BUY RISK_OFF HOLD SELL RISK_OFF HOLD This logic helps the bot avoid bad trades. It does not guarantee profit, but it can reduce the likelihood of chasing crowded or unstable market conditions. 16. Add Position Sizing A trading bot should not only decide whether to trade. It should also decide how much to trade. def position_size_multiplier(derivatives_state): multipliers = { "NEUTRAL": 1.0, "SHORT_SQUEEZE": 1.0, "LONG_SQUEEZE": 1.0, "LONG_CROWDED": 0.4, "SHORT_CROWDED": 0.4, "RISK_OFF": 0.0 } return multipliers.get(derivatives_state, 0.5) Example: base_position_size = 1000 # USDT notional derivatives_state = "LONG_CROWDED" final_size = base_position_size * position_size_multiplier(derivatives_state) print(final_size) If the market is neutral, the bot may use normal size. If the market is crowded, it may reduce size. If the market is in risk-off mode, it does not trade. This is often more useful than simply changing buy/sell signals. 17. Full Bot Framework Example Below is a simplified full example. It does not place real orders. Instead, it outputs a final trading decision. This is safer for demonstration and easier to adapt. import os import time import requests import pandas as pd from dotenv import load_dotenv load_dotenv() BASE_URL = "https://open-api-v4.coinglass.com" API_KEY = os.getenv("COINGLASS_API_KEY") if not API_KEY: raise RuntimeError("Missing COINGLASS_API_KEY environment variable") HEADERS = { "CG-API-KEY": API_KEY, "Accept": "application/json" } def request_coinglass(endpoint, params=None): url = f"{BASE_URL}{endpoint}" response = requests.get( url, headers=HEADERS, params=params, timeout=10 ) response.raise_for_status() return response.json() def safe_request_coinglass(endpoint, params=None, retries=3, sleep_seconds=2): last_error = None for attempt in range(retries): try: return request_coinglass(endpoint, params) except requests.RequestException as error: last_error = error print(f"Request failed: attempt {attempt + 1}/{retries}: {error}") time.sleep(sleep_seconds) raise last_error def to_dataframe(raw): data = raw.get("data", []) if isinstance(data, dict): rows = data.get("list", []) else: rows = data df = pd.DataFrame(rows) if df.empty: return df if "time" in df.columns: df["time"] = pd.to_datetime(df["time"], unit="ms", errors="coerce") return df def zscore(series, window=24): mean = series.rolling(window).mean() std = series.rolling(window).std() return (series - mean) / std def fetch_open_interest(symbol="BTC", interval="1h", limit=100): endpoint = "/api/futures/openInterest/ohlc-history" params = { "symbol": symbol, "interval": interval, "limit": limit } return safe_request_coinglass(endpoint, params) def fetch_funding_rate(symbol="BTC", interval="1h", limit=100): endpoint = "/api/futures/fundingRate/oi-weight-ohlc-history" params = { "symbol": symbol, "interval": interval, "limit": limit } return safe_request_coinglass(endpoint, params) def fetch_liquidation_history( symbol="BTC", exchanges="Binance,OKX,Bybit", interval="1h", limit=100 ): endpoint = "/api/futures/liquidation/aggregated-history" params = { "exchange_list": exchanges, "symbol": symbol, "interval": interval, "limit": limit } return safe_request_coinglass(endpoint, params) def add_open_interest_features(df): data = df.copy() if "close" in data.columns: data["oi_close"] = pd.to_numeric(data["close"], errors="coerce") elif "openInterest" in data.columns: data["oi_close"] = pd.to_numeric(data["openInterest"], errors="coerce") else: raise ValueError("No recognizable open interest field found") data["oi_change"] = data["oi_close"].pct_change() data["oi_change_24"] = data["oi_close"].pct_change(24) return data def add_funding_features(df, window=24): data = df.copy() if "close" in data.columns: data["funding_close"] = pd.to_numeric(data["close"], errors="coerce") elif "fundingRate" in data.columns: data["funding_close"] = pd.to_numeric( data["fundingRate"], errors="coerce" ) else: raise ValueError("No recognizable funding rate field found") data["funding_z"] = zscore(data["funding_close"], window) return data def add_liquidation_features(df, window=24): data = df.copy() data = data.rename(columns={ "longLiquidation": "long_liquidation", "shortLiquidation": "short_liquidation", "long_liq": "long_liquidation", "short_liq": "short_liquidation" }) if "long_liquidation" not in data.columns: raise ValueError("No long liquidation field found") if "short_liquidation" not in data.columns: raise ValueError("No short liquidation field found") data["long_liquidation"] = pd.to_numeric( data["long_liquidation"], errors="coerce" ) data["short_liquidation"] = pd.to_numeric( data["short_liquidation"], errors="coerce" ) data["long_liq_z"] = zscore(data["long_liquidation"], window) data["short_liq_z"] = zscore(data["short_liquidation"], window) data["total_liquidation"] = ( data["long_liquidation"] + data["short_liquidation"] ) data["total_liq_z"] = zscore(data["total_liquidation"], window) return data def prepare_time_column(df): data = df.copy() if "time" not in data.columns: raise ValueError("Missing time column") data = data.dropna(subset=["time"]) data = data.sort_values("time") return data def merge_market_data(oi_df, funding_df, liquidation_df): oi = prepare_time_column(oi_df) funding = prepare_time_column(funding_df) liquidation = prepare_time_column(liquidation_df) merged = pd.merge_asof( oi, funding, on="time", direction="nearest", tolerance=pd.Timedelta("10min"), suffixes=("_oi", "_funding") ) merged = pd.merge_asof( merged, liquidation, on="time", direction="nearest", tolerance=pd.Timedelta("10min") ) return merged def classify_derivatives_state(row): funding_z = row.get("funding_z", 0) long_liq_z = row.get("long_liq_z", 0) short_liq_z = row.get("short_liq_z", 0) total_liq_z = row.get("total_liq_z", 0) oi_change = row.get("oi_change", 0) values = [funding_z, long_liq_z, short_liq_z, total_liq_z, oi_change] values = [0 if pd.isna(v) else v for v in values] funding_z, long_liq_z, short_liq_z, total_liq_z, oi_change = values if total_liq_z > 3: return "RISK_OFF" if funding_z > 2 and oi_change > 0: return "LONG_CROWDED" if funding_z < -2 and oi_change > 0: return "SHORT_CROWDED" if short_liq_z > 2 and funding_z < 0: return "SHORT_SQUEEZE" if long_liq_z > 2 and funding_z > 0: return "LONG_SQUEEZE" return "NEUTRAL" def final_trading_decision(price_signal, derivatives_state): if derivatives_state == "RISK_OFF": return "HOLD" if price_signal == "BUY" and derivatives_state == "LONG_CROWDED": return "HOLD" if price_signal == "SELL" and derivatives_state == "SHORT_CROWDED": return "HOLD" if price_signal == "BUY" and derivatives_state == "SHORT_SQUEEZE": return "BUY" if price_signal == "SELL" and derivatives_state == "LONG_SQUEEZE": return "SELL" if derivatives_state in ["NEUTRAL", "SHORT_SQUEEZE", "LONG_SQUEEZE"]: return price_signal return "HOLD" def position_size_multiplier(derivatives_state): multipliers = { "NEUTRAL": 1.0, "SHORT_SQUEEZE": 1.0, "LONG_SQUEEZE": 1.0, "LONG_CROWDED": 0.4, "SHORT_CROWDED": 0.4, "RISK_OFF": 0.0 } return multipliers.get(derivatives_state, 0.5) def run_bot_once(symbol="BTC"): oi_raw = fetch_open_interest(symbol=symbol, interval="1h", limit=100) funding_raw = fetch_funding_rate(symbol=symbol, interval="1h", limit=100) liquidation_raw = fetch_liquidation_history( symbol=symbol, interval="1h", limit=100 ) oi_df = add_open_interest_features(to_dataframe(oi_raw)) funding_df = add_funding_features(to_dataframe(funding_raw)) liquidation_df = add_liquidation_features(to_dataframe(liquidation_raw)) market_df = merge_market_data(oi_df, funding_df, liquidation_df) if market_df.empty: raise ValueError("Merged market data is empty") latest = market_df.iloc[-1] # Example only. Replace this with your real price signal. price_signal = "BUY" derivatives_state = classify_derivatives_state(latest) final_decision = final_trading_decision(price_signal, derivatives_state) base_position_size = 1000 multiplier = position_size_multiplier(derivatives_state) final_position_size = base_position_size * multiplier result = { "symbol": symbol, "time": latest["time"], "price_signal": price_signal, "derivatives_state": derivatives_state, "final_decision": final_decision, "position_size": final_position_size } return result if __name__ == "__main__": result = run_bot_once("BTC") print("Bot result:") for key, value in result.items(): print(f"{key}: {value}") This bot framework does not place orders. That is intentional. Before connecting any strategy to real trading, you should: Backtest it Paper trade it Add exchange execution logic Add risk limits Add error handling Add logs Add monitoring Start with small position size 18. How to Add Exchange Execution Once the CoinGlass API side works, you can connect the decision output to an exchange API. The execution layer should be separate from the signal layer. Example structure: def execute_trade(decision, symbol, position_size): """ Placeholder execution function. Replace with your exchange API logic. """ if decision == "BUY": print(f"Place BUY order for {symbol}, size={position_size}") elif decision == "SELL": print(f"Place SELL order for {symbol}, size={position_size}") else: print(f"No trade for {symbol}") Then: result = run_bot_once("BTC") execute_trade( decision=result["final_decision"], symbol=result["symbol"], position_size=result["position_size"] ) In production, the execution function should handle: Order type Quantity precision Minimum notional Slippage Leverage Margin mode Reduce-only orders Stop loss Take profit Position checking Order status confirmation Never connect a strategy directly to live execution without safety checks. 19. Risk Management Rules A trading bot without risk management is not a trading system. It is just an automated order sender. At minimum, your bot should include: Rule Purpose Max position size Prevent oversized trades Max daily loss Stop trading after major losses Max open positions Avoid overexposure Stop loss Limit downside Take profit Lock gains Cooldown period Avoid overtrading Risk-off mode Stop trading during extreme events API failure mode Avoid trading with stale data Example risk filter: def risk_filter(account_state, market_state): """ Example risk control logic. """ if account_state["daily_loss_pct"] < -3: return "STOP_TRADING" if account_state["open_positions"] >= account_state["max_positions"]: return "NO_NEW_POSITIONS" if market_state["derivatives_state"] == "RISK_OFF": return "NO_NEW_POSITIONS" return "ALLOW" Risk management should override signal generation. A good rule is: Signal decides what you want to do. Risk decides whether you are allowed to do it. 20. Backtesting the Strategy Before using real money, backtest the bot. A proper backtest should include: Price candles Open interest history Funding rate history Liquidation history Trading fees Slippage Funding payments Latency assumptions Position size rules Stop loss logic Market regime changes A basic backtest loop may look like this: def backtest(market_df, price_signals): equity = 10000 position = 0 trades = [] for i in range(len(market_df)): row = market_df.iloc[i] price_signal = price_signals[i] derivatives_state = classify_derivatives_state(row) decision = final_trading_decision(price_signal, derivatives_state) size_multiplier = position_size_multiplier(derivatives_state) trades.append({ "time": row["time"], "price_signal": price_signal, "derivatives_state": derivatives_state, "decision": decision, "size_multiplier": size_multiplier }) return pd.DataFrame(trades) This is only a skeleton. A real backtest must calculate: Entry price Exit price PnL Fees Funding payments Drawdown Sharpe ratio Win rate Average profit/loss Maximum loss Exposure time Do not skip this step. A strategy that looks good in a single example may fail across different market regimes. 21. Production Checklist Before putting a CoinGlass API-powered trading bot into production, use this checklist. Checklist Item Why It Matters Confirm latest API endpoints API routes and parameters may change Confirm response fields Field names may differ by endpoint Store API key securely Prevent credential leaks Add request retries Handle temporary errors Add timeout handling Prevent stuck processes Add data validation Avoid trading on broken data Add stale data checks Avoid using old signals Add rate limit handling Prevent API blocking Add logs Debug strategy behavior Add paper trading Validate real-time behavior Add risk limits Prevent catastrophic loss Add monitoring alerts Detect failures quickly Add manual shutdown Stop bot during emergencies Start small Reduce deployment risk Example stale data check: def check_data_freshness(latest_time, max_age_minutes=90): now = pd.Timestamp.utcnow() if latest_time.tzinfo is None: latest_time = latest_time.tz_localize("UTC") age = now - latest_time if age > pd.Timedelta(minutes=max_age_minutes): raise ValueError(f"Data is stale: latest data age is {age}") return True 22. Common Mistakes Mistake 1: Using Funding Rate as a Standalone Signal Funding rate should not be used alone. Wrong: Funding high → short Funding low → long Better: Funding high → long side may be crowded Funding low → short side may be crowded Confirm with OI, price, and liquidation data Mistake 2: Entering Immediately After Liquidations A liquidation spike can mean a reversal, but it can also mean trend continuation. You need to check: Did price reclaim the level? Did open interest drop? Did funding normalize? Did volume fade? Did the liquidation cascade continue? Mistake 3: Ignoring Open Interest Price without OI context can be misleading. Price Move OI Move Possible Meaning Up Up New longs or new positions support the move Up Down Shorts closing Down Up New shorts entering Down Down Longs closing or liquidating Mistake 4: Overfitting Too Many Indicators Start simple. A practical first version can use: Price signal + OI confirmation + Funding filter + Liquidation risk filter + Position sizing rule Then test improvements one by one. Mistake 5: No Kill Switch Every live bot needs a manual and automatic kill switch. Examples: Stop trading if API data is stale. Stop trading if daily loss exceeds threshold. Stop trading if liquidation risk is extreme. Stop trading if exchange order API behaves unexpectedly. 23. Strategy Templates You Can Build with CoinGlass API Template 1: Trend Confirmation Bot Goal: Trade only when price trend is supported by derivatives data. Rules: Condition Requirement Price Breakout or moving average trend Open Interest Rising gradually Funding Rate Not extreme Liquidations No abnormal opposite-side risk Decision Allow trade Best for: BTC trend strategies ETH momentum strategies Multi-asset futures bots Template 2: Short Squeeze Bot Goal: Detect possible short squeeze setups. Rules: Condition Requirement Funding Rate Negative Open Interest High or rising Price Breaks resistance Short Liquidations Rising Decision Allow long signal Best for: Breakout bots Momentum bots Event-driven strategies Template 3: Long Squeeze Risk Filter Goal: Avoid long exposure when the long side is overcrowded. Rules: Condition Requirement Funding Rate Very positive Open Interest Rising Price Breaks support Long Liquidations Rising Decision Exit, reduce, or avoid longs Best for: Grid bots Long-biased bots Leveraged futures strategies Template 4: Funding Rate Arbitrage Monitor Goal: Detect cross-exchange funding rate opportunities. Rules: Condition Requirement Funding difference Large enough Liquidity Sufficient Open Interest Stable Liquidation risk Not extreme Decision Alert or evaluate trade Best for: Market-neutral strategies Funding capture bots Arbitrage dashboards Template 5: Risk-Off Detector Goal: Pause trading during extreme derivatives stress. Rules: Condition Trigger Total liquidation z-score Above 3 Funding z-score Extreme OI change Abnormal Price volatility High Decision Pause trading Best for: All leveraged bots Portfolio risk systems Multi-strategy trading platforms 24. How to Expand the Bot After building the first version, you can expand it with more CoinGlass API data. Add Long/Short Ratio Use long/short ratio to detect market sentiment imbalance. Possible rule: If long/short ratio is extremely long AND funding is positive AND OI is rising THEN reduce long exposure. Add Taker Buy/Sell Volume Use taker buy/sell volume to confirm aggressive flow. Possible rule: If price breaks resistance AND taker buy volume rises AND short liquidations rise THEN confirm short squeeze. Add Liquidation Heatmap Use liquidation heatmap data to identify zones where forced liquidations may occur. Possible rule: If price approaches large liquidation cluster THEN reduce leverage or tighten stop. Add Order Book Data Use order book data for execution quality. Possible rule: If order book depth is thin THEN reduce order size or use limit orders. Add ETF Flow Data For BTC and ETH, ETF flow data can help detect broader market demand. Possible rule: If ETF inflows are strong AND derivatives data is not overheated THEN increase bullish confidence. 25. Final Thoughts Building a crypto trading bot is not just about coding buy and sell rules. A strong bot needs to understand market conditions. Price tells you what happened. Derivatives data helps explain why it happened. CoinGlass API can help trading bots move from simple price-based automation to a more complete market-aware system by providing data such as: Open interest Funding rate Liquidations Long/short ratio Taker buy/sell volume Order book data Liquidation heatmap ETF flow data Options data A basic bot might say: Price is above the moving average, so buy. A better bot says: Price is above the moving average. Open interest is rising. Funding rate is neutral. Liquidations are normal. Market structure is healthy. Buy signal is allowed. Or: Price is above the moving average. But funding is extremely positive. Open interest is rising too fast. Long side is crowded. Do not chase. That is the difference between a simple script and a more intelligent trading system. No API can guarantee profitable trading. CoinGlass API does not replace strategy design, risk management, execution quality, or backtesting. But it can provide the derivatives market intelligence that many trading bots are missing. If you are building a crypto futures or perpetual trading bot, CoinGlass API is one of the most practical ways to add market structure awareness to your system.

📰Originally published at dev.to

Comments