Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
100000
End Equity
100000
Net Profit
0%
Sharpe Ratio
0
Sortino Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-8.741
Tracking Error
0.141
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
# region imports
from AlgorithmImports import *
from pytz import utc, timezone
# endregion

class QuantchaAlgorithm(QCAlgorithm):
    
    def initialize(self):
        volsource = QuantchaVolImproved

        self.set_start_date(2025, 5, 1)
        volsource.algorithm = self

        self.set_warm_up(30, resolution=Resolution.DAILY)
        self._symbol = self.add_data(volsource, 'NVDA', resolution=Resolution.DAILY).symbol   

    def on_data(self, data):
        for symbol, data_point in data.get(QuantchaVolImproved).items():
            #if self.live_mode:
            self.log(f'{self.time} {symbol} hv60 : {data_point.hv60}')                
            self.plot(str(symbol), 'hv60', data_point.hv60)

class QuantchaVolImproved(PythonData):
    def get_source(self, config, date, is_live):
        dt = timedelta(3 if is_live else 0)
        ticker = config.symbol.value.upper()
        url = ("https://data.nasdaq.com/api/v3/datatables/QUANTCHA/VOL.csv"
            f"?api_key=6Wkcb5mZdDuGjydpen9k&ticker={ticker}"
            f"&date.gte={date-dt:%Y-%m-%d}"
            f"&date.lte={date:%Y-%m-%d}")
        QuantchaVolImproved.algorithm.debug(f"{date:'%Y-%m-%d'} :: {ticker} -> {url}")
        return SubscriptionDataSource(url, SubscriptionTransportMedium.REMOTE_FILE, FileFormat.CSV)

    def reader(self, config, line, date, is_live):
        algorithm: QCAlgorithm = QuantchaVolImproved.algorithm
        algorithm.debug(line if line else 'Empty line')
        data = line.split(',')
        if not line or not data[1][0].isdigit():
            return None
        
        quantcha = QuantchaVolImproved()
        quantcha.symbol = config.symbol
        quantcha.time = datetime.strptime(data[1], "%Y-%m-%d")
        quantcha.end_time =  quantcha.time + timedelta(1)
        
        if is_live:
            time = quantcha.time
            now = datetime.now(tz=utc)
            if time.date() != now.date():
                algorithm.debug(f'{time} vs {now} -> return None')
                return None
            quantcha.end_time = Extensions.convert_from_utc(now, config.exchange_time_zone)
            quantcha.time = quantcha.end_time - timedelta(1)
            algorithm.debug(f'{time} vs {now} -> return data')

        columns = 'hv10,hv20,hv30,hv60,hv90,hv120,hv150,hv180,phv10,phv20,phv30,phv60,phv90,phv120,phv150,phv180,ivcall10,ivput10,ivmean10,ivmeanskew10,ivcall20,ivput20,ivmean20,ivmeanskew20,ivcall30,ivput30,ivmean30,ivmeanskew30,ivcall60,ivput60,ivmean60,ivmeanskew60,ivcall90,ivput90,ivmean90,ivmeanskew90,ivcall120,ivput120,ivmean120,ivmeanskew120,ivcall150,ivput150,ivmean150,ivmeanskew150,ivcall180,ivput180,ivmean180,ivmeanskew180,ivcall270,ivput270,ivmean270,ivmeanskew270,ivcall360,ivput360,ivmean360,ivmeanskew360,ivcall720,ivput720,ivmean720,ivmeanskew720,ivcall1080,ivput1080,ivmean1080,ivmeanskew1080'

        for index, column in enumerate(columns.split(',')):
            value = data[2+index].strip()
            quantcha[column] = float(value) if value and value[-1].isdigit() else -9999999
        
        # Default value is hv60
        quantcha.value = quantcha['hv60']
        return quantcha

    def default_resolution(self):
        return Resolution.DAILY