A practical tutorial for testing a classic trend-following setup on Hyperliquid 1h candles, with runnable Python and the current signal snapshot for ETH.
This walkthrough uses data from 2025-03-23 to 2026-05-10. After the SMA-200 warm-up, the strategy evaluates 8,465 hourly closes.
Use the counts here as a quick sense-check when you run the Python recipe against the same market and interval.
A simple moving average smooths price by averaging the last N closes. Traders often compare a faster line like the 50-period SMA with a slower line like the 200-period SMA to see whether momentum is strengthening or weakening.
A golden cross happens when the faster average moves above the slower one, which traders read as trend confirmation. A death cross is the opposite. The signal is easy to test, but it is still a lagging indicator and can whipsaw when price chops sideways.
"""
TikTape ETH 1h SMA crossover recipe.
No lookahead bias: both SMAs use trailing windows and the crossover is
evaluated only after each candle close.
Expected output for this exact range:
candles=8664
usable_after_sma200=8465
golden_crosses=26
death_crosses=26
latest_signal=2026-05-09T00:59:59Z death_cross
"""
import datetime
import json
import os
import urllib.parse
import urllib.request
BASE_URL = os.getenv("TIKTAPE_OHLCV_URL", "https://tiktape.xyz/api/v1/ohlcv")
API_KEY = os.getenv("TIKTAPE_API_KEY", "YOUR_TIKTAPE_API_KEY")
COIN = "ETH"
INTERVAL = "1h"
START_MS = 1742688000000
END_MS = 1778461199999
PAGE_LIMIT = 10000
INTERVAL_MS = 60 * 60 * 1000
def fetch_all_candles():
rows = []
cursor = START_MS
while cursor < END_MS:
query = urllib.parse.urlencode(
{
"coin": COIN,
"interval": INTERVAL,
"startTime": cursor,
"endTime": END_MS,
"limit": PAGE_LIMIT,
}
)
req = urllib.request.Request(
f"{BASE_URL}?{query}",
headers={"X-API-Key": API_KEY},
)
with urllib.request.urlopen(req, timeout=30) as resp:
payload = json.load(resp)
batch = payload["data"]
if not batch:
break
rows.extend(batch)
next_cursor = int(batch[-1][0]) + INTERVAL_MS
if next_cursor <= cursor:
raise RuntimeError("cursor did not advance; aborting pagination")
cursor = next_cursor
return rows
def rolling_sma(values, window):
out = [None] * len(values)
window_sum = 0.0
for idx, value in enumerate(values):
window_sum += value
if idx >= window:
window_sum -= values[idx - window]
if idx >= window - 1:
out[idx] = window_sum / window
return out
def main():
candles = fetch_all_candles()
closes = [float(row[4]) for row in candles]
sma50 = rolling_sma(closes, 50)
sma200 = rolling_sma(closes, 200)
golden_crosses = 0
death_crosses = 0
latest_signal = "none"
for idx in range(1, len(candles)):
if None in (sma50[idx - 1], sma200[idx - 1], sma50[idx], sma200[idx]):
continue
if sma50[idx - 1] <= sma200[idx - 1] and sma50[idx] > sma200[idx]:
golden_crosses += 1
signal_at = datetime.datetime.fromtimestamp(candles[idx][0] / 1000, tz=datetime.timezone.utc)
latest_signal = f"{signal_at.strftime('%Y-%m-%dT%H:%M:%SZ')} golden_cross"
elif sma50[idx - 1] >= sma200[idx - 1] and sma50[idx] < sma200[idx]:
death_crosses += 1
signal_at = datetime.datetime.fromtimestamp(candles[idx][0] / 1000, tz=datetime.timezone.utc)
latest_signal = f"{signal_at.strftime('%Y-%m-%dT%H:%M:%SZ')} death_cross"
usable_after_sma200 = max(len(candles) - 200 + 1, 0)
print(f"candles={len(candles)}")
print(f"usable_after_sma200={usable_after_sma200}")
print(f"golden_crosses={golden_crosses}")
print(f"death_crosses={death_crosses}")
print(f"latest_signal={latest_signal}")
if __name__ == "__main__":
main()
Expected output for the exact range embedded above:
candles=8664
usable_after_sma200=8465
golden_crosses=26
death_crosses=26
latest_signal=2026-05-09T00:59:59Z death_cross
The strategy currently reports 26 golden crosses and 26 death crosses in the stored 1h range. The latest crossover on ETH printed at 2026-05-09T00:59:59Z as a death_cross signal.
That gives you a concrete output to compare against when you run the script locally and start changing parameters.
Fetch the complete tutorial dataset with the TikTape API:
Use the endpoint above to request the same 1h candle history used by this walkthrough. The related links below cover the full history page, the broader backtesting guide, and the provider comparison.