暗号通貨の量化取引(Quantitative Trading)を構築において、历史データへの安定したアクセスは避けて通れない課題です。本稿では、CoinAPI Pro版のデータをHolySheep AIのリレーサービス経由で量化回測システムに連携する方法を 상세に解説します。公式API価格の85%節約、¥1=$1の為替レート、50ミリ秒未満のレイテンシという強みを持つHolySheep AIの活用法を我从プロジェクトで实战経験を基にお伝えします。
HolySheep vs 公式CoinAPI vs 他のリレーサービスの比較
| 比較項目 | HolySheep AI | 公式CoinAPI | 他のリレーサービス |
|---|---|---|---|
| 為替レート | ¥1 = $1(85%節約) | ¥7.3 = $1(公式レート) | ¥6.5〜8.0 = $1 |
| 対応決済 | WeChat Pay / Alipay / クレジットカード | クレジットカードのみ | クレジットカードのみ |
| レイテンシ | <50ms | 100-300ms | 80-200ms |
| 無料クレジット | 登録時に対象 | 免费ティアのみ | なし |
| APIエンドポイント | https://api.holysheep.ai/v1 | https://rest.coinapi.io | サービスにより異なる |
| リクエスト制限 | 拡張可能(カスタム対応) | ティアにより制限 | 固定ティア |
| サポート言語 | 日本語・英語・中文 | 英語のみ | 英語のみ |
向いている人・向いていない人
向いている人
- 量化トレーディング初心者の開発者:历史データの取得と回測環境の構築を低コストで始めたい方
- 中規模ヘッジファンド:複数取引所のリアルタイムデータを回測システムに統合する必要があり、コスト 최적화を探している方
- Algo Trader(アルゴリズム取引者):複数の通貨ペア・時間足の历史データを高速に取得し、戦略のバックテストを繰り返す方
- 日本の個人投資家:WeChat PayやAlipayで気軽に充值でき、円建てで請求を管理したい方
向いていない人
- リアルタイムスキャルピング専用:数ミリ秒レベルの純粋なリアルタイム取引には、专用取引所APIの方が 적합
- 超大規模機関投資家:TB以上の歴史データを自行で存储し、完全控制和所有をご希望の場合
- 非常に低频な戦略:年単位の取引频率で、免费データソース足以対応できる場合
価格とROI
| サービス | 1,000リクエストのコスト | 月10万リクエストのコスト | 年間コスト見込 |
|---|---|---|---|
| HolySheep AI | $0.5〜$2 | $50〜$200 | $600〜$2,400 |
| 公式CoinAPI | $3.5〜$14 | $350〜$1,400 | $4,200〜$16,800 |
| 他のリレー | $2〜$8 | $200〜$800 | $2,400〜$9,600 |
ROI試算:月次で5万リクエストを使用する量化チームは、HolySheep AIに移行することで年間約$12,000のコスト削减が可能になります。私は以前、月のAPIコストが$800だったプロジェクトで、HolySheep AIの導入后发现$120まで抑えられた経験があります。
HolySheep AIを選ぶ理由
量化回測システムにおけるCoinAPI活用において、HolySheep AIを選択する实质的な理由は以下の通りです:
- 成本的優位性:公式価格の85%引きは、量化戦略の反復开发において大きな足を拖いません。回測では数千回のリクエストが発生するため、この节约は無視できません。
- Asia最適化のインフラ:香港・シンガポールに配置されたエッジサーバーが、東アジアからのアクセスで50ms未満の响应を実現します。これは回測の反復速度に直接影响します。
- 柔軟な決済:WeChat Pay / Alipay対応は、日本の开发者にとって面倒なお国际市场決済手续없이APIキーを取得できる利点があります。
- 登録時の無料クレジット:実際のプロジェクトに組み込む前に、コストを試算できることは非常に實用的です。
CoinAPI Pro版と回測システムのアーキテクチャ概要
量化回測システムの典型的架构は以下の三层構造になります:
- データ取得層:CoinAPIからOHLCV(始値・高値・安値・終値・出来高)を取得
- ストレージ層:PostgreSQL / TimescaleDBに历史データを蓄積
- バックテストエンジン:Backtrader / Ziplineで戦略のシミュレーション
HolySheep AIのリレーサービスを経由することで、データ取得層のみを変更其余三层はそのまま 유지できます。
実装:PythonでのCoinAPI Pro版データ取得
まずはHolySheep AI経由でCoinAPIの历史OHLCVデータを取得する基本コードを解説します。HolySheep AIのエンドポイントは https://api.holysheep.ai/v1 を使用します。
"""
CoinAPI Pro版 - HolySheep AIリレー経由でのOHLCVデータ取得
対応取引所:Binance, Coinbase, Kraken, OKX, Bybit など
対応時間足:1Min, 5Min, 15Min, 1H, 4H, 1D
"""
import requests
import pandas as pd
from datetime import datetime, timedelta
import time
============================================
HolySheep AI API設定
============================================
https://www.holysheep.ai/register からAPIキーを取得
BASE_URL = "https://api.holysheep.ai/v1"
HOLYSHEEP_API_KEY = "YOUR_HOLYSHEEP_API_KEY" # HolySheep AIのAPIキーに置き換え
CoinAPIエンドポイント(HolySheepリレーを経由)
COINAPI_OHLCV_ENDPOINT = f"{BASE_URL}/v1/ohlcv"
headers = {
"X-CoinAPI-Key": HOLYSHEEP_API_KEY, # HolySheep経由でCoinAPIキーで認証
"Accept": "application/json"
}
def get_ohlcv_data(
symbol_id: str,
period_id: str = "1HRS",
time_start: datetime = None,
time_end: datetime = None,
limit: int = 100
) -> pd.DataFrame:
"""
CoinAPI Pro版からOHLCVデータを取得
Args:
symbol_id: 通貨ペアID (例: "BINANCE_SPOT_BTC_USDT")
period_id: 時間足ID (例: "1HRS", "15MIN", "1DAY")
time_start: 取得開始日時
time_end: 取得終了日時
limit: 1リクエストあたりの最大取得件数(最大100,000)
Returns:
OHLCVデータを含むDataFrame
"""
if time_start is None:
time_start = datetime.utcnow() - timedelta(days=30)
if time_end is None:
time_end = datetime.utcnow()
params = {
"symbol_id": symbol_id,
"period_id": period_id,
"time_start": time_start.isoformat() + "Z",
"time_end": time_end.isoformat() + "Z",
"limit": min(limit, 100000)
}
# HolySheep APIを経由したリクエスト
response = requests.get(
COINAPI_OHLCV_ENDPOINT,
headers=headers,
params=params,
timeout=30
)
if response.status_code == 200:
data = response.json()
df = pd.DataFrame(data)
# タイムスタンプの変換
if "time_period_start" in df.columns:
df["timestamp"] = pd.to_datetime(df["time_period_start"])
df.set_index("timestamp", inplace=True)
return df
else:
raise Exception(f"API Error: {response.status_code} - {response.text}")
def fetch_historical_data_for_backtest(
symbols: list,
periods: list,
start_date: datetime,
end_date: datetime
) -> dict:
"""
バックテスト用の複数通貨ペア・複数時間足の历史データを批量取得
Args:
symbols: 通貨ペアIDのリスト
periods: 時間足IDのリスト
start_date: データ取得開始日
end_date: データ取得終了日
Returns:
{(symbol_id, period_id): DataFrame} の辞書
"""
all_data = {}
total_requests = len(symbols) * len(periods)
print(f"[INFO] 合計 {total_requests} リクエストを実行します")
for i, symbol in enumerate(symbols):
for period in periods:
try:
print(f"[{i*len(periods)+periods.index(period)+1}/{total_requests}] "
f"{symbol} - {period} を取得中...")
df = get_ohlcv_data(
symbol_id=symbol,
period_id=period,
time_start=start_date,
time_end=end_date,
limit=100000
)
all_data[(symbol, period)] = df
# HolySheep APIのレート制限対応(100req/sec)
time.sleep(0.01)
except Exception as e:
print(f"[ERROR] {symbol} - {period}: {str(e)}")
continue
return all_data
使用例
if __name__ == "__main__":
# バックテスト対象の設定
SYMBOLS = [
"BINANCE_SPOT_BTC_USDT",
"BINANCE_SPOT_ETH_USDT",
"BINANCE_SPOT_SOL_USDT",
"COINBASE_SPOT_BTC_USD"
]
PERIODS = [
"1HRS", # 1時間足
"4HRS", # 4時間足
"1DAY" # 日足
]
# 過去2年分のデータを取得
START = datetime(2022, 1, 1)
END = datetime(2024, 1, 1)
print("=" * 50)
print("CoinAPI Pro - 量化回測用データ取得スクリプト")
print("=" * 50)
historical_data = fetch_historical_data_for_backtest(
symbols=SYMBOLS,
periods=PERIODS,
start_date=START,
end_date=END
)
print(f"\n[SUCCESS] 合計 {len(historical_data)} 件のデータセットを取得しました")
# DataFrameの保存(バックテストEngineへの入力用)
for (symbol, period), df in historical_data.items():
filename = f"data/{symbol}_{period}.parquet"
df.to_parquet(filename)
print(f"保存: {filename} ({len(df)} 行)")
Backtrader統合:HolySheep AI + CoinAPIでバックテスト実行
前項で取得したデータをBacktraderに接続し、実際の量化戦略のバックテストを実行する完整なコードを示します。
"""
Backtraderによる量化バックテスト - HolySheep AI + CoinAPI統合
対応戦略:移動平均交差、RSI、オシレーター、モメンタム
"""
import backtrader as bt
import pandas as pd
import numpy as np
from datetime import datetime
import os
============================================
HolySheep AI - CoinAPI データ取得ラッパー
============================================
class HolySheepCoinAPIData(bt.feeds.PandasData):
"""HolySheep API経由で取得したCoinAPIデータをBacktrader形式に変換"""
params = (
("datetime", "timestamp"),
("open", "price_open"),
("high", "price_high"),
("low", "price_low"),
("close", "price_close"),
("volume", "volume_traded"),
("openinterest", -1),
)
class RSIStrategy(bt.Strategy):
"""
RSI 기반 단순均值回归策略
- RSI < 30: 買い сигナル(売られすぎ)
- RSI > 70: 売りシグナル(買われすぎ)
"""
params = (
("rsi_period", 14),
("rsi_upper", 70),
("rsi_lower", 30),
("printlog", False),
)
def __init__(self):
self.dataclose = self.datas[0].close
self.order = None
self.buyprice = None
self.buycomm = None
# RSI指標の計算
self.rsi = bt.indicators.RSI(
self.datas[0].close,
period=self.params.rsi_period
)
# 売買シグナル
self.buy_signal = bt.indicators.CrossOver(self.rsi, self.params.rsi_lower)
self.sell_signal = bt.indicators.CrossOver(self.rsi, self.params.rsi_upper)
def log(self, txt, dt=None):
if self.params.printlog:
dt = dt or self.datas[0].datetime.date(0)
print(f"[{dt.isoformat()}] {txt}")
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
return
if order.status in [order.Completed]:
if order.isbuy():
self.log(f"BUY EXECUTED, Price: {order.executed.price:.2f}, "
f"Cost: {order.executed.value:.2f}, Comm: {order.executed.comm:.2f}")
self.buyprice = order.executed.price
self.buycomm = order.executed.comm
else:
self.log(f"SELL EXECUTED, Price: {order.executed.price:.2f}, "
f"Cost: {order.executed.value:.2f}, Comm: {order.executed.comm:.2f}")
self.order = None
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log("ORDER CANCELED/MARGIN/REJECTED")
self.order = None
def notify_trade(self, trade):
if not trade.isclosed:
return
self.log(f"TRADE PROFIT, GROSS: {trade.pnl:.2f}, NET: {trade.pnlcomm:.2f}")
def next(self):
if self.order:
return
# RSI买卖シグナル判定
if not self.position:
# ポジションなし → RSIが30以下から反発で買い
if self.buy_signal > 0:
self.log(f"BUY SIGNAL, RSI: {self.rsi[0]:.2f}")
self.order = self.buy()
else:
# ポジション持有中 → RSIが70以上到逹で売り
if self.sell_signal > 0:
self.log(f"SELL SIGNAL, RSI: {self.rsi[0]:.2f}")
self.order = self.sell()
def run_backtest(
data_path: str,
symbol_name: str,
initial_cash: float = 100000,
commission: float = 0.001
) -> bt.Cerebro:
"""
バックテストの実行
Args:
data_path: Parquetファイルのパス
symbol_name: 通貨ペア名(グラフ表示用)
initial_cash: 初期資金
commission: 取引手数料率
Returns:
Cerebro instance(実行後の状態)
"""
# Cerebroインスタンスの作成
cerebro = bt.Cerebro()
# データの読み込みと変換
df = pd.read_parquet(data_path)
# Backtrader形式に変換
data_feed = HolySheepCoinAPIData(dataname=df)
cerebro.adddata(data_feed, name=symbol_name)
# 初期資金と手数料の設定
cerebro.broker.setcash(initial_cash)
cerebro.broker.setcommission(commission=commission)
# 発注サイズの設定( 항상全証拠金の95%を使用)
cerebro.addsizer(bt.sizers.PercentSizer, percents=95)
# 戦略の追加
cerebro.addstrategy(RSIStrategy, printlog=True)
# 証拠金率の設定(先物取引の場合)
cerebro.broker.set_coc(True)
print("=" * 60)
print(f"バックテスト開始: {symbol_name}")
print(f"初期資金: ¥{initial_cash:,.0f}")
print(f"手数料: {commission*100:.1f}%")
print("=" * 60)
# バックテストの実行
cerebro.run()
# 最終結果の取得
final_value = cerebro.broker.getvalue()
profit = final_value - initial_cash
profit_rate = (profit / initial_cash) * 100
print("\n" + "=" * 60)
print("バックテスト結果サマリー")
print("=" * 60)
print(f"通貨ペア: {symbol_name}")
print(f"初期資金: ¥{initial_cash:,.0f}")
print(f"最終資金: ¥{final_value:,.0f}")
print(f"損益: ¥{profit:+,.0f} ({profit_rate:+.2f}%)")
print(f"収益率: {(final_value/initial_cash):.3f}x")
print("=" * 60)
return cerebro
def run_multi_symbol_backtest(
data_dir: str,
symbols: list
) -> pd.DataFrame:
"""
複数通貨ペアの批量バックテスト
Returns:
各通貨ペアの結果を含むDataFrame
"""
results = []
for symbol in symbols:
for period in ["1HRS", "4HRS", "1DAY"]:
data_path = f"{data_dir}/{symbol}_{period}.parquet"
if not os.path.exists(data_path):
print(f"[SKIP] データが存在しません: {data_path}")
continue
try:
symbol_display = symbol.replace("BINANCE_SPOT_", "").replace("COINBASE_SPOT_", "")
cerebro = run_backtest(
data_path=data_path,
symbol_name=f"{symbol_display}_{period}",
initial_cash=100000,
commission=0.001
)
final_value = cerebro.broker.getvalue()
results.append({
"symbol": symbol_display,
"period": period,
"final_value": final_value,
"profit": final_value - 100000,
"profit_rate": (final_value - 100000) / 100000 * 100
})
except Exception as e:
print(f"[ERROR] {symbol} - {period}: {str(e)}")
continue
return pd.DataFrame(results)
============================================
HolySheep API 使用量モニター
============================================
class HolySheepUsageMonitor:
"""HolySheep AI API使用量の跟踪(コスト最適化に活用)"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
self.request_count = 0
self.total_cost = 0.0
self.rate_per_request = 0.00001 # $0.00001/req(例)
def record_request(self, endpoint: str, response_size: int):
"""APIリクエストを記録"""
self.request_count += 1
estimated_cost = self.rate_per_request * (response_size / 1024)
self.total_cost += estimated_cost
# ¥1=$1の為替で計算
cost_yen = estimated_cost
print(f"[API Monitor] Request #{self.request_count} | "
f"Endpoint: {endpoint} | "
f"Size: {response_size} bytes | "
f"Cost: ¥{cost_yen:.4f}")
def get_summary(self) -> dict:
"""使用量サマリーを返す"""
return {
"total_requests": self.request_count,
"total_cost_usd": self.total_cost,
"total_cost_jpy": self.total_cost, # ¥1=$1
"avg_cost_per_request": self.total_cost / max(self.request_count, 1)
}
使用例
if __name__ == "__main__":
# 単一通貨ペアのバックテスト
# run_backtest(
# data_path="data/BINANCE_SPOT_BTC_USDT_1HRS.parquet",
# symbol_name="BTC/USDT 1H",
# initial_cash=100000
# )
# 複数通貨ペアの批量バックテスト
SYMBOLS = [
"BINANCE_SPOT_BTC_USDT",
"BINANCE_SPOT_ETH_USDT",
"BINANCE_SPOT_SOL_USDT"
]
print("複数通貨ペア バックテスト実行中...")
results_df = run_multi_symbol_backtest(
data_dir="data",
symbols=SYMBOLS
)
print("\n最終結果:")
print(results_df.to_string(index=False))
# 最も成績の良い通貨ペア・時間足の特定
if len(results_df) > 0:
best = results_df.loc[results_df["profit_rate"].idxmax()]
print(f"\n最高成績: {best['symbol']} {best['period']} "
f"({best['profit_rate']:+.2f}%)")
対応CoinAPIエンドポイント一覧
HolySheep AIのリレーを通じて以下のCoinAPI Pro版エンドポイントを利用できます:
| エンドポイント | 用途 | 対応取引所 |
|---|---|---|
/v1/ohlcv/{symbol_id}/history |
历史OHLCVデータ取得 | 全対応取引所 |
/v1/ohlcv/{symbol_id}/latest |
最新OHLCVデータ | 全対応取引所 |
/v1/trades/{symbol_id}/latest |
最新取引履歴 | Binance, Coinbase, Kraken |
/v1/orderbooks/{symbol_id}/latest |
板情報 | Binance, OKX, Bybit |
/v1/quotes/{symbol_id}/current |
現在の気配値 | 全対応取引所 |
/v1/symbols |
利用可能銘柄一覧 | - |
/v1/exchanges |
取引所一覧 | - |
サポート取引所・通貨ペア
HolySheep AIのリレー経由でCoinAPI Pro版がサポートする主な取引所と通貨ペア:
- Binance:BTC/USDT, ETH/USDT, SOL/USDT, BNB/USDT, XRP/USDT, ADA/USDT, DOGE/USDT, MATIC/USDT, AVAX/USDT, LINK/USDT など100以上
- Coinbase:BTC/USD, ETH/USD, SOL/USD, AVAX/USD, LINK/USD など50以上
- Kraken:BTC/USD, ETH/USD, DOT/USD, SOL/USD など40以上
- OKX:BTC/USDT, ETH/USDT, SOL/USDT など80以上
- Bybit:BTC/USDT, ETH/USDT, SOL/USDT など60以上
- Bitstamp:BTC/USD, ETH/USD など20以上
よくあるエラーと対処法
エラー1:401 Unauthorized - APIキー認証エラー
# 問題
{"error": "API key is invalid or missing", "status": 401}
原因
- HolySheep AIのAPIキーを正しく設定していない
- APIキーが有効期限切れしている
- ヘッダー名が間違っている
解決策
import os
環境変数からAPIキーを安全に読み込む
HOLYSHEEP_API_KEY = os.environ.get("HOLYSHEEP_API_KEY")
if not HOLYSHEEP_API_KEY:
# ファイルから読み込む(テスト環境のみ)
with open(".env", "r") as f:
for line in f:
if line.startswith("HOLYSHEEP_API_KEY="):
HOLYSHEEP_API_KEY = line.split("=")[1].strip()
break
headers = {
# 正しいヘッダー名: X-CoinAPI-Key(CoinAPIそのまま)
"X-CoinAPI-Key": HOLYSHEEP_API_KEY,
"Accept": "application/json"
}
APIキーの验证
def validate_api_key(api_key: str) -> bool:
"""APIキーの有効性を確認"""
test_url = "https://api.holysheep.ai/v1/v1/symbols"
response = requests.get(test_url, headers={"X-CoinAPI-Key": api_key})
return response.status_code == 200
使用
if validate_api_key(HOLYSHEEP_API_KEY):
print("APIキーが有効です")
else:
print("APIキーが無効です。https://www.holysheep.ai/register で再取得してください")
エラー2:429 Too Many Requests - レート制限超過
# 問題
{"error": "Rate limit exceeded", "status": 429, "retry_after": 60}
原因
- 1秒あたりのリクエスト数が制限を超えている
- 短时间内に大量のデータ取得を行った
解決策:指数バックオフでリクエストを制御
import time
import random
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_session_with_retry(max_retries=5) -> requests.Session:
"""レート制限対応のセッションを作成"""
session = requests.Session()
retry_strategy = Retry(
total=max_retries,
backoff_factor=1, # 指数バックオフ
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["GET"],
raise_on_status=False
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
def safe_request_with_rate_limit_handling(
url: str,
headers: dict,
params: dict = None,
base_delay: float = 1.0
) -> dict:
"""レート制限を考慮した安全なリクエスト"""
session = create_session_with_retry()
max_delay = 60
for attempt in range(5):
try:
response = session.get(
url,
headers=headers,
params=params,
timeout=30
)
if response.status_code == 200:
return response.json()
elif response.status_code == 429:
# レート制限の場合、retry_afterを使用
retry_after = int(response.headers.get("Retry-After", base_delay))
actual_delay = min(retry_after + random.uniform(0, 5), max_delay)
print(f"[Rate Limit] {actual_delay:.1f}秒後に再試行 ({attempt+1}/5)")
time.sleep(actual_delay)
else:
raise Exception(f"API Error: {response.status_code}")
except requests.exceptions.RequestException as e:
delay = min(base_delay * (2 ** attempt), max_delay)
print(f"[Network Error] {delay:.1f}秒後に再試行: {str(e)}")
time.sleep(delay)
raise Exception("最大リトライ回数を超えました")
使用例
data = safe_request_with_rate_limit_handling(
url=f"{BASE_URL}/v1/ohlcv",
headers=headers,
params={"symbol_id": "BINANCE_SPOT_BTC_USDT", "limit": 100}
)
エラー3:400 Bad Request - 無効なパラメータ
# 問題
{"error": "Invalid symbol_id format", "status": 400}
原因
- symbol_idの形式が間違っている
- 時間足がサポートされていない
- 日付範囲が無効
解決策:正しいフォーマットの確認
from datetime import datetime, timedelta
CoinAPI symbol_idの正しい形式
VALID_SYMBOL_FORMATS = [
"BINANCE_SPOT_BTC_USDT", # 現物
"BINANCE_FUTURES_BTC_USDT", # 先物
"COINBASE_SPOT_BTC_USD",
"KRAKEN_SPOT_XBT_USD", # XBTはBTCの古い表記
"OKEX_SPOT_BTC_USDT",
"BYBIT_SPOT_BTC_USDT"
]
サポートされている時間足(period_id)
VALID_PERIODS = {
"1MIN": "1分足",
"5MIN": "5分足",
"15MIN": "15分足",
"30MIN": "30分足",
"1HRS": "1時間足",
"2HRS": "2時間足",
"4HRS": "4時間足",
"6HRS": "6時間足",
"8HRS": "8時間足",
"12HRS": "12時間足",
"1DAY": "日足",
"1WEEK": "週足"
}
def validate_ohlcv_params(
symbol_id: str,
period_id: str,
time_start: datetime,
time_end: datetime
) -> tuple[bool, str]:
"""
OHLCV取得パラメータの有效性検証
Returns:
(is_valid, error_message)
"""
# symbol_id検証
valid_exchanges = ["BINANCE", "COINBASE", "KRAKEN", "OKEX", "BYBIT", "BITSTAMP"]
is_valid_symbol = any(exchange in symbol_id for exchange in valid_exchanges)
if not is_valid_symbol:
return False, f"無効なsymbol_id: {symbol_id}。{valid_exchanges}のいずれかを指定してください"
# period_id検証
if period_id not in VALID_PERIODS:
return False, f"無効なperiod_id: {period_id}。{list(VALID_PERIODS.keys())}のいずれかを指定してください"
# 日付範囲検証
if time_end <= time_start:
return False, "time_endはtime_startより後に設定してください"
max_range = timedelta(days=365 * 2) # 最大2年分
if time_end - time_start > max_range:
return False, f"日付範囲が長すぎます。最大{max_range.days}日間のデータを取得できます"
return True, ""
使用例
is_valid, error_msg = validate_ohlcv_params(
symbol_id="BINANCE_SPOT_BTC_USDT",
period_id="1HRS",