CoolFace
Apppublic

shaibu01/Titan-Engine

sourceHugging Faceupdated 2d agoView on Hugging Face
0likes
blockchain_alpha.py205 linesDownload Raw Back to root
1"""2TITAN BLOCKCHAIN ALPHA (v50.0 - INSTITUTIONAL ORDER FLOW & FUNDING PROXY)3TYPE: Institutional Whale Tracking & Microstructure Engine4DATA: Perpetual Funding Rates / Aggregated Taker Volume Imbalance5MATH: Z-Score Acceleration & Non-Linear Flow Normalization6DESCRIPTION: 100% Non-Blocking. Thread-Safe. True Microstructure Edge.7"""8 9import requests10import json11import time12import logging13import numpy as np14import pandas as pd15import threading16import concurrent.futures17 18# --- C++ CORE INJECTION ---19try:20    import titan_engine21    HAS_CPP_CORE = True22except ImportError:23    HAS_CPP_CORE = False24 25logger = logging.getLogger("TITAN")26 27CACHE_DURATION = 60  # 1 Minute Cache for high-frequency relevance28 29class FastMath:30    @staticmethod31    def get_zscore(array):32        """Calculates Z-Score of an array. Prioritizes C++ for speed."""33        if HAS_CPP_CORE and hasattr(titan_engine, 'calc_zscore'):34            try:35                np_arr = np.ascontiguousarray(array, dtype=np.float64)36                return float(titan_engine.calc_zscore(np_arr))37            except Exception:38                pass39                40        if len(array) == 0: return 0.041        std = np.std(array)42        if std == 0: return 0.043        return float((array[-1] - np.mean(array)) / std)44 45fast_math = FastMath()46 47class BlockchainAlpha:48    def __init__(self):49        logger.info("⛓️ BLOCKCHAIN ALPHA: ENGAGING MICROSTRUCTURE & FUNDING RADAR (ASYNC MODE)...")50        self.cache = {}51        self.cache_lock = threading.Lock()52        53        self.session = requests.Session()54        self.http_executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)55        56        # Test Public API Connection57        try:58            res = self.session.get("https://fapi.binance.com/fapi/v1/time", timeout=3)59            if res.status_code == 200:60                logger.info("✅ PUBLIC ORDER FLOW RADAR: SECURE & ACTIVE")61                self.mode = "LIVE_PUBLIC"62            else:63                raise Exception("Public API Blocked")64        except Exception:65            logger.warning("⚠️ PUBLIC API BLOCKED: FALLING BACK TO MT5 MATH PROXY")66            self.mode = "PROXY"67 68    def _fetch_funding_and_flow(self, symbol):69        """70        Pulls Perpetual Funding Rates and Taker Buy/Sell Volume ratios.71        This provides a true indication of institutional leverage and aggression.72        """73        # Map MT5 symbol to Binance Futures symbol74        if "BTC" in symbol: base_sym = "BTCUSDT"75        elif "ETH" in symbol: base_sym = "ETHUSDT"76        elif "SOL" in symbol: base_sym = "SOLUSDT"77        else: return 0.078 79        try:80            # 1. Fetch Funding Rate (Indicates over-leveraged side)81            # Positive funding means Longs pay Shorts (Market is overly Bullish/Greedy)82            # Negative funding means Shorts pay Longs (Market is overly Bearish/Fearful)83            fund_url = f"https://fapi.binance.com/fapi/v1/premiumIndex?symbol={base_sym}"84            fund_resp = self.session.get(fund_url, timeout=3)85            funding_rate = 0.086            87            if fund_resp.status_code == 200:88                funding_rate = float(fund_resp.json().get('lastFundingRate', 0.0))89 90            # 2. Fetch Aggregated Taker Volume (Microstructure Aggression)91            # Pull the last 20 15-minute candles to calculate the Z-score of Taker Volume92            klines_url = f"https://fapi.binance.com/fapi/v1/klines?symbol={base_sym}&interval=15m&limit=20"93            klines_resp = self.session.get(klines_url, timeout=3)94            95            flow_score = 0.096            if klines_resp.status_code == 200:97                klines = klines_resp.json()98                taker_buy_vols = np.array([float(k[9]) for k in klines]) # Taker buy base asset volume99                total_vols = np.array([float(k[5]) for k in klines])     # Total volume100                101                # Calculate Taker Sell Volume102                taker_sell_vols = total_vols - taker_buy_vols103                104                # Calculate Imbalance Ratio (Buy / Sell)105                imbalance_ratios = taker_buy_vols / (taker_sell_vols + 1e-9)106                107                # Z-Score the Imbalance108                flow_score = fast_math.get_zscore(imbalance_ratios)109 110            # 3. Synthesize the Alpha Score (-1.0 to 1.0)111            # High positive flow_score + High negative funding = MASSIVE BUY SIGNAL112            # High negative flow_score + High positive funding = MASSIVE SELL SIGNAL113            114            # Normalize funding rate (Usually between -0.01% and 0.01%)115            norm_funding = max(-1.0, min(1.0, funding_rate * 10000)) 116            117            # Normalize flow score (Usually between -3 and 3)118            norm_flow = max(-1.0, min(1.0, flow_score / 3.0))119            120            # Opposing forces: We want to trade WITH the flow, but AGAINST the crowd's leverage121            final_score = (norm_flow * 0.7) - (norm_funding * 0.3)122            123            return float(max(-1.0, min(1.0, final_score)))124 125        except Exception as e:126            logger.debug(f"Order Flow Fetch Error for {symbol}: {e}")127            return 0.0128 129    def _calculate_proxy_score(self, df):130        """Fallback: Uses C++ Accelerated Volatility Z-Score if API is blocked."""131        if df is None or df.empty or len(df) < 20: 132            return 0.0133            134        try:135            closes = df['close'].values136            returns = np.diff(closes) / (closes[:-1] + 1e-9)137            138            if len(returns) < 20: 139                return 0.0140                141            vol_z = fast_math.get_zscore(returns[-20:])142            143            if abs(vol_z) < 2.0: 144                return 0.0 145                146            close = closes[-1]147            open_p = df['open'].iloc[-1]148            direction = 1.0 if close > open_p else -1.0149            150            return float(min(abs(vol_z) / 5.0, 1.0) * direction)151            152        except Exception: 153            return 0.0154 155    def _async_update_cache(self, symbol, df):156        """Background thread worker to update the cache."""157        if self.mode == "LIVE_PUBLIC":158            score = self._fetch_funding_and_flow(symbol)159            if score == 0.0:160                score = self._calculate_proxy_score(df)161        else:162            score = self._calculate_proxy_score(df)163            164        with self.cache_lock:165            self.cache[symbol] = {'score': score, 'time': time.time()}166 167    def get_onchain_sentiment(self, symbol, df=None):168        """169        Returns a raw sentiment score from -1.0 (Heavy Selling) to 1.0 (Heavy Buying).170        🚨 NON-BLOCKING UPGRADE: Instantly returns cached value while updating in background.171        """172        if "BTC" not in symbol and "ETH" not in symbol and "SOL" not in symbol:173            return 0.0174            175        now = time.time()176        177        with self.cache_lock:178            cached_data = self.cache.get(symbol)179            180        # 1. Fresh Cache: Return immediately181        if cached_data and (now - cached_data['time']) < CACHE_DURATION:182            return float(cached_data['score'])183            184        # 2. Stale/Empty Cache: Fire background update to prevent blocking185        instant_proxy_score = self._calculate_proxy_score(df)186        self.http_executor.submit(self._async_update_cache, symbol, df)187        188        # Return whatever we have right now189        if cached_data:190            return float(cached_data['score'])191        return float(instant_proxy_score)192 193    def get_onchain_signal(self, symbol, df=None):194        """Converts the raw sentiment score into a definitive Action."""195        score = self.get_onchain_sentiment(symbol, df)196        197        if score >= 0.50:198            return "STRONG_BUY"199        elif score <= -0.50:200            return "STRONG_SELL"201        else:202            return "NEUTRAL"203 204# Singleton Instance for Global Imports205alpha_oracle = BlockchainAlpha()