Advertisement
srcveiga

Untitled

Mar 21st, 2023
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.80 KB | None | 0 0
  1. import pandas as pd
  2. import plotly.express as px
  3. import plotly.graph_objects as go
  4. from plotly.subplots import make_subplots
  5. import time
  6. import datetime
  7. import dash
  8. from dash import dcc
  9. from dash import html
  10. from dash.dependencies import Input, Output, State
  11. import dash_bootstrap_components as dbc
  12. from PyQt5 import QtCore, QtWidgets, uic
  13. from PyQt5.QtWebEngineWidgets import QWebEngineView
  14. from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout,QSpacerItem, QSizePolicy,QSizeGrip, QLabel
  15. from PyQt5.QtCore import QUrl, Qt, QPoint, QObject, QEvent, QRect, pyqtSignal
  16. from PyQt5.QtGui import QCursor
  17. import sys
  18. import threading
  19. import math
  20. import os
  21.  
  22. def string_to_number(df, column):
  23. if isinstance(df.iloc[0, df.columns.get_loc(column)], str):
  24. df[column] = df[column].str.replace(',','')
  25. df[column] = df[column].astype(float)
  26. return df
  27.  
  28. def read_data(filename, stock_code, usecols):
  29. df = pd.read_csv(filename, header=None, usecols=usecols,
  30. names=['time', stock_code, 'price change', 'volume'],
  31. index_col= 'time', parse_dates=['time'])
  32. index_with_nan = df.index[df.isnull().any(axis=1)]
  33. df.drop(index_with_nan, axis=0, inplace=True)
  34. df = string_to_number(df, stock_code)
  35. df = string_to_number(df, 'volume')
  36. latest_info = df.iloc[-1, :]
  37. latest_price = str(round(latest_info.iloc[0], 2))
  38. latest_price_change = str(latest_info.iloc[1])
  39. dfvol = df['volume'].resample('1Min').mean()
  40. data = df[stock_code].resample('1Min').ohlc()
  41. data['time'] = data.index
  42. data['time'] = pd.to_datetime(data['time'], format='%Y-%m-%d %H:%M:%S')
  43. data['MA5'] = data['close'].rolling(5).mean()
  44. data['MA10'] = data['close'].rolling(10).mean()
  45. data['MA20'] = data['close'].rolling(20).mean()
  46. data['volume_diff'] = dfvol.diff()
  47. data[data['volume_diff'] < 0] = None
  48. index_with_nan = data.index[data.isnull().any(axis=1)]
  49. data.reset_index(drop=True, inplace=True)
  50. #print("data was added")
  51. return data, latest_price, latest_price_change, df['volume'][-1]
  52.  
  53. def run_dash():
  54. app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
  55. colors = {
  56. 'background': '#121416',
  57. 'text': 'white'
  58. }
  59. stock = ['BOIL', 'PYPL', 'INTC', 'AAPL', 'AMZN', 'MSFT', 'TSLA']
  60. filename = 'stock_data.csv'
  61. data, latest_price, latest_price_change, volume = read_data(filename, stock[0], [1, 2, 3, 4])
  62. d2, latest_price1, latest_price_change1, volume1 = read_data(filename, stock[1], [1, 5, 6, 7])
  63. d3, latest_price2, latest_price_change2, volume2 = read_data(filename, stock[2], [1, 8, 9, 10])
  64. d4, latest_price3, latest_price_change3, volume3 = read_data(filename, stock[3], [1, 11, 12, 13])
  65. d5, latest_price4, latest_price_change4, volume4 = read_data(filename, stock[4], [1, 14, 15, 16])
  66. d6, latest_price5, latest_price_change5, volume5 = read_data(filename, stock[5], [1, 17, 18, 19])
  67. d7, latest_price6, latest_price_change6, volume6 = read_data(filename, stock[6], [1, 20, 21, 22])
  68.  
  69.  
  70. app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[ html.H1( children='DashBoard v1.0', style={ 'textAlign': 'center', 'color': colors['text']
  71. }
  72. ),
  73.  
  74. html.Div(children='DashBoard v1.0: An application for your daily trade.', style={
  75. 'textAlign': 'center',
  76. 'backgroundColor': colors['background'],
  77. 'color': colors['text']
  78. }),
  79.  
  80. dbc.Row(style={
  81. 'textAlign': 'center',
  82. 'height': '100vh',
  83. 'backgroundColor': colors['background'],
  84. 'color': colors['text']}, children=[
  85.  
  86. dbc.Col( style={'content-align': 'center','padding-left': '20px' , 'padding-right': '50px','padding-top': '40px'}, children=[
  87.  
  88. dbc.Row([
  89. dbc.Col(id='stock_name',align='center', width={'size': 1},style={'font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '45px'}),
  90. dbc.Col(id='latest_price',align='center', width={'size': 2}, style={'color': 'white'}),
  91. dbc.Col(id='latest_price_change',align='center', width={'size': 2})
  92.  
  93. ] ),
  94.  
  95. dbc.Row([dbc.Col(
  96. dcc.Graph(id="candles"), align='center',
  97. ),],),
  98.  
  99. dbc.Row([
  100. dbc.Col('Volume',align='center', width={'size': 1},style={'font-weight': 'bold','fontSize': '16','width': '15%','background-color': '#FFBF00','color': 'black', 'margin-left': '45px', 'margin-right': '10px'}),
  101. dbc.Col(id='volume',align='center', width={'size': 1},style={'color': 'white'}),
  102. ] ),
  103.  
  104. dbc.Row([dbc.Col(
  105. dcc.Graph(id="volume_chart",config={'displayModeBar': False}), align='center',
  106. ),],),
  107.  
  108. dbc.Row([
  109. dbc.Col("Rsi",align='center', width={'size': 2},style={'font-weight': 'bold','fontSize': '16','width': '10%','background-color': '#FFBF00','color': 'black', 'margin-left': '45px', 'margin-right': '10px'}),
  110. dbc.Col(volume,align='center', width={'size': 2},style={'color': 'white'}),
  111. ] ),
  112.  
  113. dbc.Row([dbc.Col(
  114. dcc.Graph(id="Rsi",config={'displayModeBar': False}), align='center',
  115. ),],),
  116.  
  117.  
  118. ], width={'size': 8},md=8,sm=12,xs=12),
  119.  
  120.  
  121. dbc.Col(style={'content-align': 'center','padding-left': '50px' , 'padding-right': '50px','padding-top': '40px'}, children=[
  122.  
  123. dbc.Row([
  124. dbc.Col(id='stock_name1',align='center', width={'size': 2},style={'width': '20%','text-align': 'center','font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '15px', 'margin-right': '15px'}),
  125. dbc.Col(id='latest_price1',align='center', width={'size': 2},style={'color': 'white'}),
  126. dbc.Col(id='latest_price_change1',align='center', width={'size': 2})
  127.  
  128. ]),
  129. dbc.Row([dbc.Col(
  130. dcc.Graph(id="stocks1",config={'displayModeBar': False}) , align='center',
  131.  
  132. ),],),
  133.  
  134. dbc.Row([
  135. dbc.Col(id="stock_name2",align='center', width={'size': 2},style={'width': '20%','text-align': 'center','font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '15px', 'margin-right': '15px'}),
  136. dbc.Col(id='latest_price2',align='center', width={'size': 2},style={'color': 'white'}),
  137. dbc.Col(id='latest_price_change2',align='center', width={'size': 2})
  138.  
  139. ]),
  140. dbc.Row([dbc.Col(
  141. dcc.Graph(id="stocks2",config={'displayModeBar': False}) , align='center',
  142.  
  143. ),],),
  144.  
  145. dbc.Row([
  146. dbc.Col(id="stock_name3",align='center', width={'size': 2},style={'width': '20%','text-align': 'center','font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '15px', 'margin-right': '15px'}),
  147. dbc.Col(id='latest_price3',align='center', width={'size': 2},style={'color': 'white'}),
  148. dbc.Col(id='latest_price_change3',align='center', width={'size': 2})
  149.  
  150. ]),
  151. dbc.Row([dbc.Col(
  152. dcc.Graph(id="stocks3",config={'displayModeBar': False}) , align='center',
  153.  
  154. ),],),
  155.  
  156. dbc.Row([
  157. dbc.Col(id="stock_name4",align='center', width={'size': 2},style={'width': '20%','text-align': 'center','font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '15px', 'margin-right': '15px'}),
  158. dbc.Col(id='latest_price4',align='center', width={'size': 2},style={'color': 'white'}),
  159. dbc.Col(id='latest_price_change4',align='center', width={'size': 2})
  160.  
  161. ]),
  162. dbc.Row([dbc.Col(
  163. dcc.Graph(id="stocks4",config={'displayModeBar': False}) , align='center',
  164.  
  165. ),],),
  166.  
  167. dbc.Row([
  168. dbc.Col(id="stock_name5",align='center', width={'size': 2},style={'width': '20%','text-align': 'center','font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '15px', 'margin-right': '15px'}),
  169. dbc.Col(id='latest_price5',align='center', width={'size': 2},style={'color': 'white'}),
  170. dbc.Col(id='latest_price_change5',align='center', width={'size': 2})
  171.  
  172. ]),
  173. dbc.Row([dbc.Col(
  174. dcc.Graph(id="stocks5",config={'displayModeBar': False}) , align='center',
  175.  
  176. ),],),
  177.  
  178. dbc.Row([
  179. dbc.Col(id="stock_name6",align='left', width={'size': 2},style={'width': '20%','text-align': 'center','font-weight': 'bold','fontSize': '16','background-color': '#FFBF00','color': 'black', 'margin-left': '15px', 'margin-right': '15px'}),
  180. dbc.Col(id='latest_price6',align='center', width={'size': 2},style={'color': 'white'}),
  181. dbc.Col(id='latest_price_change6',align='center', width={'size': 2})
  182.  
  183. ]),
  184. dbc.Row([dbc.Col(
  185. dcc.Graph(id="stocks6",config={'displayModeBar': False}) , align='center',
  186.  
  187. ),],),
  188.  
  189. ], width={'size': 4},md=4,sm=12,xs=12),
  190. ]),
  191.  
  192. dcc.Store(id='line-visibility-store', data={'MA5': True, 'MA10': True, 'MA20': True}),
  193. dcc.Store(id='zoom_store'),
  194. dcc.Interval(id= "interval", interval = 1000)
  195.  
  196. ])
  197.  
  198. @app.callback(
  199. Output("candles", "figure"),
  200. Output("stocks1", "figure"),
  201. Output("stocks2", "figure"),
  202. Output("stocks3", "figure"),
  203. Output("stocks4", "figure"),
  204. Output("stocks5", "figure"),
  205. Output("stocks6", "figure"),
  206. Output("volume_chart", "figure"),
  207. Output("Rsi", "figure"),
  208. Output("stock_name", "children"),
  209. Output("latest_price", "children"),
  210. Output("latest_price_change", "children"),
  211. Output("volume", "children"),
  212. Output("latest_price_change", "style"),
  213. Output("stock_name1", "children"),
  214. Output("latest_price1", "children"),
  215. Output("latest_price_change1", "children"),
  216. Output("latest_price_change1", "style"),
  217. Output("stock_name2", "children"),
  218. Output("latest_price2", "children"),
  219. Output("latest_price_change2", "children"),
  220. Output("latest_price_change2", "style"),
  221. Output("stock_name3", "children"),
  222. Output("latest_price3", "children"),
  223. Output("latest_price_change3", "children"),
  224. Output("latest_price_change3", "style"),
  225. Output("stock_name4", "children"),
  226. Output("latest_price4", "children"),
  227. Output("latest_price_change4", "children"),
  228. Output("latest_price_change4", "style"),
  229. Output("stock_name5", "children"),
  230. Output("latest_price5", "children"),
  231. Output("latest_price_change5", "children"),
  232. Output("latest_price_change5", "style"),
  233. Output("stock_name6", "children"),
  234. Output("latest_price6", "children"),
  235. Output("latest_price_change6", "children"),
  236. Output("latest_price_change6", "style"),
  237. Input("interval", "n_intervals"),
  238. Input("zoom_store", "data"),
  239. Input("line_visibility_store", "data")
  240.  
  241. )
  242.  
  243.  
  244. def update_figure(n_intervals,zoom_data, line_visibility):
  245.  
  246. external_stylesheets = ['./assets/custom.css']
  247. #data
  248. stock = ['BOIL', 'PYPL', 'INTC', 'AAPL', 'AMZN', 'MSFT', 'TSLA']
  249. filename = 'stock_data.csv'
  250. data, latest_price, latest_price_change, volume = read_data(filename, stock[0], [1, 2, 3, 4])
  251.  
  252. pos = data['open'] - data['close'] < 0
  253. neg = data['open'] - data['close'] > 0
  254. data['x_axis'] = list(range(1, len(data['volume_diff']) +1))
  255. ymax = data['volume_diff'].max()
  256. ystd = data['volume_diff'].std()
  257.  
  258.  
  259.  
  260. candles = go.Figure()
  261. candles.add_trace(go.Candlestick(x=data.index,open=data['open'],high=data['high'],low=data['low'],close=data['close'],name=stock[0],showlegend=False))
  262. candles.add_trace(go.Scatter(x=data.index, y=data['MA5'],showlegend=True, name="5 minute SMA",marker={'color': 'pink'}, visible=line_visibility['MA5']))
  263. candles.add_trace(go.Scatter(x=data.index, y=data['MA10'],showlegend=True, name="10 minute SMA",marker={'color': 'orange'}, visible=line_visibility['MA10']))
  264. candles.add_trace(go.Scatter(x=data.index, y=data['MA20'], name="20 minute SMA",showlegend=True, marker={'color': '#08a0e9'}, visible=line_visibility['M20']))
  265. candles.update_layout(
  266. #width= 600,
  267. height=400,
  268. legend=dict(x=0.02,y=0.98,bgcolor='#091217',font=dict(color='white', size=10),bordercolor='white', borderwidth=0.5),
  269. xaxis=dict( zerolinecolor='#091217', showticklabels=False,gridcolor="grey"), #Candle
  270. yaxis=dict( gridcolor="grey", tickfont=dict(color='white')), #Candle
  271.  
  272. margin=dict(l=0, r=0, t=10, b=20),
  273. xaxis_rangeslider_visible=False,
  274. plot_bgcolor='#091217',
  275. paper_bgcolor=colors['background'],
  276. font_color=colors['text'],
  277. yaxis_range=[data['low'].min()- data['high'].std()*0.5,data['high'].max()+data['high'].std()*3 if not math.isnan(data['high'].max()) and data['high'].max() !=0 else [] ]
  278. )
  279.  
  280. if zoom_data is not None:
  281. candles.update_xaxes(range=zoom_data),
  282.  
  283.  
  284.  
  285. # Add volume chart to second subplot
  286. volume_chart = go.Figure()
  287. volume_chart.add_trace(go.Bar(x=data['x_axis'][pos],y=data['volume_diff'][pos],name='Volume',showlegend=False,marker={'color': 'Green'}))
  288. volume_chart.add_trace(go.Bar(x=data['x_axis'][neg],y=data['volume_diff'][neg],name='Volume',showlegend=False,marker={'color': 'Red'}))
  289. volume_chart.update_layout(
  290. #width= 300,
  291. height=80,
  292. yaxis_range=[0, ymax+ystd*3 if not math.isnan(ymax)else []],
  293. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=True, gridcolor="grey"), #Volume
  294. yaxis=dict(zerolinecolor='#091217',tickfont=dict(color='#121416'), showgrid=False),
  295. margin=dict(l=0, r=0, t=10, b=20),
  296. xaxis_rangeslider_visible=False,
  297. plot_bgcolor='#091217',
  298. paper_bgcolor=colors['background'],
  299. font_color=colors['text']
  300. )
  301.  
  302. # Add volume chart to second subplot
  303. Rsi = go.Figure()
  304. Rsi.add_trace(go.Bar(x=data['x_axis'][pos],y=data['volume_diff'][pos],name='Volume2',showlegend=False,marker={'color': 'Green'}))
  305. Rsi.update_layout(
  306. #width= 300,
  307. height=80,
  308. yaxis_range=[0, ymax+ystd*3 if not math.isnan(ymax)else []],
  309. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=True, gridcolor="grey"), #Volume
  310. yaxis=dict(zerolinecolor='#091217',tickfont=dict(color='#121416'), showgrid=False),
  311. margin=dict(l=0, r=0, t=10, b=20),
  312. xaxis_rangeslider_visible=False,
  313. plot_bgcolor='#091217',
  314. paper_bgcolor=colors['background'],
  315. font_color=colors['text']
  316. )
  317.  
  318. stocks1 = go.Figure()
  319. d2, latest_price1, latest_price_change1, volume = read_data(filename, stock[1], [1, 5, 6, 7])
  320. stocks1.add_trace(go.Scatter(x=d2.index, y=d2['close'],showlegend=False,marker={'color': 'White'}, name=stock[1]))
  321. stocks1.update_layout(
  322. #width= 300,
  323. height=82,
  324. yaxis_range=[d2['close'].min()-d2['close'].std()*0.5, d2['close'].max()+d2['close'].std()*3 if not math.isnan(d2['close'].max()) and d2['close'].max() != 0 else []],
  325. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=False),
  326. yaxis=dict(showticklabels=False, showgrid=False),
  327. margin=dict(l=0, r=0, t=10, b=20),
  328. xaxis_rangeslider_visible=False,
  329. plot_bgcolor='#091217',
  330. paper_bgcolor=colors['background'],
  331. font_color=colors['text']
  332. )
  333.  
  334. d3, latest_price2, latest_price_change2, volume2 = read_data(filename, stock[2], [1, 8, 9, 10])
  335. stocks2 = go.Figure()
  336. stocks2.add_trace(go.Scatter(x=d3.index, y=d3['close'],showlegend=False,marker={'color': 'White'}, name=stock[2]))
  337. stocks2.update_layout(
  338. #width= 300,
  339. height=82,
  340. yaxis_range=[d3['close'].min()-d3['close'].std()*0.5, d3['close'].max()+d3['close'].std()*3 if not math.isnan(d3['close'].max()) and d3['close'].max() != 0 else []],
  341. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=False),
  342. yaxis=dict(showticklabels=False, showgrid=False),
  343. margin=dict(l=0, r=0, t=10, b=20),
  344. xaxis_rangeslider_visible=False,
  345. plot_bgcolor='#091217',
  346. paper_bgcolor=colors['background'],
  347. font_color=colors['text']
  348. )
  349.  
  350. d4, latest_price3, latest_price_change3, volume3 = read_data(filename, stock[3], [1, 11, 12, 13])
  351. stocks3 = go.Figure()
  352. stocks3.add_trace(go.Scatter(x=d4.index, y=d4['close'],showlegend=False,marker={'color': 'White'}, name=stock[3]))
  353. stocks3.update_layout(
  354. #width= 300,
  355. height=82,
  356. yaxis_range=[d4['close'].min()-d4['close'].std()*0.5, d4['close'].max()+d4['close'].std()*3 if not math.isnan(d4['close'].max()) and d4['close'].max() != 0 else []],
  357. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=False),
  358. yaxis=dict(showticklabels=False, showgrid=False),
  359. margin=dict(l=0, r=0, t=10, b=20),
  360. xaxis_rangeslider_visible=False,
  361. plot_bgcolor='#091217',
  362. paper_bgcolor=colors['background'],
  363. font_color=colors['text']
  364. )
  365.  
  366. stocks4 = go.Figure()
  367. d5, latest_price4, latest_price_change4, volume4 = read_data(filename, stock[4], [1, 14, 15, 16])
  368. stocks4.add_trace(go.Scatter(x=d5.index, y=d5['close'],showlegend=False,marker={'color': 'White'}, name=stock[4]))
  369. stocks4.update_layout(
  370. #width= 300,
  371. height=82,
  372. yaxis_range=[d5['close'].min()-d5['close'].std()*0.5, d5['close'].max()+d5['close'].std()*3 if not math.isnan(d5['close'].max()) and d5['close'].max() != 0 else []],
  373. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=False),
  374. yaxis=dict(showticklabels=False, showgrid=False),
  375. margin=dict(l=0, r=0, t=10, b=20),
  376. xaxis_rangeslider_visible=False,
  377. plot_bgcolor='#091217',
  378. paper_bgcolor=colors['background'],
  379. font_color=colors['text']
  380. )
  381.  
  382. d6, latest_price5, latest_price_change5, volume5 = read_data(filename, stock[5], [1, 17, 18, 19])
  383. stocks5 = go.Figure()
  384. stocks5.add_trace(go.Scatter(x=d6.index, y=d6['close'],showlegend=False,marker={'color': 'White'}, name=stock[5]))
  385. stocks5.update_layout(
  386. #width= 300,
  387. height=82,
  388. yaxis_range=[d6['close'].min()-d6['close'].std()*0.5, d6['close'].max()+d6['close'].std()*3 if not math.isnan(d6['close'].max()) and d6['close'].max() != 0 else []],
  389. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=False),
  390. yaxis=dict(showticklabels=False, showgrid=False),
  391. margin=dict(l=0, r=0, t=10, b=20),
  392. xaxis_rangeslider_visible=False,
  393. plot_bgcolor='#091217',
  394. paper_bgcolor=colors['background'],
  395. font_color=colors['text']
  396. )
  397.  
  398. d7, latest_price6, latest_price_change6, volume6 = read_data(filename, stock[6], [1, 20, 21, 22])
  399. stocks6 = go.Figure()
  400. stocks6.add_trace(go.Scatter(x=d7.index, y=d7['close'],showlegend=False,marker={'color': 'White'}, name=stock[2]))
  401. stocks6.update_layout(
  402. #width= 300,
  403. height=82,
  404. yaxis_range=[d7['close'].min()-d7['close'].std()*0.5, d7['close'].max()+d7['close'].std()*3 if not math.isnan(d7['close'].max()) and d7['close'].max() != 0 else []],
  405. xaxis=dict(zerolinecolor='#091217',showticklabels=False, showgrid=False),
  406. yaxis=dict(showticklabels=False, showgrid=False),
  407. margin=dict(l=0, r=0, t=10, b=20),
  408. xaxis_rangeslider_visible=False,
  409. plot_bgcolor='#091217',
  410. paper_bgcolor=colors['background'],
  411. font_color=colors['text']
  412. )
  413. #{'color': '#18b800' if latest_price_change[0] == '+' else '#ff3503'}
  414. return candles,stocks1, stocks2, stocks3, stocks4, stocks5, stocks6, volume_chart, Rsi, \
  415. stock[0], latest_price, latest_price_change, volume ,{'color': '#18b800' if latest_price_change[0] == '+' else '#ff3503'}, stock[1], latest_price1, latest_price_change1,{'color': '#18b800' if latest_price_change1[0] == '+' else '#ff3503'}, \
  416. stock[2], latest_price2, latest_price_change2,{'color': '#18b800' if latest_price_change2[0] == '+' else '#ff3503'},stock[3], latest_price3, latest_price_change3,{'color': '#18b800' if latest_price_change3[0] == '+' else '#ff3503'}, \
  417. stock[4], latest_price4, latest_price_change4,{'color': '#18b800' if latest_price_change4[0] == '+' else '#ff3503'}, stock[5], latest_price5, latest_price_change5,{'color': '#18b800' if latest_price_change5[0] == '+' else '#ff3503'}, \
  418. stock[6], latest_price6, latest_price_change6,{'color': '#18b800' if latest_price_change6[0] == '+' else '#ff3503'}
  419.  
  420. @app.callback(
  421.  
  422. Output('zoom_store', 'data'),
  423. Input('candles', 'relayoutData'))
  424.  
  425. def update_zoom(relayout_data):
  426. if relayout_data is not None and 'xaxis.range[0]' in relayout_data and 'xaxis.range[1]' in relayout_data:
  427. return [relayout_data['xaxis.range[0]'], relayout_data['xaxis.range[1]']]
  428. return None
  429.  
  430. @app.callback(
  431. Output('line_visibility_store', 'data'),
  432. Input('candles', 'restyleData'),
  433. State("line-visibility-store", 'data'))
  434.  
  435. def update_line_visibility(restyle_data, current_visibility):
  436. if restyle_data is not None and 'visible' in restyle_data:
  437. new_visibility = current_visibility.copy()
  438. for i, visible in enumerate(restyle_data['visible']):
  439. if i == 0:
  440. new_visibility['MA5'] = visible
  441. elif i == 1:
  442. new_visibility['MA10'] = visible
  443. elif i == 2:
  444. new_visibility['MA20'] = visible
  445. return new_visibility
  446. return current_visibility
  447.  
  448. app.run_server()
  449.  
  450. class XAxisSizeGrip3(QSizeGrip):
  451. def __init__(self, parent=None):
  452. super().__init__(parent)
  453.  
  454. def mousePressEvent(self, event):
  455. super().mousePressEvent(event)
  456. self.window().setMaximumWidth(self.width())
  457. self.window().setMinimumWidth(self.width())
  458. self.window().setMaximumHeight(16777215)
  459. self.window().setMinimumHeight(0)
  460.  
  461. def enterEvent(self, event):
  462. super().enterEvent(event)
  463. self.setCursor(QCursor(Qt.SizeVerCursor))
  464.  
  465. def leaveEvent(self, event):
  466. super().leaveEvent(event)
  467. self.unsetCursor()
  468.  
  469. def mouseReleaseEvent(self, event):
  470. super().mouseReleaseEvent(event)
  471. self.window().setMaximumWidth(16777215) # remove the height limit after the drag is complete
  472. self.window().setMinimumWidth(0) # remove the height limit after the drag is complete
  473.  
  474. class XAxisSizeGrip(QSizeGrip):
  475. def __init__(self, parent=None):
  476. super().__init__(parent)
  477.  
  478. def mousePressEvent(self, event):
  479. super().mousePressEvent(event)
  480. self.window().setMaximumHeight(16777215)
  481. self.window().setMinimumHeight(0)
  482. self.window().setMaximumWidth(16777215)
  483. self.window().setMinimumWidth(0)
  484.  
  485. class XAxisSizeGrip2(QSizeGrip):
  486. def __init__(self, parent=None):
  487. super().__init__(parent)
  488.  
  489.  
  490. def enterEvent(self, event):
  491. super().enterEvent(event)
  492. self.setCursor(QCursor(Qt.SizeHorCursor))
  493.  
  494. def leaveEvent(self, event):
  495. super().leaveEvent(event)
  496. self.unsetCursor()
  497.  
  498. def mousePressEvent(self, event):
  499. super().mousePressEvent(event)
  500. #self.setCursor(QCursor(Qt.SizeHorCursor))
  501. self.window().setMaximumWidth(16777215)
  502. self.window().setMinimumWidth(0)
  503. self.window().setMaximumHeight(self.height())
  504. self.window().setMinimumHeight(self.height())
  505.  
  506.  
  507. def mouseReleaseEvent(self, event):
  508. super().mouseReleaseEvent(event)
  509. self.window().setMaximumHeight(16777215) # remove the height limit after the drag is complete
  510. self.window().setMinimumHeight(0) # remove the height limit after the drag is complete
  511.  
  512. class App(QMainWindow):
  513. window_resized = pyqtSignal()
  514. def __init__(self):
  515. super().__init__()
  516. uic.loadUi('gui2.ui', self)
  517.  
  518. self.setAttribute(Qt.WA_TranslucentBackground, True)
  519. self.setWindowFlag(Qt.FramelessWindowHint)
  520. self.setGeometry(0, 0, 1250, 900)
  521. self.groupBox_3_layout = QVBoxLayout(self.groupBox_3)
  522. web1 = QWebEngineView()
  523. web1.load(QUrl("http://127.0.0.1:8050"))
  524. self.groupBox_3_layout.addWidget(web1)
  525. self.pushButton_6.clicked.connect(self.on_pushButton_6_clicked)
  526. #button to min
  527. self.pushButton_9.clicked.connect(self.minimize_window)
  528. #button to max
  529. self.pushButton_8.clicked.connect(self.maximize_window)
  530. #button
  531. self.pushButton_7.clicked.connect(self.close_window)
  532.  
  533. self.is_maximized = False
  534. self.original_geometry = self.geometry()
  535.  
  536. # Set up the drag event for groupBox_23
  537. self.dragPos = None
  538. self.groupBox23.mouseMoveEvent = self.mouseMoveEvent1
  539. self.groupBox23.mousePressEvent = self.mousePressEvent1
  540.  
  541.  
  542. # Top left corner
  543. size_grip1 = XAxisSizeGrip(self)
  544. size_grip1.setToolTip("Resize")
  545. size_grip1.setGeometry(0, 0, 10, 10)
  546. size_grip1.setStyleSheet("background-color: transparent;")
  547.  
  548. # top right corner
  549. size_grip2 = XAxisSizeGrip(self)
  550. size_grip2.setToolTip("Resize")
  551. size_grip2.setGeometry(0, self.height() - 10, 10, 10)
  552. size_grip2.setStyleSheet("background-color: transparent;")
  553.  
  554. # Botom left corner
  555. size_grip3 = XAxisSizeGrip(self)
  556. size_grip3.setToolTip("Resize")
  557. size_grip3.setGeometry(self.width() - 10, 0, 10, 10)
  558. size_grip3.setStyleSheet("background-color: transparent;")
  559.  
  560. # Bottom Right corner
  561. size_grip4 = XAxisSizeGrip(self)
  562. size_grip4.setToolTip("Resize")
  563. size_grip4.setGeometry(-10, self.height() - 10, self.width(), 10)
  564. size_grip4.setStyleSheet("background-color: transparent;")
  565.  
  566. # Right side
  567. size_grip5 = XAxisSizeGrip2(self)
  568. size_grip5.setToolTip("Resize")
  569. size_grip5.setGeometry(0, - 10, 10, self.height()-20)
  570. size_grip5.setStyleSheet("background-color: transparent;")
  571.  
  572. # Left side
  573. size_grip6 = XAxisSizeGrip2(self)
  574. size_grip6.setToolTip("Resize")
  575. size_grip6.setGeometry(0, - 10, 10, self.height()-20)
  576. size_grip6.setStyleSheet("background-color: transparent;")
  577.  
  578. # Bottom side
  579. size_grip7 = XAxisSizeGrip3(self)
  580. size_grip7.setToolTip("Resize")
  581. size_grip7.setGeometry(self.width()-self.width()+10, self.height() - 10, self.width()-20, 10)
  582. size_grip7.setStyleSheet("background-color: transparent;")
  583.  
  584. self.size_grip1 = size_grip1
  585. self.size_grip2 = size_grip2
  586. self.size_grip3 = size_grip3
  587. self.size_grip4 = size_grip4
  588. self.size_grip5 = size_grip5
  589. self.size_grip6 = size_grip6
  590. self.size_grip7 = size_grip7
  591.  
  592. self.previous_geometry = None
  593.  
  594. self.window_resized.connect(self.update_size_grips)
  595.  
  596. def on_pushButton_6_clicked(self):
  597. if self.groupBox_4.maximumWidth() == 0:
  598. self.groupBox_4.setMaximumWidth(130)
  599. else:
  600. self.groupBox_4.setMaximumWidth(0)
  601.  
  602. def minimize_window(self):
  603. self.showMinimized()
  604.  
  605. def maximize_window(self):
  606. if self.isMaximized():
  607. self.showNormal()
  608. self.is_maximized = False
  609. self.setGeometry(self.original_geometry)
  610. else:
  611. self.showMaximized()
  612. self.is_maximized = True
  613.  
  614. def close_window(self):
  615. self.close()
  616.  
  617. # Function to handle the mouse press event
  618.  
  619. def mousePressEvent1(self, event):
  620. if event.button() == Qt.LeftButton:
  621. self.dragPos = event.globalPos()
  622.  
  623. def mouseMoveEvent1(self, event):
  624. if self.dragPos is not None:
  625. delta = event.globalPos() - self.dragPos
  626. new_pos = self.pos() + delta
  627. self.move(new_pos)
  628. self.dragPos = event.globalPos()
  629.  
  630. screen_geometry = QApplication.desktop().availableGeometry()
  631. screen_margin = 30 # Adjust this value to change the docking sensitivity
  632.  
  633. # Left edge docking
  634. if event.globalX() <= screen_margin and not self.isMaximized():
  635. if self.previous_geometry is None:
  636. self.previous_geometry = self.geometry()
  637. self.setGeometry(QRect(0, 0, screen_geometry.width() // 2, screen_geometry.height()))
  638.  
  639. # Right edge docking
  640. elif event.globalX() >= screen_geometry.width() - screen_margin and not self.isMaximized():
  641. if self.previous_geometry is None:
  642. self.previous_geometry = self.geometry()
  643. self.setGeometry(QRect(screen_geometry.width() // 2, 0, screen_geometry.width() // 2, screen_geometry.height()))
  644.  
  645. # Undock and restore previous geometry
  646. elif self.previous_geometry is not None:
  647. new_x = new_pos.x()
  648. new_y = new_pos.y()
  649. undocked_geometry = QRect(new_x, new_y, self.previous_geometry.width(), self.previous_geometry.height())
  650. self.setGeometry(undocked_geometry)
  651. self.previous_geometry = None
  652.  
  653.  
  654.  
  655.  
  656.  
  657. def mouseReleaseEvent(self, event):
  658. self.dragPos = None
  659.  
  660. def resizeEvent(self, event):
  661. super().resizeEvent(event)
  662. self.window_resized.emit()
  663.  
  664. def update_size_grips(self):
  665. self.size_grip2.setGeometry(self.width() - 10, 0, 10, 10)
  666. self.size_grip3.setGeometry(0, self.height() - 10, 10, 10)
  667. self.size_grip4.setGeometry(self.width()-10, self.height() - 10, 10, 10)
  668. self.size_grip5.setGeometry(self.width()-10 , 10, 10, self.height()-20)
  669. self.size_grip6.setGeometry(0 , 10, 10, self.height()-20)
  670. self.size_grip7.setGeometry(self.width()-self.width()+10, self.height() - 10, self.width()-20, 10)
  671.  
  672. if __name__ == '__main__':
  673. threading.Thread(target=run_dash, args=(), daemon=True).start()
  674. app = QApplication(sys.argv)
  675. win = App()
  676. win.show()
  677. sys.exit(app.exec_())
  678.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement