Repository: gridstatus/gridstatus
Pull request #555: feat(ENG 1317): CAISO Scheduling Point / Tie Combo LMPs
Author: login: Kladar
Labels: name: enhancement
description: New feature or request
Created: 2025-03-11T18:34:37Z | Merged: 2025-03-14T16:02:23Z

## Summary
Adds the `caiso_lmp_scheduling_point_tie_combination_5_min`, `caiso_lmp_scheduling_point_tie_combination_15_min`, and `caiso_lmp_scheduling_point_tie_combination_hourly` datasets.

```
from gridstatus.caiso import CAISO
caiso = CAISO()

df = caiso.get_lmp_scheduling_point_tie_real_time_5_min(date="2025-03-10")
print(df)

df = caiso.get_lmp_scheduling_point_tie_real_time_15_min(date="2025-03-10")
print(df)

df = caiso.get_lmp_scheduling_point_tie_day_ahead_hourly(date="2025-03-10")
print(df)
```


Diff:
diff --git a/gridstatus/caiso.py b/gridstatus/caiso.py
index 1bb167932..4f47a294c 100644
--- a/gridstatus/caiso.py
+++ b/gridstatus/caiso.py
@@ -184,6 +184,54 @@
             "grp_type": [None, "ALL", "ALL_APNODES"],
         },
     },
