Volume Weighted Average Price (VWAP) is a commonly used reference for evaluating the relationship between price and traded volume. Unlike a simple average price, VWAP incorporates trading volume into the calculation, allowing traders to evaluate a volume-weighted price level. This makes VWAP useful as a reference when assessing whether market prices are trading around, above, or below a volume-weighted benchmark.
This project develops a Crypto VWAP Trading Intelligence System using the MarketFlow API. The analysis focuses on BTCUSDT and retrieves VWAP data together with the available indicator catalog. The system is organized into five cells covering API configuration, VWAP retrieval, data normalization, market analysis, and the final trader dashboard. crypto_vwap_trading_intelligenc…
The analysis is deliberately designed to distinguish between available information and unavailable information. The VWAP endpoint provides a VWAP value and total volume, but the response does not provide a comparable current market price. Therefore, the system does not incorrectly use VWAP as a substitute for the latest price. Price deviation and a directional trading signal remain unavailable until an additional time-compatible market price is obtained. crypto_vwap_trading_intelligenc…
Cell 1 — Configuration and API Setup
The first cell imports the required Python libraries and establishes the MarketFlow API connection. Requests handles API communication, NumPy supports numerical calculations, Pandas manages structured data, Matplotlib is used for visualization, and IPython Display presents the resulting tables.
The API host and base URL are configured, while the RapidAPI key is retrieved from the environment variable RAPIDAPI_KEY. If the environment variable is unavailable, the notebook requests the API key through getpass() so that the credential is not displayed directly. The analysis is configured for BTCUSDT with a default limit of 100. crypto_vwap_trading_intelligenc…
# CELL 2 — AUTO FIX VWAP API + INDICATOR LIST
import requests
import json
import time
def get_api(path, params=None):
try:
r = requests.get(
BASE_URL + path,
headers=HEADERS,
params=params,
timeout=35
)
try:
data = r.json()
except ValueError:
data = {"message": r.text[:500]}
return r.status_code, data
except requests.RequestException as e:
return 0, {"message": str(e)}
# =========================================
# 1. FETCH VWAP DENGAN PARAMETER ALTERNATIF
# =========================================
vwap_raw = None
candidates = [
{"symbol": SYMBOL},
{"symbol": SYMBOL, "limit": 10},
{"symbol": SYMBOL, "limit": 20},
{"symbol": SYMBOL, "limit": 50},
{"symbol": SYMBOL, "limit": 5},
{"symbol": SYMBOL, "limit": 1},
]
for params in candidates:
status, data = get_api(
"/tools/crypto/vwap",
params
)
print(f"Testing {params} -> HTTP {status}")
if status == 200 and not (
isinstance(data, dict) and (
data.get("success") is False or
data.get("error")
)
):
vwap_raw = data
print("\nVWAP API SUCCESS")
print(json.dumps(data, indent=2, default=str)[:2500])
break
else:
message = (
data.get("message", data.get("error", ""))
if isinstance(data, dict)
else str(data)
)
print("API Message:", str(message)[:300])
if status in (401, 403, 429):
print("Request dihentikan karena masalah akses atau kuota.")
break
time.sleep(0.5)
# =========================================
# 2. FETCH INDICATOR CATALOG
# =========================================
status, indicators_raw = get_api(
"/tools/indicator/list"
)
if status != 200:
indicators_raw = None
print("\n" + "=" * 60)
print("API DATA STATUS")
print("=" * 60)
print("VWAP:", "AVAILABLE" if vwap_raw is not None else "FAILED")
print("INDICATORS:", "AVAILABLE" if indicators_raw is not None else "FAILED")
if vwap_raw is None:
print("\nVWAP endpoint belum menghasilkan data.")
print("Periksa pesan validasi parameter yang tercetak di atas.")This configuration establishes the authentication structure used by the remaining cells. Keeping the API key outside the published source code is important when the notebook is shared publicly.
Cell 2 — VWAP API Retrieval and Indicator Catalog
The second cell creates a reusable get_api() function for MarketFlow API requests. The function returns both the HTTP status code and the decoded response.
The VWAP endpoint is tested with several parameter combinations. The system starts with the symbol alone and then attempts alternative limit values. This approach allows the notebook to identify a parameter configuration accepted by the endpoint instead of assuming that one request format will always work. crypto_vwap_trading_intelligenc…
The cell also retrieves the MarketFlow indicator catalog from /tools/indicator/list and reports whether VWAP and the indicator catalog are available. A separate diagnostic request displays the HTTP status, content type, response URL, raw response, and JSON structure when available. crypto_vwap_trading_intelligenc…
import json
import requests
url = f"{BASE_URL}/tools/crypto/vwap"
response = requests.get(
url,
headers=HEADERS,
params={
"symbol": "BTCUSDT",
"limit": 100
},
timeout=35
)
print("=" * 65)
print("VWAP API DIAGNOSTIC")
print("=" * 65)
print("HTTP Status :", response.status_code)
print("Content Type:", response.headers.get("Content-Type"))
print("Response URL:", response.url)
try:
data = response.json()
print("\nRAW RESPONSE:")
print(json.dumps(data, indent=2, ensure_ascii=False)[:6000])
print("\nDATA STRUCTURE:")
print("Root type:", type(data).__name__)
if isinstance(data, dict):
print("Root keys:", list(data.keys()))
except ValueError:
print("\nNON-JSON RESPONSE:")
print(response.text[:3000])The resulting status output distinguishes whether the VWAP endpoint and indicator catalog are available. This is useful because later analytical calculations should only be performed when the underlying API data are actually available.
Cell 3 — Normalize VWAP and Indicator Data
The third cell converts the raw VWAP response into a structured DataFrame. The extracted fields are Symbol, VWAP, Total_Volume, Limit, and Weight.
The indicator response is processed through extract_indicators(), which supports several possible response structures such as indicators, data, results, and items. The resulting indicator catalog is then converted into a DataFrame. crypto_vwap_trading_intelligenc…
# ============================================================# CELL 3 — NORMALISASI VWAP & INDICATOR CATALOG# ============================================================def extract_indicators(obj): if isinstance(
# CELL 3 — NORMALISASI VWAP & INDICATOR CATALOG
def extract_indicators(obj):
if isinstance(obj, list):
return obj
if isinstance(obj, dict):
for key in ("indicators", "data", "results", "items"):
if isinstance(obj.get(key), list):
return obj[key]
return []
vwap_data = vwap_raw if isinstance(vwap_raw, dict) else {}
vwap_df = pd.DataFrame([{
"Symbol": vwap_data.get("symbol", SYMBOL),
"VWAP": pd.to_numeric(vwap_data.get("vwap"), errors="coerce"),
"Total_Volume": pd.to_numeric(
vwap_data.get("total_volume"), errors="coerce"
),
"Limit": vwap_data.get("limit"),
"Weight": vwap_data.get("weight")
}])
indicator_df = pd.DataFrame(
extract_indicators(indicators_raw)
)
print("=" * 65)
print("VWAP DATA")
print("=" * 65)
display(vwap_df)
print("\nINDICATOR CATALOG")
print("Total indicators:", len(indicator_df))
if not indicator_df.empty:
display(indicator_df)
print("\nData successfully normalized.")
Normalization creates a clean data layer for the analytical stage. At this point, the system has a structured VWAP value and total volume together with the available indicator catalog.
Cell 4 — VWAP Market Analysis
The fourth cell performs the analytical validation. The code explicitly sets Price and Deviation_% to unavailable because the VWAP endpoint does not return a comparable current market price.
This distinction is technically important. VWAP is a reference value, but it should not be treated as the current price simply because both variables have price units. Without a synchronized market price, calculating:
\[ Deviation = \frac{Price-VWAP}{VWAP} \times100 \]
would not be valid.
The system therefore assigns UNAVAILABLE to Market_Bias and INSUFFICIENT DATA to Trading_Signal. It separately validates whether the VWAP and total volume are available. crypto_vwap_trading_intelligenc…
# CELL 4 — VWAP MARKET ANALYSIS
analysis = vwap_df.copy()
# Harga terakhir tidak tersedia dalam respons endpoint VWAP.
# Jangan gunakan VWAP sebagai pengganti last price.
analysis["Price"] = np.nan
analysis["Deviation_%"] = np.nan
analysis["Market_Bias"] = "UNAVAILABLE"
analysis["Trading_Signal"] = "INSUFFICIENT DATA"
# Validasi VWAP
analysis["VWAP_Valid"] = (
analysis["VWAP"].notna()
& (analysis["VWAP"] > 0)
)
# Ketersediaan volume
analysis["Volume_Valid"] = (
analysis["Total_Volume"].notna()
& (analysis["Total_Volume"] >= 0)
)
# Metadata tersedia, tetapi semantik weight belum diverifikasi.
analysis["Data_Status"] = np.where(
analysis["VWAP_Valid"] & analysis["Volume_Valid"],
"VWAP AVAILABLE",
"INCOMPLETE"
)
print("=" * 70)
print("BTCUSDT VWAP ANALYSIS")
print("=" * 70)
display(analysis[[
"Symbol",
"VWAP",
"Total_Volume",
"Limit",
"Weight",
"Market_Bias",
"Trading_Signal",
"Data_Status"
]])
if analysis["VWAP_Valid"].any():
print("\nVWAP tersedia untuk referensi harga.")
print("Price deviation dan trading signal memerlukan")
print("harga pasar tambahan yang sebanding secara waktu.")
This cell prevents a common analytical error: treating the existence of a VWAP value as sufficient evidence for a bullish or bearish trading signal.
The current output can confirm that VWAP is available, but it cannot establish whether BTCUSDT is trading above or below VWAP at the same point in time. A synchronized market-price dataset is therefore required before a directional signal can be calculated.
Cell 5 — Crypto VWAP Trader Dashboard
The fifth cell produces the final dashboard for BTCUSDT. It displays the available VWAP, total volume, API limit, weight metadata, data status, and current trading signal.
The visualization contains two components. The first presents the VWAP as a reference price level. The second summarizes the available indicator catalog by category when the category field is available. The cell also generates a trading-analysis summary table and exports the analysis, indicator catalog, and raw VWAP response to files. crypto_vwap_trading_intelligenc…
# CELL 5 — CRYPTO VWAP TRADER DASHBOARD
from IPython.display import display
import matplotlib.pyplot as plt
print("=" * 72)
print(f"CRYPTO VWAP TRADER DASHBOARD | {SYMBOL}")
print("=" * 72)
valid = analysis.loc[analysis["VWAP_Valid"]]
if valid.empty:
print("Tidak ada data VWAP valid.")
else:
row = valid.iloc[-1]
vwap = float(row["VWAP"])
volume = row["Total_Volume"]
print(f"\nSymbol : {row['Symbol']}")
print(f"VWAP : {vwap:,.2f} USDT")
print(f"Total Volume : {volume:,.4f}" if pd.notna(volume)
else "Total Volume : N/A")
print(f"Limit : {row['Limit']}")
print(f"Weight : {row['Weight']}")
print(f"Data Status : {row['Data_Status']}")
print(f"Trading Signal : {row['Trading_Signal']}")
# ==================================
# DASHBOARD VISUALIZATION
# ==================================
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Chart 1: VWAP reference
axes[0].axhline(
y=vwap,
linewidth=2.5,
color="royalblue",
label="VWAP"
)
axes[0].scatter(
[0], [vwap],
color="darkblue",
s=90,
zorder=3
)
axes[0].set_xlim(-0.5, 0.5)
axes[0].set_xticks([])
axes[0].set_ylim(vwap * 0.98, vwap * 1.02)
axes[0].set_title(f"{SYMBOL} | VWAP Reference")
axes[0].set_ylabel("Price (USDT)")
axes[0].grid(alpha=0.25)
axes[0].legend()
axes[0].annotate(
f"{vwap:,.2f} USDT",
xy=(0, vwap),
xytext=(0, 14),
textcoords="offset points",
ha="center",
fontweight="bold"
)
# Chart 2: indikator berdasarkan kategori
if (
not indicator_df.empty
and "category" in indicator_df.columns
):
counts = (
indicator_df["category"]
.fillna("unknown")
.value_counts()
)
axes[1].bar(
counts.index.astype(str),
counts.values,
color="steelblue"
)
axes[1].set_title("Available Indicator Categories")
axes[1].set_ylabel("Number of Indicators")
axes[1].tick_params(axis="x", rotation=35)
axes[1].grid(axis="y", alpha=0.25)
else:
axes[1].text(
0.5, 0.5,
"Indicator categories unavailable",
ha="center", va="center",
transform=axes[1].transAxes
)
axes[1].set_axis_off()
plt.suptitle(
"CRYPTO VWAP MARKET INTELLIGENCE",
fontsize=15,
fontweight="bold"
)
plt.tight_layout()
plt.show()
# ==================================
# TRADING ANALYSIS TABLE
# ==================================
print("\nTRADING ANALYSIS SUMMARY")
summary = pd.DataFrame([{
"Symbol": row["Symbol"],
"VWAP": vwap,
"Volume": volume,
"Market Bias": row["Market_Bias"],
"Trading Signal": row["Trading_Signal"],
"Data Status": row["Data_Status"]
}])
display(summary)
# ==================================
# EXPORT RESULTS
# ==================================
analysis.to_csv(
f"{SYMBOL}_vwap_analysis.csv",
index=False
)
indicator_df.to_csv(
"marketflow_indicator_catalog.csv",
index=False
)
with open("marketflow_vwap_raw.json", "w") as f:
json.dump(vwap_raw, f, indent=2, default=str)
print("\nFiles exported successfully.")
The final dashboard should therefore be interpreted as a VWAP data-intelligence dashboard, not as a complete automated trading system. The current implementation correctly reports INSUFFICIENT DATA for the trading signal because a synchronized current price is not available in the VWAP endpoint response. crypto_vwap_trading_intelligenc…
The exported files include the normalized VWAP analysis, the MarketFlow indicator catalog, and the raw VWAP JSON response. crypto_vwap_trading_intelligenc…
Conclusion
The Crypto VWAP Trading Intelligence System provides a structured workflow for retrieving, validating, normalizing, and presenting VWAP information for BTCUSDT through the MarketFlow API. The five-cell architecture separates API configuration, data retrieval, normalization, analytical validation, and dashboard presentation, making the workflow easier to inspect and reproduce.
The current implementation successfully establishes VWAP as a reference value and validates the availability of total volume. However, the analysis correctly avoids generating a bullish or bearish trading signal because the API response does not provide a synchronized current market price. Consequently, Market_Bias remains UNAVAILABLE and Trading_Signal remains INSUFFICIENT DATA. crypto_vwap_trading_intelligenc…
For a complete VWAP trading model, the next analytical requirement is a time-compatible BTCUSDT market-price series. Once the current or candle-level price is available, the system can calculate price deviation from VWAP, determine whether price is above or below the volume-weighted benchmark, and develop a properly defined trading condition. Until that additional data are available, the most defensible interpretation is that the system provides VWAP market intelligence and data validation rather than an executable trading signal.
