diff --git a/README.md b/README.md index 53d7d49..dd1de17 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,8 @@ [![codecov](https://codecov.io/gh/amor71/FINRAShortData/branch/main/graph/badge.svg?token=Gy7JKcpOqh)](https://codecov.io/gh/amor71/FINRAShortData) # FINRAShortData -Process FINRA Short Daily Data [feeds](https://developer.finra.org/docs#query_api-equity-equity_short_interest_standardized) -## Prerequisite - -* FINRA Developer Credentials are required. If you do not yet have an account, [create one here](https://developer.finra.org/create-account?Forward_URL=https://gateway.finra.org/app/dfo-console?rcpRedirNum=1). - -* Once you have access, you will need to create an API key. Daily Short Data feeds are free. [click here](https://gateway.finra.org/app/api-console/add-credential) to create API credential and follow the instructions. +Process FINRA Short Daily Data [feeds](https://www.finra.org/finra-data/browse-catalog/short-sale-volume-data/daily-short-sale-volume-files) ## Install @@ -20,29 +15,30 @@ To install the package type: ## Quick start -### Authenticate +### Example 1: Daily Short Volumes for past 2 days (inclusive) ```python -from finrashortdata import auth -token = auth(client_id=, secret=) +import asyncio +from finrashortdata import daily_shorts +import pandas as pd + +df : pd.DataFrame = asyncio.run(daily_shorts(offset=2)) ``` -### Example 1: Basic data loading & processing +### Example 2: Daily Short Volumes for time_range ```python +import asyncio from finrashortdata import daily_shorts +from datetime import date import pandas as pd -df : pd.DataFrame = daily_shorts(token) -``` -### Example 2: load latest data -```python -from finrashortdata import daily_shorts_chunk_and_size, daily_shorts - -chunk, max_data = daily_shorts_chunk_and_size(token) -df : pd.DataFrame = daily_shorts(token=token, offset=max_data-10*chunk) +df : pd.DataFrame = asyncio.run(daily_shorts( + start_date=date(year=2022, month=9, day=1), + end_date=date(year=2022, month=9, day=10))) ``` +*Scripts work as-is* ## Licensing @@ -55,6 +51,3 @@ Use the [Issues](https://github.com/amor71/FINRAShortData/issues) section ## Contributing If you'd like to contribute to the project, drop me a line at mailto:amor71@sgeltd.com - - - diff --git a/finrashortdata/__init__.py b/finrashortdata/__init__.py index 14c8581..4c95811 100644 --- a/finrashortdata/__init__.py +++ b/finrashortdata/__init__.py @@ -1,4 +1,3 @@ -__version__ = "0.0.13" +__version__ = "0.1.0" -from .auth import auth -from .daily import daily_shorts, daily_shorts_chunk_and_size +from .daily import daily_shorts diff --git a/finrashortdata/daily.py b/finrashortdata/daily.py index c3c5e14..8afbe49 100644 --- a/finrashortdata/daily.py +++ b/finrashortdata/daily.py @@ -1,103 +1,94 @@ -import asyncio -import concurrent.futures -import time -from typing import Optional, Tuple +import io +from datetime import date, datetime, timezone +from typing import List, Optional import pandas as pd +import pandas_market_calendars import requests from .decorators import timeit -url: str = "https://api.finra.org/data/group/OTCMarket/name/regShoDaily" - -def _requests_get(token: str, chunk_size: int, offset: int) -> pd.DataFrame: - r = requests.get( - url=url, - headers={ - "Authorization": f"Bearer {token}", - "Accept": "application/json", - }, - params={"limit": chunk_size, "offset": offset}, - ) - r.raise_for_status() - - if r.status_code in (429, 502): - print(f"{url} return {r.status_code}, waiting and re-trying") - time.sleep(10) - return _requests_get(token, chunk_size, offset) - - x = r.json() - df = pd.DataFrame(x) - df.rename( - columns={ - "securitiesInformationProcessorSymbolIdentifier": "symbol", - "totalParQuantity": "volume", - "shortParQuantity": "shorts", - "shortExemptParQuantity": "exempt", - }, - inplace=True, +def _short_by_date(d: datetime) -> pd.DataFrame: + base_url = f'https://cdn.finra.org/equity/regsho/daily/CNMSshvol{d.strftime("%Y%m%d")}.txt' + content = requests.get(base_url).content + df = pd.read_csv( + io.StringIO(content.decode("utf-8")), + sep="|", + engine="python", + skipfooter=1, + keep_default_na=False, ) - df.drop(["reportingFacilityCode", "marketCode"], axis=1, inplace=True) + df["date"] = d.date() + + if not df.empty: + del df["Date"] + df["ShortPercent"] = round( + 100.0 * df["ShortVolume"] / df["TotalVolume"], 2 + ) + df["ShortExemptPercent"] = round( + 100.0 * df["ShortExemptVolume"] / df["TotalVolume"], 2 + ) + return df.set_index(["Symbol", "date"]).sort_index().dropna() + return df -def daily_shorts_chunk_and_size(token: str) -> Tuple[int, int]: - """Return the optimal chunk size and total number of data-points, +def _get_trading_holidays( + mcal: pandas_market_calendars.MarketCalendar, +) -> List[str]: + return mcal.holidays().holidays - Chunk size is used internally, by the daily_shorts() function - to reduce the number of calls to the FINRA end-point, - it is also used as the 'offset' step when calling daily_shorts() directly with restrictions. - Input Arguments: token obtained from the auth() function. - Returns: tuple with chunk size followed by number of data-points to be loaded from FINRA end-point. - """ - r = requests.get( - url=url, - headers={ - "Authorization": f"Bearer {token}", - "Accept": "application/json", - }, - params={"limit": 1}, +def _calc_start_date_from_offset( + mcal: pandas_market_calendars.MarketCalendar, end_date: date, offset: int +) -> date: + cbd_offset = pd.tseries.offsets.CustomBusinessDay( + n=offset - 1, holidays=_get_trading_holidays(mcal) ) - r.raise_for_status() - return int(r.headers["Record-Max-Limit"]), int(r.headers["Record-Total"]) + return (datetime.now(timezone.utc) - cbd_offset).date() + + +def _short_iterator(days: List) -> pd.DataFrame: + df = pd.DataFrame() + for day in days: + day_df = _short_by_date(day) + if not day_df.empty: + df = ( + day_df + if df.empty + else pd.concat([df, day_df], axis=0).sort_index() + ) + + return df @timeit async def daily_shorts( - token: str, offset: int = 0, limit: Optional[int] = None + start_date: Optional[date] = None, + end_date: Optional[date] = date.today(), + offset: Optional[int] = None, ) -> pd.DataFrame: """Download Daily Short details Input Arguments: - token -> obtained from the auth() function. - offset -> starting point (default 0). - limit -> end point (default not limit). + start_date -> Optional, start date for pulling short-date. + end_date -> last date (inclusive) for pulling short-date. + offset -> If start_date not provided, calculate start date as offset from end_date. Returns: If successful returns DataFrame with all details """ - chunk_size, max_records = daily_shorts_chunk_and_size(token) - - if limit: - max_records = min(max_records, limit) - - print( - f"loading data (chunk_size={chunk_size}, offset={offset}, max_records={max_records-offset})..." - ) - with concurrent.futures.ThreadPoolExecutor() as executor: - loop = asyncio.get_event_loop() - futures = [ - loop.run_in_executor( - executor, _requests_get, token, chunk_size, offset - ) - for offset in range(offset, max_records, chunk_size) - ] - df = ( - pd.concat(await asyncio.gather(*futures)) - .groupby(["tradeReportDate", "symbol"]) - .sum() + if not start_date and not offset: + raise ValueError( + "daily_shorts(): must have either start_date or offset" ) + elif not start_date and offset < 1: # type: ignore + raise ValueError("daily_shorts(): offset >= 1") - df["short_percent"] = round(100.0 * df.shorts / df.volume, 1) + nyse = pandas_market_calendars.get_calendar("NYSE") + if not start_date: + start_date = _calc_start_date_from_offset(nyse, end_date, offset) # type: ignore - return df + schedule = nyse.schedule(start_date=start_date, end_date=end_date) + days = schedule.index.to_list() + + return _short_iterator(days) if len(days) else pd.DataFrame() diff --git a/notebooks/process_files.ipynb b/notebooks/process_files.ipynb new file mode 100644 index 0000000..94c7e27 --- /dev/null +++ b/notebooks/process_files.ipynb @@ -0,0 +1,466 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "80b70f7b", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import io\n", + "import requests\n", + "from datetime import datetime\n", + "import pandas_market_calendars\n", + "\n", + "from typing import List\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a3de1c25", + "metadata": {}, + "outputs": [], + "source": [ + "# Last date for short data\n", + "end_date = datetime(year=2022, month=9, day=20) \n", + "\n", + "# Num days for trend\n", + "offset = 500" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "daec42f4", + "metadata": {}, + "outputs": [], + "source": [ + "nyse = pandas_market_calendars.get_calendar('NYSE')" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "80ca17d2", + "metadata": {}, + "outputs": [], + "source": [ + "def finra_short_by_date(d: datetime) -> pd.DataFrame:\n", + " base_url = f'https://cdn.finra.org/equity/regsho/daily/CNMSshvol{d.strftime(\"%Y%m%d\")}.txt'\n", + " content = requests.get(base_url).content\n", + " df = pd.read_csv(io.StringIO(content.decode('utf-8')), sep=\"|\", index_col=0, usecols=[1,2,3,4,5])\n", + " df['date'] = d.date()\n", + " df['ShortPercent'] = round(100. * df['ShortVolume'] / df['TotalVolume'], 2)\n", + " return df\n", + "\n", + "def get_trading_holidays() -> List[str]:\n", + " return nyse.holidays().holidays" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a495111d", + "metadata": {}, + "outputs": [], + "source": [ + "cbd_offset = pd.tseries.offsets.CustomBusinessDay(n=offset - 1, holidays=get_trading_holidays())\n", + "start_date = datetime.utcnow() - cbd_offset\n", + "schedule = nyse.schedule(start_date=start_date, end_date=end_date)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "3b39fe24", + "metadata": {}, + "outputs": [], + "source": [ + "data = {'date': [], 'short_percentage': []}\n", + "for day in schedule.index.to_list():\n", + " df = finra_short_by_date(day)\n", + " data['date'].append(day)\n", + " data['short_percentage'].append(df.loc['AAPL']['ShortPercent'])" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a060cf97", + "metadata": {}, + "outputs": [], + "source": [ + "appl_data = pd.DataFrame(data=data['short_percentage'], index=data['date'], columns=['Short Percentage'])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "45d91dfb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Short Percentage
2020-09-2943.30
2020-09-3040.72
2020-10-0161.06
2020-10-0260.28
2020-10-0536.85
......
2022-09-1446.41
2022-09-1545.32
2022-09-1640.92
2022-09-1940.82
2022-09-2040.26
\n", + "

498 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " Short Percentage\n", + "2020-09-29 43.30\n", + "2020-09-30 40.72\n", + "2020-10-01 61.06\n", + "2020-10-02 60.28\n", + "2020-10-05 36.85\n", + "... ...\n", + "2022-09-14 46.41\n", + "2022-09-15 45.32\n", + "2022-09-16 40.92\n", + "2022-09-19 40.82\n", + "2022-09-20 40.26\n", + "\n", + "[498 rows x 1 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "appl_data" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "bbb2583f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([18536., 18628., 18718., 18809., 18901., 18993., 19083., 19174.,\n", + " 19266.]),\n", + " [Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, ''),\n", + " Text(0, 0, '')])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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xhnYuXOn5z7fuPl7OOFTp4U+16ZNm3DnnXdiwYIFeO+99/D2229j4sSJeUpuI5PJeCp4ADjssMOwbNkyvPfee1i5ciVeeOGFwMcOi3Iq+FmzZuHZZ591fPbss89i1qxZZZKo+IgUfISKxYEDB7BgwQI89thjjhdz/vz5OOWUUzBz5kwceeSRDquzV69euOmmm3D00Udj+vTpUoW8ZMkSnHrqqZg8eTLOPvtsbN261VeWyy67DGeddZalKG+//XZMnToV48ePx7XXXmuFuH77P67D3//sbI0we/ZsfOMb37D+f+SRR3DTTTc5ttmxYwcaGxvRq1cv6zrESIrf/e53mDZtGsaMGYM33ngDgOEEv+aaazBhwgQcc8wxeO211wAATzzxBM4//3ycccYZmD59Om6++Wa88cYbaGpqwn333ae8xng8jhNPPBFr167Fzp07cfHFF2Pq1KmYOnUqFi5cCMBY2Vx55ZU46aSTcOWVV2L79u248MILMWnSJEyaNAlvvvkmAOCpp57CtGnT0NTUhOuuuw7ZbBY333wz2tvb0dTUhMsvvxwAcMEFF2Dy5Mk4+uij8fDDD1uy9OrVC7feeismTZqE448/Htu3bwcAfPTRRzj++OMxYcIEfPe737XuFwDcc889mDp1KiZOnIjvf//7Odc3ffp0rF692nrera2tmDt3Li644ALMmzcPxxxzDCZMmIAvfelL6OzszNlfPNecOXNw9dVXAzBWh9dffz2OP/54HHrooZg/fz6+9KUvYdy4cdY2APDKK6/ghBNOwLHHHotLL70UBw4cQLERcfARAuEHf3ofK7e0FPSYRx3cG9//zNHK71988UWcc845GDNmDAYMGIAlS5Zg8uTJAIBFixZh5cqVGDlyJM455xz84Q9/wCWXXILW1lZMmTIF9913H26//Xb84Ac/wM9//nPrmOl0Gl//+tfx4osvYtCgQXjuuedw6623Yvbs2b7yHnvssRZVdMMNN+B//ud/AABXXnklXnrpJXzmM5+R7ve5z30Od955J+655x4kEgk8/vjjOVTBpEmTMGTIEIwePRrTp0/HRRdd5DheJpPBokWL8Je//AU/+MEPMHfuXPziF78AEWH58uVYvXo1zjrrLHz44YcAgHfeeQfvvfce+vfvj/nz5+PHP/4xXnrpJc/ra2trw7x583D77bfjxhtvxE033YSTTz4Zn3zyCc4++2wrF2LlypVYsGAB6urqcNlll+HUU0/F888/j2w2iwMHDmDVqlV47rnnsHDhQiQSCXzta1/Db37zG9x99934+c9/jmXLllnnnD17Nvr374/29nZMnToVF198MQYMGIDW1lYcf/zxuPPOO/Gtb30LjzzyCL773e/ixhtvxI033ohZs2bhoYceso7zyiuvYM2aNVi0aBEYYzj//PPx+uuv45RTTrG2icViuPjii/Hb3/4WN954I/70pz/htNNOQzKZxNVXX4158+ZhzJgx+OIXv4gHH3zQMSn7Ye/evXjrrbfwxz/+Eeeffz4WLlyIRx99FFOnTsWyZcswfPhw3HHHHZg7dy4aGhrwox/9CPfee681hoqFyIKPULF45pln8PnPfx4A8PnPf95B00ybNg2HHnooYrEYZs2ahQULFgAANE3DZZddBgC44oorrM85PvjgA6xYsQIzZsxAU1MT7rjjDmzatCmQPGIi2muvvYbjjjsOEyZMwKuvvor3338fgDxEslevXjjjjDPw0ksvYfXq1Uin05gwYYJjm1gshpdffhlz5szBmDFjcNNNN+G2226zvr/ooosAAJMnT8b69esBAAsWLMAVV1wBABg7dixGjhxpKfgZM2agf//+ga7ro48+QlNTE0466STMnDkT5557LubOnYsbbrgBTU1NOP/889HS0mJZnOeffz7q6uoAAK+++iquv/566xr69OmDefPmYcmSJZg6dSqampowb948rFu3TnruBx54wLLSN27ciDVr1gAAkskkzjvvvJxrfuutt3DppZcCAL7whS9Yx3nllVfwyiuv4JhjjrEmYn4sESJNw+mZDz74AKNHj8aYMWMAAFdddRVef/31QPeO4zOf+QyICBMmTMCQIUMwYcIEaJqGo48+GuvXr8fbb7+NlStX4qSTTkJTUxOefPJJbNiwIdQ58oGvBU9EhwD4PwBDYJQneZgxdj8R3Qbg3wDwNfB3GGN/KZagEcoLL0u7GNizZw9effVVLF++HESEbDYLIsI999wDIDeczK8dIgdjDEcffTTeeuut0DItXboUU6ZMQUdHB772ta9h8eLFOOSQQ3Dbbbf5xi5/5StfwV133YWxY8fimmuuUco6bdo0TJs2DTNmzMA111xjKfmamhoAhhINwn03NAQvHsY5eBG6ruPtt99GbW1uZJffsRljuOqqq/DDH/7Qc7v58+dj7ty5eOutt1BfX4/TTjvNuo+JRMJ6dkGumTGGW265Bdddd53ndieeeCK2bt2Kd999F2+++SaeffZZfPDBB577cIhjyf28+fPRNM36m/+fyWQQi8UwY8aMkvuSgljwGQDfZIwdBeB4AP9OREeZ393HGGsyfyLlHqFgmDNnDq688kps2LAB69evx8aNGzF69GiLf160aBE+/vhj6LqO5557DieffDIAQzHxaJmnn37a+pzjyCOPxM6dOy0Fn06nLevbC7///e/xyiuvYNasWdbLPXDgQBw4cMAZnUOQxkked9xx2LhxI55++mmpU2/Lli145513rP+XLVuGkSNHesr0qU99Cr/5zW8AAB9++CE++eQTHHnkkTnbNTY2Yv/+/b7XKOKss87Cz372M4c8MkyfPh0PPvggACCbzWLfvn2YPn065syZgx07dgAwJmturSYSCaTTaQDAvn370K9fP9TX12P16tV4++23feU6/vjj8fvf/x4AHH6Zs88+G7Nnz7ZWGZs3b7bOL4KIcNlll+Gqq67Cueeei9raWhx55JFYv3491q5dCwD49a9/jVNPPTVn3yFDhmDVqlXQdR3PP/+8r6xuuRcuXGido7W11VptFRO+Cp4xtpUx9o75934YDbeHFVuwCD0bzzzzDC688ELHZxdffLFlAU2dOhU33HADxo0bh9GjR1vbNjQ0YNGiRRg/fjxeffXVHI4zmUxizpw5+Pa3v41JkyahqanJcgy6cd9991lhkk899RReffVVDBo0CH379sW//du/Yfz48Tj77LMxdepUax+FfgdgcPEnnXQS+vXrl/NdOp3Gf/3Xf2Hs2LFoamrCc889h/vvv9/zHn3ta1+DruuYMGECLrvsMjzxxBMO65Fj4sSJiMVimDRpkqeTVcQDDzyAxYsXY+LEiTjqqKMcfLeI+++/H6+99homTJiAyZMnY+XKlTjqqKNwxx134KyzzsLEiRMxY8YMy7F57bXXYuLEibj88stxzjnnIJPJYNy4cbj55ptx/PHH+8r105/+FPfeey8mTpyItWvXok+fPgCMCekLX/gCTjjhBEyYMAGXXHKJclKbNWsW3n33XWuira2txeOPP45LL73Uola++tWv5ux3991347zzzsOJJ56IoUPDhTUPGjQITzzxBGbNmoWJEyfihBNO6HLobyAw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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(\n", + " appl_data,\n", + " label=\"Apple Daily Short Percetange Volume\",\n", + ")\n", + "plt.legend()\n", + "plt.xticks(rotation=45) " + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "08ad2bea", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ShortVolumeShortExemptVolumeTotalVolumeMarketdateShortPercent
Symbol
A216459.0487.0426407.0B,Q,N2022-09-2050.76
AA1337513.01705.02012123.0B,Q,N2022-09-2066.47
AAA10.00.021.0Q,N2022-09-2047.62
AAAU111153.00.0396936.0B,Q,N2022-09-2028.00
AAC7635.00.0123380.0Q2022-09-206.19
.....................
ZWS166458.029.0348833.0B,Q,N2022-09-2047.72
ZY57926.00.0154750.0B,Q,N2022-09-2037.43
ZYME42970.0125.0131545.0B,Q,N2022-09-2032.67
ZYNE92781.00.0305456.0B,Q,N2022-09-2030.37
ZYXI18944.00.046128.0B,Q,N2022-09-2041.07
\n", + "

