Skip to content

Spreads and Intraday Analysis

fiat_comparison(currencies, root=None)

Build a comparison table across multiple fiat currencies (daily metrics).

Parameters:

Name Type Description Default
currencies sequence of str

List of fiat codes to include (e.g. ['ARS', 'BOB', 'EUR']).

required
root path - like

Root of processed data.

None

Returns:

Type Description
DataFrame

One row per date per currency, with: - date - currency - avg_buy_price - avg_sell_price - spread_abs - spread_pct

Source code in src\p2p_analytics\spreads.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def fiat_comparison(
    currencies: Sequence[str],
    root: str | None = None,
) -> pd.DataFrame:
    """
    Build a comparison table across multiple fiat currencies (daily metrics).

    Parameters
    ----------
    currencies : sequence of str
        List of fiat codes to include (e.g. ['ARS', 'BOB', 'EUR']).
    root : path-like, optional
        Root of processed data.

    Returns
    -------
    pandas.DataFrame
        One row per date per currency, with:
        - date
        - currency
        - avg_buy_price
        - avg_sell_price
        - spread_abs
        - spread_pct
    """
    df = load_binance_master(root=root)
    df_sub = df[df["currency"].isin(currencies)].copy()

    grouped = (
        df_sub
        .groupby(["date", "currency", "side"], as_index=False)["price"]
        .mean()
        .pivot_table(
            index=["date", "currency"],
            columns="side",
            values="price"
        )
        .rename(columns={"BUY": "avg_buy_price", "SELL": "avg_sell_price"})
        .reset_index()
    )

    grouped["spread_abs"] = (grouped["avg_sell_price"] - grouped["avg_buy_price"]).abs()
    mid = (grouped["avg_sell_price"] + grouped["avg_buy_price"]) / 2
    grouped["spread_pct"] = grouped["spread_abs"] / mid * 100

    return grouped

intraday_profile(currency, start=None, end=None, root=None)

Intraday price profile for a given currency (average over all days).

Parameters:

Name Type Description Default
currency str

Fiat currency code.

required
start str or Timestamp

Start date (inclusive).

None
end str or Timestamp

End date (inclusive).

None
root path - like

Root of processed data.

None

Returns:

Type Description
DataFrame

One row per hour (0–23) with: - hour - currency - mean_buy_price - mean_sell_price

Source code in src\p2p_analytics\spreads.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def intraday_profile(
    currency: str,
    start: str | pd.Timestamp | None = None,
    end: str | pd.Timestamp | None = None,
    root: str | None = None,
) -> pd.DataFrame:
    """
    Intraday price profile for a given currency (average over all days).

    Parameters
    ----------
    currency : str
        Fiat currency code.
    start : str or pandas.Timestamp, optional
        Start date (inclusive).
    end : str or pandas.Timestamp, optional
        End date (inclusive).
    root : path-like, optional
        Root of processed data.

    Returns
    -------
    pandas.DataFrame
        One row per hour (0–23) with:
        - hour
        - currency
        - mean_buy_price
        - mean_sell_price
    """
    df = load_binance_currency(currency, root=root)
    df = _ensure_datetime(df, "scrape_datetime")

    df["date"] = pd.to_datetime(df["date"]).dt.date
    df["hour"] = df["scrape_datetime"].dt.hour

    if start is not None:
        df = df[df["date"] >= pd.to_datetime(start).date()]

    if end is not None:
        df = df[df["date"] <= pd.to_datetime(end).date()]

    grouped = (
        df
        .groupby(["hour", "side"], as_index=False)["price"]
        .mean()
        .pivot_table(
            index="hour",
            columns="side",
            values="price"
        )
        .rename(columns={"BUY": "mean_buy_price", "SELL": "mean_sell_price"})
        .reset_index()
    )

    grouped["currency"] = currency
    return grouped

p2p_spread(currency, by='day', root=None)

Compute BUY–SELL spread for a given currency using the Phase 1 parquet files.

Parameters:

Name Type Description Default
currency str

Fiat code, e.g. 'ARS', 'BOB', 'EUR'.

required
by (day, hour)

Aggregation level for spreads.

'day'
root path - like

Root of processed data. If None, infer from project layout.

None

Returns:

Type Description
DataFrame

Columns include: - date (and hour if by='hour') - currency - avg_buy_price - avg_sell_price - spread_abs - spread_pct

Source code in src\p2p_analytics\spreads.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
def p2p_spread(
    currency: str,
    by: ByType = "day",
    root: str | None = None,
) -> pd.DataFrame:
    """
    Compute BUY–SELL spread for a given currency using the Phase 1 parquet files.

    Parameters
    ----------
    currency : str
        Fiat code, e.g. 'ARS', 'BOB', 'EUR'.
    by : {'day', 'hour'}, default 'day'
        Aggregation level for spreads.
    root : path-like, optional
        Root of processed data. If None, infer from project layout.

    Returns
    -------
    pandas.DataFrame
        Columns include:
        - date (and hour if by='hour')
        - currency
        - avg_buy_price
        - avg_sell_price
        - spread_abs
        - spread_pct
    """
    df = load_binance_currency(currency, root=root)
    return _p2p_spread_core(df, currency, by=by)