# Realized P&L on the FIFO basis

Realized P&L is computed by keeping track of each buy and sell in the chronological order and updating the total using the oldest matching execution from the opposite side (FIFO). We'll use the following sequence of trades for illustration.

```ipython3
import onetick.py as otp

trades = otp.Ticks(
    SIDE=['B', 'B', 'B', 'S', 'S', 'S', 'S', 'S', 'B', 'B', 'S'],
    PRICE=[1.0, 2.0, 3.0, 2.5, 4.0, 5.0, 6.0, 7.0, 3.0, 4.0, 1.0],
    SIZE=[700, 20, 570, 600, 100, 100, 100, 100, 150, 10, 100],
)

otp.run(trades)
```

```myst-ansi
                      Time SIDE  PRICE  SIZE
0  2024-02-01 00:00:00.000    B    1.0   700
1  2024-02-01 00:00:00.001    B    2.0    20
2  2024-02-01 00:00:00.002    B    3.0   570
3  2024-02-01 00:00:00.003    S    2.5   600
4  2024-02-01 00:00:00.004    S    4.0   100
5  2024-02-01 00:00:00.005    S    5.0   100
6  2024-02-01 00:00:00.006    S    6.0   100
7  2024-02-01 00:00:00.007    S    7.0   100
8  2024-02-01 00:00:00.008    B    3.0   150
9  2024-02-01 00:00:00.009    B    4.0    10
10 2024-02-01 00:00:00.010    S    1.0   100
```

## (New way) Using `pnl_realized` OneTick method

```ipython3
pnl_r = trades.pnl_realized(buy_sell_flag_field='SIDE', output_field_name='PROFIT')
pnl_r = pnl_r.agg({'TOTAL_PROFIT': otp.agg.sum('PROFIT')}, running=True, all_fields=True)
otp.run(pnl_r)
```

```myst-ansi
                      Time SIDE  PRICE  SIZE  PROFIT  TOTAL_PROFIT
0  2024-02-01 00:00:00.000    B    1.0   700     0.0           0.0
1  2024-02-01 00:00:00.001    B    2.0    20     0.0           0.0
2  2024-02-01 00:00:00.002    B    3.0   570     0.0           0.0
3  2024-02-01 00:00:00.003    S    2.5   600   900.0         900.0
4  2024-02-01 00:00:00.004    S    4.0   100   300.0        1200.0
5  2024-02-01 00:00:00.005    S    5.0   100   220.0        1420.0
6  2024-02-01 00:00:00.006    S    6.0   100   300.0        1720.0
7  2024-02-01 00:00:00.007    S    7.0   100   400.0        2120.0
8  2024-02-01 00:00:00.008    B    3.0   150     0.0        2120.0
9  2024-02-01 00:00:00.009    B    4.0    10     0.0        2120.0
10 2024-02-01 00:00:00.010    S    1.0   100  -200.0        1920.0
```

## (Old way) Manual implementation

We define the deque variables to keep the buy and sell trades as they arrive. Note that the variables are associated with the trades time series.

```ipython3
trades.state_vars['BUY_DEQUE'] = otp.state.tick_deque()
trades.state_vars['SELL_DEQUE'] = otp.state.tick_deque()
```

As every trade arrives, we apply the following function, which updates the deques and computes the realized profit from the trade.

```ipython3
def fifo_computation_of_realized_profit(tick):
    buy_tick = otp.tick_deque_tick()
    sell_tick = otp.tick_deque_tick()
    tick['PROFIT'] = 0.0

    if tick['SIDE'] == 'B':
        tick.state_vars['BUY_DEQUE'].push_back(tick)
    else:
        tick.state_vars['SELL_DEQUE'].push_back(tick)

    while tick.state_vars['BUY_DEQUE'].get_size() > 0 and tick.state_vars['SELL_DEQUE'].get_size() > 0:
        tick.state_vars['BUY_DEQUE'].get_tick(0, buy_tick)
        tick.state_vars['SELL_DEQUE'].get_tick(0, sell_tick)
        if buy_tick['SIZE'] > sell_tick['SIZE']:
            tick['PROFIT'] += sell_tick['SIZE'] * (sell_tick['PRICE'] - buy_tick['PRICE'])
            buy_tick['SIZE'] -= sell_tick['SIZE']
            sell_tick['SIZE'] = 0
        else:
            tick['PROFIT'] += buy_tick['SIZE'] * (sell_tick['PRICE'] - buy_tick['PRICE'])
            sell_tick['SIZE'] -= buy_tick['SIZE']
            buy_tick['SIZE'] = 0

        if buy_tick['SIZE'] == 0:
            tick.state_vars['BUY_DEQUE'].pop_front()
        if sell_tick['SIZE'] == 0:
            tick.state_vars['SELL_DEQUE'].pop_front()
```

Total realized profit can now be calculated by applying the function to every trade.

```ipython3
trades = trades.script(fifo_computation_of_realized_profit)
trades = trades.agg({'TOTAL_PROFIT': otp.agg.sum('PROFIT')}, running=True, all_fields=True)
otp.run(trades)
```

```myst-ansi
                      Time SIDE  PRICE  SIZE  PROFIT  TOTAL_PROFIT
0  2024-02-01 00:00:00.000    B    1.0   700     0.0           0.0
1  2024-02-01 00:00:00.001    B    2.0    20     0.0           0.0
2  2024-02-01 00:00:00.002    B    3.0   570     0.0           0.0
3  2024-02-01 00:00:00.003    S    2.5   600   900.0         900.0
4  2024-02-01 00:00:00.004    S    4.0   100   300.0        1200.0
5  2024-02-01 00:00:00.005    S    5.0   100   220.0        1420.0
6  2024-02-01 00:00:00.006    S    6.0   100   300.0        1720.0
7  2024-02-01 00:00:00.007    S    7.0   100   400.0        2120.0
8  2024-02-01 00:00:00.008    B    3.0   150     0.0        2120.0
9  2024-02-01 00:00:00.009    B    4.0    10     0.0        2120.0
10 2024-02-01 00:00:00.010    S    1.0   100  -200.0        1920.0
```