+    "lmp_scheduling_point_tie_combination_5_min": {
+        "query": {
+            "path": "SingleZip",
+            "resultformat": 6,
+            "queryname": "PRC_SPTIE_LMP",
+            "version": 5,
+        },
+        "params": {
+            "market_run_id": "RTD",
+            "node": None,
+            "grp_type": [None, "ALL", "ALL_APNODES"],
+        },
+        "meta": {
+            "max_query_frequency": "1h",
+        },
+    },
+    "lmp_scheduling_point_tie_combination_15_min": {
+        "query": {
+            "path": "SingleZip",
+            "resultformat": 6,
+            "queryname": "PRC_SPTIE_LMP",
+            "version": 5,
+        },
+        "params": {
+            "market_run_id": "RTPD",
+            "node": None,
+            "grp_type": [None, "ALL", "ALL_APNODES"],
+        },
+        "meta": {
+            "max_query_frequency": "1h",
+        },
+    },
+    "lmp_scheduling_point_tie_combination_hourly": {
+        "query": {
+            "path": "SingleZip",
+            "resultformat": 6,
+            "queryname": "PRC_SPTIE_LMP",
+            "version": 5,
+        },
+        "params": {
+            "market_run_id": "DAM",
+            "node": None,
+            "grp_type": [None, "ALL", "ALL_APNODES"],
+        },
+        "meta": {
+            "max_query_frequency": "1d",
+        },
+    },
     "demand_forecast": {
         "query": {
             "path": "SingleZip",
@@ -2247,3 +2295,134 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_5_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_real_time_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_15_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_day_ahead_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            try:
+                df = self.get_lmp_scheduling_point_tie_day_ahead_hourly(
+                    pd.Timestamp.now(tz=self.default_timezone).normalize()
+                    + pd.Timedelta(days=1),
+                )
+            except KeyError:
+                df = self.get_lmp_scheduling_point_tie_day_ahead_hourly(
+                    "today",
+                )
+
+            return df
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Node",
+                "TIE": "Tie",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Node",
+                "Tie",
+                "Market",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
+            columns={
+                "MCE": "Energy",
+                "MCC": "Congestion",
+                "MCL": "Loss",
+                "MGHG": "GHG",
+            },
+        )
+
+        df["Location"] = df["Node"] + " " + df["Tie"]
+        return df[
+            [
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Market",
+                "Node",
+                "Tie",
+                "LMP",
+                "Energy",
+                "Congestion",
+                "Loss",
+                "GHG",
+            ]
+        ]
diff --git a/gridstatus/tests/source_specific/test_caiso.py b/gridstatus/tests/source_specific/test_caiso.py
index 3daa192f8..e9fd95fe2 100644
--- a/gridstatus/tests/source_specific/test_caiso.py
+++ b/gridstatus/tests/source_specific/test_caiso.py
@@ -789,3 +789,143 @@ def test_get_pnodes(self):
         with caiso_vcr.use_cassette("test_get_pnodes.yaml"):
             df = self.iso.get_pnodes()
             assert df.shape[0] > 0
+
+    """get_lmp_scheduling_point_tie_combination"""
+
+    def _check_lmp_scheduling_point_tie(self, df: pd.DataFrame):
+        assert df.shape[0] > 0
+        assert df.columns.tolist() == [
+            "Interval Start",
+            "Interval End",
+            "Location",
+            "Market",
+            "Node",
+            "Tie",
+            "LMP",
+            "Energy",
+            "Congestion",
+            "Loss",
+            "GHG",
+        ]
+
+        assert (df["Location"] == df["Node"] + " " + df["Tie"]).all()
+
+        self._check_time_columns(
+            df,
+            instant_or_interval="interval",
+            skip_column_named_time=True,
+        )
+
+    @pytest.mark.parametrize("date", ["2022-10-15"])
+    def test_get_lmp_scheduling_point_tie_real_time_5_min(self, date):
+        with caiso_vcr.use_cassette(
+            f"test_get_lmp_scheduling_point_tie_real_time_5_min_{date}.yaml",
+        ):
+            df = self.iso.get_lmp_scheduling_point_tie_real_time_5_min(date)
+            self._check_lmp_scheduling_point_tie(df)
+
+            interval_minutes = (
+                df["Interval End"] - df["Interval Start"]
+            ).dt.total_seconds() / 60
+            assert (interval_minutes == 5).all()
+
+    @pytest.mark.parametrize("date", ["2022-10-15"])
+    def test_get_lmp_scheduling_point_tie_real_time_15_min(self, date):
+        with caiso_vcr.use_cassette(
+            f"test_get_lmp_scheduling_point_tie_real_time_15_min_{date}.yaml",
+        ):
+            df = self.iso.get_lmp_scheduling_point_tie_real_time_15_min(date)
+            self._check_lmp_scheduling_point_tie(df)
+
+            interval_minutes = (
+                df["Interval End"] - df["Interval Start"]
+            ).dt.total_seconds() / 60
+            assert (interval_minutes == 15).all()
+
+    @pytest.mark.parametrize("date", ["2022-10-15"])
+    def test_get_lmp_scheduling_point_tie_day_ahead_hourly(self, date):
+        with caiso_vcr.use_cassette(
+            f"test_get_lmp_scheduling_point_tie_day_ahead_hourly_{date}.yaml",
+        ):
+            df = self.iso.get_lmp_scheduling_point_tie_day_ahead_hourly(date)
+            self._check_lmp_scheduling_point_tie(df)
+
+            interval_minutes = (
+                df["Interval End"] - df["Interval Start"]
+            ).dt.total_seconds() / 60
+            assert (interval_minutes == 60).all()
+
+    @pytest.mark.parametrize(
+        "start, end",
+        [
+            (
+                pd.Timestamp("today").normalize() - pd.Timedelta(days=3),
+                pd.Timestamp("today").normalize() - pd.Timedelta(days=1),
+            ),
+        ],
+    )
+    def test_get_lmp_scheduling_point_tie_day_ahead_hourly_min_date_range(
+        self,
+        start,
+        end,
+    ):
+        with caiso_vcr.use_cassette(
+            f"test_get_lmp_scheduling_point_tie_day_ahead_hourly_date_range_{start.strftime('%Y-%m-%d')}_{end.strftime('%Y-%m-%d')}.yaml",
+        ):
+            df = self.iso.get_lmp_scheduling_point_tie_day_ahead_hourly(
+                start,
+                end=end,
+            )
+            self._check_lmp_scheduling_point_tie(df)
+
+            assert df["Interval Start"].min() >= self.local_start_of_day(start)
+
+    @pytest.mark.parametrize(
+        "start, end",
+        [
+            (
+                pd.Timestamp("today").normalize() - pd.Timedelta(days=3),
+                pd.Timestamp("today").normalize() - pd.Timedelta(days=1),
+            ),
+        ],
+    )
+    def test_get_lmp_scheduling_point_tie_real_time_5_min_date_range(
+        self,
+        start,
+        end,
+    ):
+        with caiso_vcr.use_cassette(
+            f"test_get_lmp_scheduling_point_tie_real_time_5_min_date_range_{start.strftime('%Y-%m-%d')}_{end.strftime('%Y-%m-%d')}.yaml",
+        ):
+            df = self.iso.get_lmp_scheduling_point_tie_real_time_5_min(
+                start,
+                end=end,
+            )
+            self._check_lmp_scheduling_point_tie(df)
+
+            assert df["Interval Start"].min() >= self.local_start_of_day(start)
+
+    @pytest.mark.parametrize(
+        "start, end",
+        [
+            (
+                pd.Timestamp("today").normalize() - pd.Timedelta(days=3),
+                pd.Timestamp("today").normalize() - pd.Timedelta(days=1),
+            ),
+        ],
+    )
+    def test_get_lmp_scheduling_point_tie_real_time_15_min_date_range(
+        self,
+        start,
+        end,
+    ):
+        with caiso_vcr.use_cassette(
+            f"test_get_lmp_scheduling_point_tie_real_time_15_min_date_range_{start.strftime('%Y-%m-%d')}_{end.strftime('%Y-%m-%d')}.yaml",
+        ):
+            df = self.iso.get_lmp_scheduling_point_tie_real_time_15_min(
+                start,
+                end=end,
+            )
+            self._check_lmp_scheduling_point_tie(df)
+
+            assert df["Interval Start"].min() >= self.local_start_of_day(start)


Reviews:
user: login: kmax12
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T03:07:47Z
user: login: kmax12
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T04:02:01Z
user: login: Kladar
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T15:09:38Z
user: login: Kladar
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T15:16:52Z
user: login: Kladar
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T15:17:48Z
user: login: WillKoehrsen
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T19:55:27Z
user: login: Kladar
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T21:40:43Z
user: login: WillKoehrsen
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T23:50:31Z
user: login: Kladar
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T00:09:40Z
user: login: WillKoehrsen
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T18:02:14Z
user: login: Kladar
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-13T18:17:09Z
user: login: WillKoehrsen
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T19:48:49Z
user: login: WillKoehrsen
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T19:49:29Z
user: login: WillKoehrsen
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-13T19:49:37Z

Review comments:
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
path: gridstatus/caiso.py
user: login: kmax12
body: when I look at this data, it seems like `Node Tie` is what we typically call location since it has only one value per interval. `Node` and `Tie` both have multiple values per interval.

edit: ignore this comment. i see what you did downstream with subseries index
created_at: 2025-03-12T02:59:39Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "GROUP": "Group",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Group",
+                "Market",
+                "POS",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
+            columns={
+                "MCE": "Energy",
+                "MCC": "Congestion",
+                "MCL": "Loss",
+                "MGHG": "GHG",
+            },
+        )
+
+        df["Node Tie"] = df["Location"] + " " + df["Tie"]
+        return df[
+            [
+                "Interval Start",
+                "Interval End",
+                "Market",
+                "Location",
+                "Node Tie",
+                "POS",
+                "Tie",
+                "Group",
path: gridstatus/caiso.py
user: login: kmax12
body: we don't need to include `group`. I think that is just a number that corresponds to "Node Tie"
created_at: 2025-03-12T03:02:15Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "GROUP": "Group",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Group",
+                "Market",
+                "POS",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
+            columns={
+                "MCE": "Energy",
+                "MCC": "Congestion",
+                "MCL": "Loss",
+                "MGHG": "GHG",
+            },
+        )
+
+        df["Node Tie"] = df["Location"] + " " + df["Tie"]
+        return df[
+            [
+                "Interval Start",
+                "Interval End",
+                "Market",
+                "Location",
+                "Node Tie",
+                "POS",
+                "Tie",
+                "Group",
+                "GRP_TYPE",
path: gridstatus/caiso.py
user: login: kmax12
body: there might be some valuable info in `GRP_TYPE`, but not we drop it for other LMP datasets.

unique values are `['ALL', 'ALL_APNODES']`
created_at: 2025-03-12T03:03:10Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
path: gridstatus/caiso.py
user: login: kmax12
body: I believe we need a `support_date_range` decorator on all these methods

edit: nevermind i see `get_oasis_dataset` is decorated with it
created_at: 2025-03-12T03:04:55Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "GROUP": "Group",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Group",
+                "Market",
+                "POS",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
+            columns={
+                "MCE": "Energy",
+                "MCC": "Congestion",
+                "MCL": "Loss",
+                "MGHG": "GHG",
+            },
+        )
+
+        df["Node Tie"] = df["Location"] + " " + df["Tie"]
+        return df[
+            [
+                "Interval Start",
+                "Interval End",
+                "Market",
+                "Location",
+                "Node Tie",
+                "POS",
+                "Tie",
+                "Group",
path: gridstatus/caiso.py
user: login: kmax12
body: same applies to `POS` and `GRP_TYPE`. let's remove POS
created_at: 2025-03-12T04:02:01Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "GROUP": "Group",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Group",
+                "Market",
+                "POS",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
+            columns={
+                "MCE": "Energy",
+                "MCC": "Congestion",
+                "MCL": "Loss",
+                "MGHG": "GHG",
+            },
+        )
+
+        df["Node Tie"] = df["Location"] + " " + df["Tie"]
+        return df[
+            [
+                "Interval Start",
+                "Interval End",
+                "Market",
+                "Location",
+                "Node Tie",
+                "POS",
+                "Tie",
+                "Group",
+                "GRP_TYPE",
path: gridstatus/caiso.py
user: login: Kladar
body: should I drop `GRP_TYPE`?
created_at: 2025-03-12T15:09:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
path: gridstatus/caiso.py
user: login: Kladar
body: You're right though in that I needed to add the `meta` field for frequency to the `OASIS_DATASET_CONFIG` to use that `get_oasis_dataset` decorator. 5 and 15 min are hour_start, hourly is day_start
created_at: 2025-03-12T15:16:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2247,3 +2286,118 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "GROUP": "Group",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Group",
+                "Market",
+                "POS",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
+            columns={
+                "MCE": "Energy",
+                "MCC": "Congestion",
+                "MCL": "Loss",
+                "MGHG": "GHG",
+            },
+        )
+
+        df["Node Tie"] = df["Location"] + " " + df["Tie"]
+        return df[
+            [
+                "Interval Start",
+                "Interval End",
+                "Market",
+                "Location",
+                "Node Tie",
+                "POS",
+                "Tie",
+                "Group",
path: gridstatus/caiso.py
user: login: Kladar
body: Removed `POS` and `group`. lmk in comment below what we should do with `GRP_TYPE`.
created_at: 2025-03-12T15:17:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2247,3 +2295,113 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Market",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
path: gridstatus/caiso.py
user: login: WillKoehrsen
body: Should there be an LMP column in these datasets?
created_at: 2025-03-12T19:55:26Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2295,113 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_combination_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_combination_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_hourly",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def _handle_lmp_scheduling_point_tie_combination(
+        self,
+        df: pd.DataFrame,
+    ) -> pd.DataFrame:
+        df = df.rename(
+            columns={
+                "NODE": "Location",
+                "TIE": "Tie",
+                "MARKET_RUN_ID": "Market",
+            },
+        )
+
+        df = df.pivot_table(
+            index=[
+                "Interval Start",
+                "Interval End",
+                "Location",
+                "Tie",
+                "Market",
+                "GRP_TYPE",
+            ],
+            columns="LMP_TYPE",
+            values="PRC",
+            aggfunc="first",
+        ).reset_index()
+
+        df.columns.name = None
+        df = df.rename(
path: gridstatus/caiso.py
user: login: Kladar
body: Ah yes, nice catch, it's there until the final column filtering (and CAISO calls it LMP so doesn't need renaming)
created_at: 2025-03-12T21:40:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2247,3 +2295,112 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
path: gridstatus/caiso.py
user: login: WillKoehrsen
body: We don't necessarily need to address this, but calling these functions with "latest" gives an error: `AttributeError: 'str' object has no attribute 'tz_convert'`.
created_at: 2025-03-12T23:50:31Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2295,112 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
path: gridstatus/caiso.py
user: login: Kladar
body: mm yeah, I think it's worth adding since it's pretty standard. Added it as `now` for real time. seems to be working pretty well and accurate to what is published.

For day ahead, it tries "tomorrow", and since it is likely published sometime in the morning for the following day (what I ran into), if that fails then do "today".
created_at: 2025-03-13T00:09:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2247,3 +2295,134 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_5_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_real_time_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_15_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_day_ahead_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            try:
+                df = self.get_lmp_scheduling_point_tie_day_ahead_hourly(
+                    pd.Timestamp.now(tz=self.default_timezone).normalize()
+                    + pd.Timedelta(days=1),
+                )
+            except ValueError:
path: gridstatus/caiso.py
user: login: WillKoehrsen
body: I think the error in this case is a `KeyError`. 

```python
CAISO().get_lmp_scheduling_point_tie_day_ahead_hourly('2025-03-14')

> KeyError: 'PRC'
```
created_at: 2025-03-13T18:02:14Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2295,134 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_5_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_real_time_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_15_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_day_ahead_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            try:
+                df = self.get_lmp_scheduling_point_tie_day_ahead_hourly(
+                    pd.Timestamp.now(tz=self.default_timezone).normalize()
+                    + pd.Timedelta(days=1),
+                )
+            except ValueError:
path: gridstatus/caiso.py
user: login: Kladar
body: ah yes, updated. sorry for the paper cuts on this one
created_at: 2025-03-13T18:17:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2247,3 +2295,112 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
path: gridstatus/caiso.py
user: login: WillKoehrsen
body: Works well, thanks.
created_at: 2025-03-13T19:48:49Z
author_association: COLLABORATOR
diff_hunk: @@ -2247,3 +2295,134 @@ def get_as_procurement(
         df.columns.name = None
 
         return df
+
+    def get_lmp_scheduling_point_tie_real_time_5_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        """Get LMP scheduling point tie combination 5-min data from CAISO.
+
+        Args:
+            date (str | pd.Timestamp): date to return data
+            end (str | pd.Timestamp | None, optional): last date of range to return data.
+                If None, returns only date. Defaults to None.
+            verbose (bool, optional): print out url being fetched. Defaults to False.
+
+        Returns:
+            pandas.DataFrame: A DataFrame of LMP scheduling point tie combination 5-min data
+        """
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_5_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_5_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_real_time_15_min(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            return self.get_lmp_scheduling_point_tie_real_time_15_min(
+                pd.Timestamp.now(tz=self.default_timezone),
+            )
+
+        df = self.get_oasis_dataset(
+            dataset="lmp_scheduling_point_tie_combination_15_min",
+            date=date,
+            end=end,
+            verbose=verbose,
+            raw_data=False,
+        )
+        return self._handle_lmp_scheduling_point_tie_combination(df)
+
+    def get_lmp_scheduling_point_tie_day_ahead_hourly(
+        self,
+        date: str | pd.Timestamp,
+        end: str | pd.Timestamp | None = None,
+        verbose: bool = False,
+    ) -> pd.DataFrame:
+        if date == "latest":
+            try:
+                df = self.get_lmp_scheduling_point_tie_day_ahead_hourly(
+                    pd.Timestamp.now(tz=self.default_timezone).normalize()
+                    + pd.Timedelta(days=1),
+                )
+            except ValueError:
path: gridstatus/caiso.py
user: login: WillKoehrsen
body: No problem, thanks for working through it.
created_at: 2025-03-13T19:49:28Z
author_association: COLLABORATOR

PR comments:
user: login: WillKoehrsen
created_at: 2025-03-12T23:10:32Z
body: Now I'm getting a KeyError using the latest code.

```python

CAISO().get_lmp_scheduling_point_tie_day_ahead_hourly('2025-01-01')

> KeyError: "['Location'] not in index"

```
author_association: COLLABORATOR
user: login: Kladar
created_at: 2025-03-12T23:24:22Z
body: > Now I'm getting a KeyError using the latest code.
> 
> ```python
> CAISO().get_lmp_scheduling_point_tie_day_ahead_hourly('2025-01-01')
> 
> > KeyError: "['Location'] not in index"
> ```

Oop, yep, columns in the helper function (and the tests) needed to be updated. Updated and running them locally now...

Update: passing locally
author_association: CONTRIBUTOR
user: login: WillKoehrsen
created_at: 2025-03-12T23:24:28Z
body: > Now I'm getting a KeyError using the latest code.

Fixed with the latest code!
author_association: COLLABORATOR