9911 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " ShortVolume ShortExemptVolume TotalVolume Market date \\\n", + "Symbol \n", + "A 216459.0 487.0 426407.0 B,Q,N 2022-09-20 \n", + "AA 1337513.0 1705.0 2012123.0 B,Q,N 2022-09-20 \n", + "AAA 10.0 0.0 21.0 Q,N 2022-09-20 \n", + "AAAU 111153.0 0.0 396936.0 B,Q,N 2022-09-20 \n", + "AAC 7635.0 0.0 123380.0 Q 2022-09-20 \n", + "... ... ... ... ... ... \n", + "ZWS 166458.0 29.0 348833.0 B,Q,N 2022-09-20 \n", + "ZY 57926.0 0.0 154750.0 B,Q,N 2022-09-20 \n", + "ZYME 42970.0 125.0 131545.0 B,Q,N 2022-09-20 \n", + "ZYNE 92781.0 0.0 305456.0 B,Q,N 2022-09-20 \n", + "ZYXI 18944.0 0.0 46128.0 B,Q,N 2022-09-20 \n", + "\n", + " ShortPercent \n", + "Symbol \n", + "A 50.76 \n", + "AA 66.47 \n", + "AAA 47.62 \n", + "AAAU 28.00 \n", + "AAC 6.19 \n", + "... ... \n", + "ZWS 47.72 \n", + "ZY 37.43 \n", + "ZYME 32.67 \n", + "ZYNE 30.37 \n", + "ZYXI 41.07 \n", + "\n", + "[9911 rows x 6 columns]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "finra_short_by_date(end_date).dropna()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tests/test_auth.py b/tests/test_auth.py deleted file mode 100644 index f39a15a..0000000 --- a/tests/test_auth.py +++ /dev/null @@ -1,58 +0,0 @@ -import os - -import pytest -from requests.exceptions import HTTPError - -from finrashortdata import auth - - -def test_auth_positive() -> bool: - client_id = os.getenv("TEST_API_CLIENT_ID", None) - secret = os.getenv("TEST_API_SECRET", None) - - if not client_id or not secret: - raise AssertionError( - "tests require env variables TEST_API_CLIENT_ID, TEST_API_SECRET" - ) - - token = auth(client_id, secret) - - print(token) - - return True - - -def test_auth_negative() -> bool: - try: - auth("some in correct stuff", "lead to error") - except HTTPError: - return True - - raise AssertionError("Excepted HTTPError") - - -def test_auth_no_type() -> bool: - try: - auth() # type: ignore - except TypeError: - return True - - raise AssertionError("Excepted TypeError exception") - - -def test_auth_no_secret() -> bool: - try: - auth("id1") # type: ignore - except TypeError: - return True - - raise AssertionError("Excepted TypeError exception") - - -def test_auth_none_values() -> bool: - try: - auth(None, "secret") # type: ignore - except TypeError: - return True - - raise AssertionError("Excepted TypeError exception") diff --git a/tests/test_process.py b/tests/test_process.py deleted file mode 100644 index ef1444f..0000000 --- a/tests/test_process.py +++ /dev/null @@ -1,40 +0,0 @@ -import os - -import pandas as pd -import pytest - -from finrashortdata import auth, daily_shorts, daily_shorts_chunk_and_size - - -async def test_daily_shorts_positive() -> bool: - client_id = os.getenv("TEST_API_CLIENT_ID", None) - secret = os.getenv("TEST_API_SECRET", None) - - if not client_id or not secret: - raise AssertionError( - "tests require env variables TEST_API_CLIENT_ID, TEST_API_SECRET" - ) - token = auth(client_id, secret) - chunk, max_data = daily_shorts_chunk_and_size(token) - _df: pd.DataFrame = await daily_shorts( - token=token, offset=max_data - chunk - ) - print(_df) - - return True - - -async def test_daily_shorts_positive_limit() -> bool: - client_id = os.getenv("TEST_API_CLIENT_ID", None) - secret = os.getenv("TEST_API_SECRET", None) - - if not client_id or not secret: - raise AssertionError( - "tests require env variables TEST_API_CLIENT_ID, TEST_API_SECRET" - ) - token = auth(client_id, secret) - chunk, max_data = daily_shorts_chunk_and_size(token) - _df: pd.DataFrame = await daily_shorts(token=token, offset=0, limit=chunk) - print(_df) - - return True