Skip to content

Client

Python example

import requests
from dataclasses import dataclass
from datetime import datetime, timezone
from decimal import Decimal
from math import floor
from pprint import pp
from typing import List, Self

STRING_FORMATS = ("%Y-%m-%dT%H:%M", "%Y-%m-%d", "%Y-%m-%d %H:%M")


class Timestamp(int):
    @classmethod
    def from_datetime(cls, dt: datetime) -> Self:
        return cls(floor(dt.replace(tzinfo=timezone.utc).timestamp()))

    @classmethod
    def from_string(cls, s: str) -> Self:
        for string_format in STRING_FORMATS:
            try:
                dt = datetime.strptime(s, string_format)
            except ValueError:
                continue
            return cls.from_datetime(dt)
        raise ValueError("Invalid datetime format.")

    def __repr__(self):
        return f"{self.__class__.__name__}({int(self)})"


@dataclass
class Area:
    type: str
    t0: Timestamp
    a0: Decimal
    b0: Decimal
    a1: Decimal
    b1: Decimal
    added_at: Timestamp
    removed_at: Timestamp | None

    def top(self, ts: Timestamp) -> Decimal:
        if self.b0 > self.b1:
            return self.a0 * ts + self.b0
        else:
            return self.a1 * ts + self.b1

    def bottom(self, ts: Timestamp) -> Decimal:
        if self.b0 < self.b1:
            return self.a0 * ts + self.b0
        else:
            return self.a1 * ts + self.b1


class PaapiClient:
    def __init__(self, base_url: str):
        self._base_url = base_url

    def pairs(self) -> List[str]:
        response = requests.get(f"{self._base_url}/v1/pairs")
        response.raise_for_status()
        return [i["slug"] for i in response.json()["items"] if i["is_active"]]

    def areas(self, pair: str) -> List[Area]:
        response = requests.get(f"{self._base_url}/v1/pairs/{pair}/areas")
        response.raise_for_status()
        return [
            Area(
                type=i["type"],
                t0=Timestamp(i["t0"]),
                a0=Decimal(i["a0"]),
                b0=Decimal(i["b0"]),
                a1=Decimal(i["a1"]),
                b1=Decimal(i["b1"]),
                added_at=Timestamp(i["added_at"]),
                removed_at=(
                    Timestamp(i["removed_at"]) if i["removed_at"] is not None else None
                ),
            )
            for i in response.json()["items"]
        ]


def main():
    paapi = PaapiClient(base_url="https://paapi.io")
    pp(paapi.pairs()[:5])
    areas = paapi.areas("BTCUSDT")[:5]
    pp(areas)

    pp(areas[0].top(Timestamp.from_string("2023-12-01")))
    pp(areas[0].bottom(Timestamp.from_string("2023-12-01")))


if __name__ == "__main__":
    main()