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, | ||||
|     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( | ||||
|         oi: dict[str, dict[str, Decimal | None]] | ||||
|  | @ -87,6 +92,65 @@ async def max_pain_daemon( | |||
| 
 | ||||
|         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): | ||||
|         nonlocal oi_by_strikes | ||||
|         if 'oi' == msg[0]: | ||||
|  | @ -127,6 +191,16 @@ async def max_pain_daemon( | |||
|     async with maybe_open_oi_feed( | ||||
|         instruments, | ||||
|     ) 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: | ||||
| 
 | ||||
|             update_oi_by_strikes(msg) | ||||
|  | @ -134,13 +208,21 @@ async def max_pain_daemon( | |||
|                 if 'oi' == msg[0]: | ||||
|                     timestamp = msg[1]['timestamp'] | ||||
|                     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(f'timestamp:             {datetime.fromtimestamp(max_pain['timestamp'])}') | ||||
|                     print(f'expiry_date:           {max_pain['expiry_date']}') | ||||
|                     print(f'max_pain:              {max_pain['max_pain']}') | ||||
|                     print(f'total intrinsic value: {max_pain['total_intrinsic_value']}') | ||||
|                     print(f'max_pain:              {max_pain['max_pain']:,.0f}') | ||||
|                     print(f'total intrinsic value: {max_pain['total_intrinsic_value']:,.0f}') | ||||
|                     print('-----------------------------------------------') | ||||
| 
 | ||||
|             # Process GUI events to keep the window responsive | ||||
|             app.processEvents() | ||||
| 
 | ||||
| 
 | ||||
| async def main(): | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue