py-market-profile

repository·master·Indexed 19 days ago

https://github.com/bfolkens/py-market-profile

A Python library for calculating Market Profile (Volume Profile) metrics from Pandas DataFrames containing OHLCV data. It supports both volume-based ('vol') and Time Price Opportunity ('tpo') modes. Key features include calculating Point of Control (POC), Value Area, Initial Balance, and Open Range, as well as identifying High and Low Value Nodes. The library allows for time-based slicing of MarketProfile objects to analyze specific market sessions.

Tokens
2.5K
Snippets
9
Records
9
Agent score
63%

What's inside py-market-profile

  1. Calculate Market Profile from a Pandas DataFrame

    master

    To use marketprofile, provide a Pandas DataFrame where the index is a timestamp and the columns contain OHLCV (Open, High, Low, Close, Volume) values.

    1. Initialize a MarketProfile object with your DataFrame.
    2. Slice the object using timestamp ranges to focus on specific periods.
    3. Access the .profile attribute to get the volume profile series.
    from market_profile import MarketProfile
    import pandas_datareader as data
    
    # Load data (example using Yahoo Finance)
    amzn = data.get_data_yahoo('AMZN', '2019-12-01', '2019-12-31')
    
    # Create the MarketProfile object
    mp = MarketProfile(amzn)
    
    # Slice for a specific time range
    mp_slice = mp[amzn.index.min():amzn.index.max()]
    
    # Get the profile series
    print(mp_slice.profile)
  2. Slice MarketProfile to create a MarketProfileSlice

    master

    You can extract specific time periods or data segments from a MarketProfile object using standard Python slicing. Slicing a MarketProfile returns a MarketProfileSlice object, which automatically calculates the profile metrics (POC, Value Area, etc.) for that specific subset of data.

    Example:

    # Get profile for a specific slice of the dataframe
    sliced_profile = mp[slice(start_time, end_time)]
    # If mp is a MarketProfile instance
    # Slicing returns a MarketProfileSlice
    sliced_mp = mp[0:100] 
    # or using timestamps if the index is DatetimeIndex
    sliced_mp = mp['2023-01-01':'2023-01-02']
  3. Access Market Profile attributes and properties

    master

    Once you have a sliced MarketProfile object (mp_slice), you can extract various market profile metrics and properties:

    • .profile: Returns a Pandas Series representing the volume at different price levels.
    • .poc_price: Returns the Point of Control (POC) price.
    • .profile_range: Returns a tuple of (min_price, max_price) for the profile.
    • .value_area: Returns a tuple of (low_price, high_price) for the value area.
    • .balanced_target: Returns the balanced target price.
    • .initial_balance(): Returns a tuple representing the initial balance range.
    • .open_range(): Returns a tuple representing the open range.
    • .low_value_nodes: Returns a Pandas Series of low value nodes.
    • .high_value_nodes: Returns a Pandas Series of high value nodes.
    # Assuming mp_slice is a sliced MarketProfile object
    print(mp_slice.poc_price)
    print(mp_slice.value_area)
    print(mp_slice.initial_balance())
    print(mp_slice.low_value_nodes)
  4. Load Google Finance data for Market Profile analysis

    master

    To use py-market-profile, you need OHLCV (Open, High, Low, Close, Volume) data. You can use the google_finance module to download data from Google Finance and save it to a local file, then read it into a pandas DataFrame.

    Use get_google_data(filename, ticker, duration_minutes, interval_minutes) to download data and read_google_data(filename) to load it.

    import os
    from google_finance import get_google_data, read_google_data
    
    # Download and save data if it doesn't exist
    if not os.path.exists('google.txt'):
        # get_google_data(filename, ticker, duration_minutes, interval_minutes)
        get_google_data('google.txt', 'GOOG', 60 * 30, 5)
    
    # Load the data into a DataFrame
    df = read_google_data('google.txt')
  5. Create and slice a MarketProfile object

    master

    Initialize a MarketProfile object by passing a pandas DataFrame containing OHLCV data and specifying the tick_size.

    You can slice the MarketProfile object using time-based offsets (e.g., using pd.Timedelta) to analyze specific market sessions or time windows.

    from market_profile import MarketProfile
    import pandas as pd
    
    # Initialize the profile with OHLCV data
    mp = MarketProfile(df, tick_size=1)
    
    # Slice the profile for the last 6.5 hours
    mp_slice = mp[df.index.max() - pd.Timedelta(6.5, 'h'):df.index.max()]
  6. Extract market metrics from MarketProfileSlice

    master

    Once you have a MarketProfileSlice (via slicing a MarketProfile), you can access several key market profile metrics:

    • open_range(): Returns a tuple (low, high) representing the price range during the open_range_size period.
    • initial_balance(): Returns a tuple (low, high) representing the price range during the initial_balance_delta period.
    • calculate_value_area(): Returns a tuple (val, vah) representing the Value Area Low and Value Area High.
    • calculate_balanced_target(): Returns the calculated balanced target price (bt).
    • find_extrema(sign): Finds local extrema in the profile. Use np.less for Low Value Nodes (LVN) and np.greater for High Value Nodes (HVN).
    • as_dict(): Returns a dictionary containing all calculated metrics.

    Dictionary Keys in as_dict():

    • or_low, or_high: Open Range bounds.
    • ib_low, ib_high: Initial Balance bounds.
    • poc: Point of Control price.
    • low, high: Profile price range bounds.
    • val, vah: Value Area Low and High.
    • bt: Balanced Target.
    • lvn: Low Value Nodes (Series).
    • hvn: High Value Nodes (Series).
    # Assuming sliced_mp is a MarketProfileSlice
    metrics = sliced_mp.as_dict()
    
    print(f"POC: {metrics['poc']}")
    print(f"Value Area: {metrics['val']} - {metrics['vah']}")
    print(f"Open Range: {metrics['or_low']} - {metrics['or_high']}")
  7. Initialize MarketProfile

    master

    The MarketProfile class is the primary entry point for analyzing market data. It takes a pandas DataFrame containing market data (expected to have 'Close', 'Low', 'High', and 'Volume' columns) and applies market profile logic based on specified parameters.

    Parameters:

    • df: A pandas DataFrame.
    • tick_size (float, default: 0.05): The minimum price increment.
    • prices_per_row (int, default: 1): Multiplier for tick size to determine row size.
    • row_size (float, default: tick_size * prices_per_row): The actual price width of a profile row.
    • open_range_size (pd.Timedelta, default: 10 minutes): Duration of the open range.
    • initial_balance_delta (pd.Timedelta, default: 1 hour): Duration of the initial balance period.
    • value_area_pct (float, default: 0.70): The percentage of volume/TPO to include in the value area.
    • mode (str, default: 'vol'): The calculation mode. Use 'vol' for volume-based profiles or 'tpo' for Time Price Opportunity (count-based) profiles.
    import pandas as pd
    from market_profile import MarketProfile
    
    # Assuming df has 'Close', 'Low', 'High', 'Volume' and a DatetimeIndex
    df = pd.read_csv('market_data.csv', index_col=0, parse_dates=True)
    
    mp = MarketProfile(
        df, 
        tick_size=0.25, 
        mode='vol', 
        value_area_pct=0.70
    )
  8. Access Market Profile indicators and data

    master

    Once a MarketProfile (or a slice of one) is created, you can access calculated market indicators and the underlying profile data:

    • mp.profile: The underlying profile data (can be plotted using pandas .plot())
    • mp.poc_price: Point of Control price
    • mp.profile_range: The range of the profile
    • mp.value_area: The value area range
    • mp.balanced_target: The balanced target price
    • mp.initial_balance(): Method to return the initial balance range
    • mp.open_range(): Method to return the opening range

    Note: The methods initial_balance() and open_range() return a tuple representing the range.

    # Accessing indicators from a MarketProfile slice
    print "Initial balance: %f, %f" % mp_slice.initial_balance()
    print "Opening range: %f, %f" % mp_slice.open_range()
    print "POC: %f" % mp_slice.poc_price
    print "Profile range: %f, %f" % mp_slice.profile_range
    print "Value area: %f, %f" % mp_slice.value_area
    print "Balanced Target: %f" % mp_slice.balanced_target
    
    # Plotting the profile data
    mp_slice.profile.plot(kind='bar')