Skip to content

Instantly share code, notes, and snippets.

@hn4002
hn4002 / schwab_api_bugs_temp_fix.py
Created November 5, 2025 23:51
Workaround fix for the bugs in the Schwab Streaming API because of the lot vs share size changes
l2_quote["service"] = event["service"]
if l2_quote["service"].upper() == "NYSE_BOOK":
# Apply the volume fix - divide volume by 100 for all asks and bids for all exchanges
bidLevelContainer = l2_quote["BIDS"]
for bidLevel in bidLevelContainer:
bidLevelVolume = 0
for bidRow in bidLevel["BIDS"]:
bidRow["BID_VOLUME"] = bidRow["BID_VOLUME"] / 100.0
bidLevelVolume += bidRow["BID_VOLUME"]
@hn4002
hn4002 / tos_caculate_price_improv_n_fees.py
Created September 29, 2025 23:24
Calculate price improvement and fees from a TOS exported file
#=======================================================================================================================
# This file reads the exported file from TOS and calculates the price improvement and fees for each day.
# It then outputs a summary of the price improvement and fees for each day.
# To generate the exported file, follow these steps:
# 1. Go to "Monitor" -> "Account Statement" tab in TOS
# 2. Set the date range
# 3. In the "Order History" section, click on the gear icon (Customize...) on the right side and make sure "Price Improvement" column is selected
# 4. Click on the hamburger button ("Show Actions Menu") near the top right of the "Account Statement" tab
# 2. Click on Export to File
# 3. Save the file to your computer
@hn4002
hn4002 / polygon_download_daily_data.py
Last active September 15, 2025 22:24
A script to download daily data from polygon.io at the end of the day
# This script downloads daily data at EOD. It should be run 30 mins after the market close.
# You also need a paid subscription of polygon.io for the script to work. It takes about 75 secs
# to get data for 10k+ symbols (stocks + ETFs).
# Once the daily data is downloaded, it generates weekly and monthly data automatically. This data
# should match with the weekly and monthly data of Polygon.
import datetime
import json
import os
import pytz
@hn4002
hn4002 / das_stoploss_flatten_large.md
Last active May 16, 2025 23:23
DAS Script to Set SL and Flatten large position based on bid/ask

These scripts achieve these goals:

  • Normally a stoploss order gets trigerred based on the last trade price. These scripts will create a stoposs order in DAS Trader such that it gets trigerred based on the Ask or the Bid (although it can be modified to use the last trade price for the trigger).
  • The scripts will break a big order into multiple smaller orders of the desired size. For example, if we have 30k shares and we want to exit the full position once the stop is trigerred and we want to execute the order in the chunks of 4k shares, then the script will automatically do this. Some brokers some times take a long time to process a large order, so breaking into smaller chunks solves this problem.
  • When you add to an existing position, then the stoploss order does not need to be updated as it reads the position size when the stop is trigered and not when it is created.
@hn4002
hn4002 / NYSE_BOOK_vs_NASDAQ_BOOK.md
Created April 6, 2025 01:57
Schwab L2 Streaming: Subscribing to NYSE_BOOK or NASDAQ_BOOK?

In the initialization code, first find out the exchanges for the symbols and accordingly sort them into two buckets:

class SchwabStreamingClient:

    #=====================================================================================
    def __init__(self):
        # All one time initialization should be done here
        self.client = schwab.auth.client_from_token_file(
                api_key=client_id,
@hn4002
hn4002 / check_refresh_token_validity.md
Last active June 10, 2024 23:12
Check refresh token expiration time and show an error/warning accordingly.

This is what I do when I do manual auth:

    def _create_token_meta_file(self):
        # Create a file to save the timestamp for the last time the refresh token was generated
        meta_path = pathlib.Path(self._token_path).with_suffix(".meta.json")
        # First delete the meta file if it exists
        if os.path.exists(meta_path):
            os.remove(meta_path)
        # Now create the meta file with the current timestamp
@hn4002
hn4002 / data_utils.py
Last active June 5, 2024 20:12
Convert OHLCV 1-min data to other intraday timeframe
import math
import pandas
# ======================================================================================================================
def convert_data_for_timeframe(price_data, target_timeframe):
"""
Convert 1-min price data to a new timeframe.
Reference Links
* https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html
@hn4002
hn4002 / schwab_py_manual_auth_meta.py
Created May 15, 2024 17:09
schwab-py manual auth with some meta info
# This script is used to manually authenticate the user with the Schwab API.
# It deletes the token file at the beginning. It also creates a meta file with the current timestamp.
import datetime
import json
import os
import pathlib
import pytz
import sys
@hn4002
hn4002 / schwab-py-manual-oauth-flow.py
Last active May 11, 2024 18:57
schwab-py: Script for the weekly manual oauth flow
# This script is used to manually authenticate the user with the Schwab API.
# Delete the token file before running this script.
import schwab
from environment.instance_settings import schwabSettings
client_id = schwabSettings.SCHWAB_APP_ID
client_secret = schwabSettings.SCHWAB_APP_SECRET
@hn4002
hn4002 / schwab-py-get-history.py
Created May 11, 2024 18:40
schwab-py: Get price history
import datetime
import json
import os
import pytz
import sys
import schwab
from environment.instance_settings import schwabSettings