Add Plot
Here is the `plot_graph()` that is in char of the bars, scatter and vertical line plot items. Also all the necessary code for the graph to be shown.
							parent
							
								
									e8c5f7a531
								
							
						
					
					
						commit
						490aaa3874
					
				|  | @ -10,6 +10,11 @@ from piker.brokers.deribit.api import ( | ||||||
|     get_client, |     get_client, | ||||||
|     maybe_open_oi_feed, |     maybe_open_oi_feed, | ||||||
| ) | ) | ||||||
|  | import sys | ||||||
|  | import pyqtgraph as pg | ||||||
|  | from PyQt6 import QtCore | ||||||
|  | from pyqtgraph import ScatterPlotItem, InfiniteLine | ||||||
|  | from PyQt6.QtWidgets import QApplication | ||||||
| 
 | 
 | ||||||
| def check_if_complete( | def check_if_complete( | ||||||
|         oi: dict[str, dict[str, Decimal | None]] |         oi: dict[str, dict[str, Decimal | None]] | ||||||
|  | @ -87,6 +92,65 @@ async def max_pain_daemon( | ||||||
| 
 | 
 | ||||||
|         return total_intrinsic_value, max_pain |         return total_intrinsic_value, max_pain | ||||||
| 
 | 
 | ||||||
|  |     def plot_graph( | ||||||
|  |         oi_by_strikes: dict[str, dict[str, Decimal]], | ||||||
|  |         plot, | ||||||
|  |     ): | ||||||
|  |         """Update the bar graph with new open interest data.""" | ||||||
|  |         plot.clear() | ||||||
|  | 
 | ||||||
|  |         intrinsic_values = get_total_intrinsic_values(oi_by_strikes) | ||||||
|  | 
 | ||||||
|  |         for strike_str in sorted(oi_by_strikes, key=lambda x: int(x)): | ||||||
|  |             strike = int(strike_str) | ||||||
|  |             calls_val = float(oi_by_strikes[strike_str]['C']) | ||||||
|  |             puts_val  = float(oi_by_strikes[strike_str]['P']) | ||||||
|  | 
 | ||||||
|  |             bar_c = pg.BarGraphItem( | ||||||
|  |                 x=[strike - 100], | ||||||
|  |                 height=[calls_val], | ||||||
|  |                 width=200, | ||||||
|  |                 pen='w', | ||||||
|  |                 brush=(0, 0, 255, 150) | ||||||
|  |             ) | ||||||
|  |             plot.addItem(bar_c) | ||||||
|  | 
 | ||||||
|  |             bar_p = pg.BarGraphItem( | ||||||
|  |                 x=[strike + 100], | ||||||
|  |                 height=[puts_val], | ||||||
|  |                 width=200, | ||||||
|  |                 pen='w', | ||||||
|  |                 brush=(255, 0, 0, 150) | ||||||
|  |             ) | ||||||
|  |             plot.addItem(bar_p) | ||||||
|  | 
 | ||||||
|  |             total_val = float(intrinsic_values[strike_str]['total']) / 100000 | ||||||
|  | 
 | ||||||
|  |             scatter_iv = ScatterPlotItem( | ||||||
|  |                 x=[strike], | ||||||
|  |                 y=[total_val], | ||||||
|  |                 pen=pg.mkPen(color=(0, 255, 0), width=2), | ||||||
|  |                 brush=pg.mkBrush(0, 255, 0, 150), | ||||||
|  |                 size=3, | ||||||
|  |                 symbol='o' | ||||||
|  |             ) | ||||||
|  |             plot.addItem(scatter_iv) | ||||||
|  | 
 | ||||||
|  |         _, max_pain = get_intrinsic_value_and_max_pain(intrinsic_values) | ||||||
|  | 
 | ||||||
|  |         vertical_line = InfiniteLine( | ||||||
|  |             pos=max_pain, | ||||||
|  |             angle=90, | ||||||
|  |             pen=pg.mkPen(color='yellow', width=1, style=QtCore.Qt.PenStyle.DotLine), | ||||||
|  |             label=f'Max pain: {max_pain:,.0f}', | ||||||
|  |             labelOpts={ | ||||||
|  |                 'position': 0.85, | ||||||
|  |                 'color': 'yellow', | ||||||
|  |                 'movable': True | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|  |         plot.addItem(vertical_line) | ||||||
|  | 
 | ||||||
|     def update_oi_by_strikes(msg: tuple): |     def update_oi_by_strikes(msg: tuple): | ||||||
|         nonlocal oi_by_strikes |         nonlocal oi_by_strikes | ||||||
|         if 'oi' == msg[0]: |         if 'oi' == msg[0]: | ||||||
|  | @ -127,6 +191,16 @@ async def max_pain_daemon( | ||||||
|     async with maybe_open_oi_feed( |     async with maybe_open_oi_feed( | ||||||
|         instruments, |         instruments, | ||||||
|     ) as oi_feed: |     ) as oi_feed: | ||||||
|  |         # Initialize QApplication | ||||||
|  |         app = QApplication(sys.argv) | ||||||
|  | 
 | ||||||
|  |         win = pg.GraphicsLayoutWidget(show=True) | ||||||
|  |         win.setWindowTitle('Calls (blue) vs Puts (red)') | ||||||
|  | 
 | ||||||
|  |         plot = win.addPlot(title='OI by Strikes') | ||||||
|  |         plot.showGrid(x=True, y=True) | ||||||
|  |         print('Plot initialized...') | ||||||
|  | 
 | ||||||
|         async for msg in oi_feed: |         async for msg in oi_feed: | ||||||
| 
 | 
 | ||||||
|             update_oi_by_strikes(msg) |             update_oi_by_strikes(msg) | ||||||
|  | @ -134,13 +208,21 @@ async def max_pain_daemon( | ||||||
|                 if 'oi' == msg[0]: |                 if 'oi' == msg[0]: | ||||||
|                     timestamp = msg[1]['timestamp'] |                     timestamp = msg[1]['timestamp'] | ||||||
|                     max_pain = get_max_pain(oi_by_strikes) |                     max_pain = get_max_pain(oi_by_strikes) | ||||||
|  |                     intrinsic_values = get_total_intrinsic_values(oi_by_strikes) | ||||||
|  | 
 | ||||||
|  |                     # graph here | ||||||
|  |                     plot_graph(oi_by_strikes, plot) | ||||||
|  | 
 | ||||||
|                     print('-----------------------------------------------') |                     print('-----------------------------------------------') | ||||||
|                     print(f'timestamp:             {datetime.fromtimestamp(max_pain['timestamp'])}') |                     print(f'timestamp:             {datetime.fromtimestamp(max_pain['timestamp'])}') | ||||||
|                     print(f'expiry_date:           {max_pain['expiry_date']}') |                     print(f'expiry_date:           {max_pain['expiry_date']}') | ||||||
|                     print(f'max_pain:              {max_pain['max_pain']}') |                     print(f'max_pain:              {max_pain['max_pain']:,.0f}') | ||||||
|                     print(f'total intrinsic value: {max_pain['total_intrinsic_value']}') |                     print(f'total intrinsic value: {max_pain['total_intrinsic_value']:,.0f}') | ||||||
|                     print('-----------------------------------------------') |                     print('-----------------------------------------------') | ||||||
| 
 | 
 | ||||||
|  |             # Process GUI events to keep the window responsive | ||||||
|  |             app.processEvents() | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| async def main(): | async def main(): | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue