出来高分析の初手としてのデータ取得
はじめに
この記事はデータ活用の初手としてTrading Viewとyfinance、Google Colabを活用して必要な情報を取得するまでを書いた備忘録です。
この状態のスクリプトが横展開効きやすそうだと考え、メモに残します。
最終アウトプットはGoogle Colab上で動作するPythonスクリプトです。Pythonスクリプトだけ欲しい人は目次から飛んでください。
Trading Viewでスクリーニング
fetch_tradingview_tickers関数でデータ取得対象を決めるためにTrading Viewのスクリーナーを用いて条件に一致する銘柄のティッカーコードを取得します。
yfinanceに渡すティッカコードリストを作成するのにTrading Viewを使うことにしたのはフィルター条件の柔軟さと、必要に応じてティッカーコード以外のデータも取得し、掛け合わせることができるためです。
また、スクリーナーの利用にあたって有料プランの契約は必要ありません。
payload内、filterの部分でスクリーニング条件を指定します。
下の例では出来高50万以上、相対ボリューム1.0以上、普通株、東証などを指定しています。
"filter": [
{"left": "type", "operation": "equal", "right": "stock"},
{"left": "subtype", "operation": "in_range", "right": ["common", "foreign-issuer"]},
{"left": "volume","operation": "egreater","right": 500000},
{"left": "relative_volume_10d_calc","operation": "egreater","right": 1},
{"left": "exchange", "operation": "equal", "right": "TSE"}
],
自分が指定したい検索条件が分からないときはGUIで条件指定後、F12でデベロッパーツールを開き、Network>Fetch/XHR>scan>PayloadをコピペすればOKです。
yfinanceからデータを取得
取得したティッカーコードに対してdownload_data関数でyfinanceからデータを取得します。
下記の例では5分足のデータを11日分取得し、初日のデータを切り捨てて10日分のデータをcsv出力しています。
なぜか指定期間初日の9:00の出来高が0になってしまう仕様になっているため、+1日して初日のデータを捨てています。
Python スクリプト
import requests
import json
import pandas as pd
import yfinance as yf
def fetch_tradingview_tickers():
url = 'https://scanner.tradingview.com/japan/scan'
headers = {
"Accept-Language": "ja,en-US;q=0.9,en;q=0.8",
"Origin": "https://jp.tradingview.com/",
"Referer": "https://jp.tradingview.com/"
}
payload = {
"filter": [
{"left": "type", "operation": "equal", "right": "stock"},
{"left": "subtype", "operation": "in_range", "right": ["common", "foreign-issuer"]},
{"left": "volume","operation": "egreater","right": 500000},
{"left": "relative_volume_10d_calc","operation": "egreater","right": 1},
{"left": "exchange", "operation": "equal", "right": "TSE"}
],
"options": {"lang": "ja"},
"markets": ["japan"],
"symbols": {"query": {"types": []}, "tickers": [], "groups": [{"type": "index", "values": ["TVC:NI225"]}]},
"columns": ["name"],
"sort": {"sortBy": "name", "sortOrder": "asc"},
"price_conversion": {"to_symbol": False}
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
return pd.DataFrame([stock['d'] for stock in response.json()["data"]], columns=payload["columns"])
def download_data(ticker_names):
ticker_symbols = [name + ".T" for name in ticker_names]
data = yf.download(ticker_symbols, period="11d", interval="5m", group_by='ticker')
all_data = pd.DataFrame()
if isinstance(data.columns, pd.MultiIndex):
for ticker in ticker_symbols:
if ticker in data.columns.levels[0]: # ティッカーシンボルが存在するかチェック
df = data[ticker].dropna().copy()
df = df[df.index.date > df.index[0].date()]
df['Ticker'] = ticker
# 数値データの列のみを整数に変換
numeric_cols = df.select_dtypes(include=['number']).columns
df[numeric_cols] = df[numeric_cols].round(0).astype(int)
all_data = pd.concat([all_data, df])
else: # 単一ティッカーの場合
data = data.dropna().copy()
data = data[data.index.date > data.index[0].date()]
data['Ticker'] = ticker_symbols[0]
# 数値データの列のみを整数に変換
numeric_cols = data.select_dtypes(include=['number']).columns
data[numeric_cols] = data[numeric_cols].round(0).astype(int)
all_data = data
return all_data
def main():
try:
tickers = fetch_tradingview_tickers()
all_data = download_data(tickers['name'].tolist())
all_data.to_csv('all_tickers_data.csv')
print("All tickers have been processed and their data saved in a single CSV file.")
except requests.HTTPError as e:
print(f"HTTP error occurred: {e}")
except json.JSONDecodeError as e:
print(f"JSON decode error: {e}")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == '__main__':
main()
活用
スクリーニング条件を変えたい場合はfilterを変更
Trading Viewから取得するデータを増やしたい場合はcolumnsを変更
yfinanceから取得するデータを変更したいときはyf.downloadのパラメータを変更してください