rac-bot / tradingview.py
Bohaska
add rac bot files
cb6590e
import aiohttp
import asyncio
import json
import datetime
from enum import Enum
from math import sqrt
import logging
class MarketStatus(Enum):
# OPEN includes pre-market and post-market
TRADING = 1
CLOSED = 2
def format_ws_request(data):
return f"~m~{len(data)}~m~{data}"
async def get_stock_info(ticker):
endpoint = f"wss://data.tradingview.com/socket.io/websocket"
session = aiohttp.ClientSession()
random_session_id = "qs_PqKEQDeY5hPs"
async with session.ws_connect(endpoint, origin='https://www.tradingview.com') as ws:
await ws.receive()
logging.debug(f"connected to {endpoint}")
await ws.send_str(format_ws_request('{"m":"set_data_quality","p":["low"]}'))
await ws.send_str(format_ws_request('{"m":"set_auth_token","p":["unauthorized_user_token"]}'))
await ws.send_str(format_ws_request('{"m":"set_locale","p":["en","US"]}'))
await ws.send_str(format_ws_request(f'{{"m":"quote_create_session","p":["{random_session_id}"]}}'))
# await ws.send_str(format_ws_request(f'{{"m":"quote_set_fields","p":["{random_session_id}","base-currency-logoid","ch","chp","currency-logoid","currency_code","currency_id","base_currency_id","current_session","description","exchange","format","fractional","is_tradable","language","local_description","listed_exchange","logoid","lp","lp_time","minmov","minmove2","original_name","pricescale","pro_name","short_name","type","typespecs","update_mode","volume","variable_tick_size","value_unit_id","ask","bid","fundamentals","high_price","is_tradable","low_price","open_price","prev_close_price","rch","rchp","rtc","rtc_time","status","basic_eps_net_income","beta_1_year","earnings_per_share_basic_ttm","industry","market_cap_basic","price_earnings_ttm","sector","volume","dividends_yield","timezone"]}}'))
await ws.send_str(format_ws_request(f'{{"m":"quote_add_symbols","p":["{random_session_id}","{ticker}"]}}'))
await ws.send_str(format_ws_request(f'{{"m":"quote_fast_symbols","p":["{random_session_id}","{ticker}"]}}'))
logging.debug("sent messages")
ws_stock_info = await ws.receive()
logging.debug(ws_stock_info.data)
await ws.close()
logging.debug("closed websocket")
index = 4
new_stock_info = None
while new_stock_info is None:
try:
stock_info = json.loads(ws_stock_info.data.split("~")[index])["p"][1]
new_stock_info = {
"short_name": stock_info["v"]["short_name"],
"name": stock_info["n"],
"last_price": stock_info["v"]["lp"],
"current_session": MarketStatus.TRADING if stock_info["v"]["current_session"] in ["market", "pre_market", "post_market"] else MarketStatus.CLOSED,
}
except KeyError:
index += 4
new_stock_info["close_price"] = new_stock_info["last_price"] if new_stock_info["current_session"] == MarketStatus.CLOSED else stock_info["v"]["prev_close_price"]
new_stock_info["change"] = 0 if new_stock_info["current_session"] == MarketStatus.CLOSED else new_stock_info["last_price"] - new_stock_info["close_price"]
new_stock_info["change_percent"] = 0 if new_stock_info["current_session"] == MarketStatus.CLOSED else (new_stock_info["last_price"] - new_stock_info["close_price"])/new_stock_info["last_price"] * 100
return new_stock_info
async def get_technical_rating(ticker, time=None, adjust=None):
headers = {
'authority': 'scanner.tradingview.com',
'accept': 'application/json',
'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8,zh-Hans;q=0.7,zh;q=0.6',
'cache-control': 'no-cache',
# 'cookie': 'cookiePrivacyPreferenceBannerProduction=notApplicable; cookiesSettings={"analytics":true,"advertising":true}; device_t=TGdRUEJBOjA.DsY7yfR2BGUIu_pO-s2MDpMczSLpYWQXBZVedEgbwks; sessionid=m4vktjbp6w9tw0noiyy56cu5djsz3b3k; sessionid_sign=v1:7+2774aIu7zFlHqM7hPs01NHuPzTxJGiz40C0U4ofts=; tv_ecuid=61f7b49d-5ff0-460e-a9c6-f4f08384b31e; cachec=61f7b49d-5ff0-460e-a9c6-f4f08384b31e; etg=61f7b49d-5ff0-460e-a9c6-f4f08384b31e; _ga=GA1.1.1541556038.1701929137; _ga_YVVRYGL0E0=GS1.1.1702701849.26.1.1702702103.60.0.0; _sp_id.cf1a=2f870214-eb23-490e-821b-b3632a37c876.1701906159.44.1704694255.1704532038.1ccd4fce-568b-4d9f-8495-4e675b3cb00e',
'origin': 'https://www.tradingview.com',
'pragma': 'no-cache',
'referer': 'https://www.tradingview.com/',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
}
params = {
"symbol": ticker,
"no_404": "true",
}
if time is not None:
params["fields"] = "Recommend.All" + time
else:
params["fields"] = "Recommend.All"
tries = 0
async with aiohttp.ClientSession() as session:
logging.debug(f"Getting URL https://scanner.tradingview.com/symbol...")
while tries < 5:
try:
rating = await session.get("https://scanner.tradingview.com/symbol", params=params, headers=headers, timeout=20)
rating = await rating.json()
logging.debug(rating)
rating = list(rating.values())[0]
adjust = False if adjust is None else adjust
if adjust:
if rating < 0:
return sqrt(rating * -1) * -1
else:
return sqrt(rating)
else:
return rating
except:
tries += 1
if tries >= 5:
raise asyncio.exceptions.TimeoutError(f"Failed to fetch info after {tries} tries")