Compare commits

..

No commits in common. "3526d5d5642a808d99093fd38bef548f4e95bbf8" and "f26a42e76f588d0ba0f2de8f72fbcd98d0c503ed" have entirely different histories.

1 changed files with 42 additions and 42 deletions

View File

@ -11,15 +11,6 @@ from piker.brokers.deribit.api import (
maybe_open_oi_feed, maybe_open_oi_feed,
) )
def check_if_complete(
oi: dict[str, dict[str, Decimal | None]]
) -> bool:
return all(
oi[strike]['C'] is not None
and
oi[strike]['P'] is not None for strike in oi
)
async def max_pain_daemon( async def max_pain_daemon(
) -> None: ) -> None:
@ -27,17 +18,19 @@ async def max_pain_daemon(
instruments: list[Symbol] = [] instruments: list[Symbol] = []
oi_by_strikes: dict[str, dict[str, Decimal]] oi_by_strikes: dict[str, dict[str, Decimal]]
def update_oi_by_strikes(msg: tuple): def check_if_complete(
nonlocal oi_by_strikes oi: dict[str, dict[str, Decimal | None]],
if 'oi' == msg[0]:
strike_price = msg[1]['strike_price'] ) -> bool:
option_type = msg[1]['option_type'] for strike in oi:
open_interest = msg[1]['open_interest'] if (
oi_by_strikes.setdefault( oi[strike]['C'] == None
strike_price, {} or
).update( oi[strike]['P'] == None
{option_type: open_interest} ):
) return False
return True
def get_max_pain( def get_max_pain(
oi_by_strikes: dict[str, dict[str, Decimal]] oi_by_strikes: dict[str, dict[str, Decimal]]
@ -57,15 +50,17 @@ async def max_pain_daemon(
# an amount greater than zero. # an amount greater than zero.
total_intrinsic_value: Decimal = Decimal('Infinity') total_intrinsic_value: Decimal = Decimal('Infinity')
max_pain: Decimal = Decimal(0) max_pain: Decimal = Decimal(0)
intrinsic_values: dict[str, dict[str, Decimal]] = {}
closes: list[str] = sorted(oi_by_strikes.keys())
for strike in oi_by_strikes:
s: Decimal = Decimal(f'{strike}')
call_cash: Decimal = Decimal(0) call_cash: Decimal = Decimal(0)
put_cash: Decimal = Decimal(0) put_cash: Decimal = Decimal(0)
intrinsic_values: dict[str, dict[str, Decimal]] = {} for close in closes:
closes: list = sorted(Decimal(close) for close in oi_by_strikes) c: Decimal = Decimal(f'{close}')
call_cash += max(0, (s - c) * oi_by_strikes[f'{close}']['C'])
for strike, oi in oi_by_strikes.items(): put_cash += max(0, (c - s) * oi_by_strikes[f'{close}']['P'])
s = Decimal(strike)
call_cash = sum(max(0, (s - c) * oi_by_strikes[str(c)]['C']) for c in closes)
put_cash = sum(max(0, (c - s) * oi_by_strikes[str(c)]['P']) for c in closes)
intrinsic_values[strike] = { intrinsic_values[strike] = {
'C': call_cash, 'C': call_cash,
@ -73,9 +68,10 @@ async def max_pain_daemon(
'total': call_cash + put_cash, 'total': call_cash + put_cash,
} }
if intrinsic_values[strike]['total'] < total_intrinsic_value: for strike in intrinsic_values:
total_intrinsic_value = intrinsic_values[strike]['total'] if intrinsic_values[f'{strike}']['total'] < total_intrinsic_value:
max_pain = s total_intrinsic_value = intrinsic_values[f'{strike}']['total']
max_pain = strike\
return { return {
'timestamp': timestamp, 'timestamp': timestamp,
@ -84,6 +80,7 @@ async def max_pain_daemon(
'max_pain': max_pain, 'max_pain': max_pain,
} }
async with get_client( async with get_client(
) as client: ) as client:
instruments = await client.get_instruments( instruments = await client.get_instruments(
@ -95,11 +92,14 @@ async def max_pain_daemon(
instruments, instruments,
) as oi_feed: ) as oi_feed:
async for msg in oi_feed: async for msg in oi_feed:
update_oi_by_strikes(msg)
if check_if_complete(oi_by_strikes):
if 'oi' == msg[0]: if 'oi' == msg[0]:
timestamp = msg[1]['timestamp'] timestamp = msg[1]['timestamp']
strike_price = msg[1]['strike_price']
option_type = msg[1]['option_type']
open_interest = msg[1]['open_interest']
oi_by_strikes[f'{strike_price}'][f'{option_type}'] = open_interest
if check_if_complete(oi_by_strikes):
max_pain = get_max_pain(oi_by_strikes) max_pain = get_max_pain(oi_by_strikes)
print('-----------------------------------------------') print('-----------------------------------------------')
print(f'timestamp: {datetime.fromtimestamp(max_pain['timestamp'])}') print(f'timestamp: {datetime.fromtimestamp(max_pain['timestamp'])}')