Benjamin Consolvo commited on
Commit
3fba644
·
1 Parent(s): dc37fde

simplify clock

Browse files
Files changed (1) hide show
  1. app.py +1 -166
app.py CHANGED
@@ -742,167 +742,6 @@ def load_auto_trade_log():
742
  except Exception:
743
  return None
744
 
745
- class TradingApp:
746
- def __init__(self):
747
- self.alpaca = AlpacaTrader(st.secrets['ALPACA_API_KEY'], st.secrets['ALPACA_SECRET_KEY'], 'https://paper-api.alpaca.markets')
748
- self.sentiment = NewsSentiment(st.secrets['NEWS_API_KEY'])
749
- self.analyzer = StockAnalyzer(self.alpaca)
750
- self.data = self.analyzer.get_historical_data(self.analyzer.symbols)
751
- self.auto_trade_log = [] # Store automatic trade actions
752
-
753
- def display_charts(self):
754
- # Dynamically adjust columns based on number of stocks and available width
755
- symbols = list(self.data.keys())
756
- symbol_to_name = self.analyzer.symbol_to_name
757
- n = len(symbols)
758
-
759
- # Calculate columns based on n for best fit
760
- if n <= 3:
761
- cols = n
762
- elif n <= 6:
763
- cols = 3
764
- elif n <= 8:
765
- cols = 4
766
- elif n <= 12:
767
- cols = 4
768
- else:
769
- cols = 5
770
-
771
- rows = (n + cols - 1) // cols
772
- subplot_titles = [
773
- f"{symbol} - {symbol_to_name.get(symbol, '')}" for symbol in symbols
774
- ]
775
- fig = make_subplots(rows=rows, cols=cols, subplot_titles=subplot_titles)
776
- for idx, symbol in enumerate(symbols):
777
- df = self.data[symbol]
778
- if not df.empty:
779
- row = idx // cols + 1
780
- col = idx % cols + 1
781
- fig.add_trace(
782
- go.Scatter(
783
- x=df.index,
784
- y=df['Close'],
785
- mode='lines',
786
- name=symbol,
787
- hovertemplate=f"%{{x}}<br>{symbol}: %{{y:.2f}}<extra></extra>"
788
- ),
789
- row=row,
790
- col=col
791
- )
792
- fig.update_layout(
793
- title="Top Volume Stocks - Price Charts (Since 2023)",
794
- height=max(400 * rows, 600),
795
- showlegend=False,
796
- dragmode=False,
797
- )
798
- # Enable scroll-zoom for each subplot (individual zoom)
799
- fig.update_layout(
800
- xaxis=dict(fixedrange=False),
801
- yaxis=dict(fixedrange=False),
802
- )
803
- for i in range(1, rows * cols + 1):
804
- fig.layout[f'xaxis{i}'].update(fixedrange=False)
805
- fig.layout[f'yaxis{i}'].update(fixedrange=False)
806
- st.plotly_chart(fig, use_container_width=True, config={"scrollZoom": True})
807
-
808
- def manual_trade(self):
809
- # Move all user inputs to the sidebar
810
- with st.sidebar:
811
- st.header("Manual Trade")
812
- symbol = st.text_input('Enter stock symbol')
813
- qty = int(st.number_input('Enter quantity'))
814
- action = st.selectbox('Action', ['Buy', 'Sell'])
815
- if st.button('Execute'):
816
- if action == 'Buy':
817
- order = self.alpaca.buy(symbol, qty)
818
- else:
819
- order = self.alpaca.sell(symbol, qty)
820
- if order:
821
- st.success(f"Order executed: {action} {qty} shares of {symbol}")
822
- else:
823
- st.error("Order failed")
824
- st.header("Portfolio")
825
- st.write("Cash Balance:")
826
- st.write(self.alpaca.getCash())
827
- st.write("Holdings:")
828
- st.write(self.alpaca.getHoldings())
829
- st.write("Recent Trades:")
830
- st.write(pd.DataFrame(self.alpaca.trades))
831
-
832
- def auto_trade_based_on_sentiment(self, sentiment):
833
- # Add company name to each action
834
- actions = []
835
- symbol_to_name = self.analyzer.symbol_to_name
836
- for symbol, sentiment_value in sentiment.items():
837
- action = None
838
- if sentiment_value == 'Positive':
839
- order = self.alpaca.buy(symbol, 1)
840
- action = 'Buy'
841
- elif sentiment_value == 'Negative':
842
- order = self.alpaca.sell(symbol, 1)
843
- action = 'Sell'
844
- else:
845
- order = None
846
- action = 'Hold'
847
- actions.append({
848
- 'symbol': symbol,
849
- 'company_name': symbol_to_name.get(symbol, ''),
850
- 'sentiment': sentiment_value,
851
- 'action': action
852
- })
853
- self.auto_trade_log = actions
854
- return actions
855
-
856
- def background_auto_trade(app):
857
- # This function runs in a background thread and does not require a TTY.
858
- # The warning "tcgetpgrp failed: Not a tty" is harmless and can be ignored.
859
- # It is likely caused by the environment in which the script is running (e.g., Streamlit, Docker, or a notebook).
860
- # No code changes are needed for this warning.
861
- while True:
862
- sentiment = app.sentiment.get_news_sentiment(app.analyzer.symbols)
863
- actions = []
864
- for symbol, sentiment_value in sentiment.items():
865
- action = None
866
- if sentiment_value == 'Positive':
867
- order = app.alpaca.buy(symbol, 1)
868
- action = 'Buy'
869
- elif sentiment_value == 'Negative':
870
- order = app.alpaca.sell(symbol, 1)
871
- action = 'Sell'
872
- else:
873
- order = None
874
- action = 'Hold'
875
- actions.append({
876
- 'symbol': symbol,
877
- 'sentiment': sentiment_value,
878
- 'action': action
879
- })
880
- # Append to log file instead of overwriting
881
- log_entry = {
882
- "timestamp": datetime.now().isoformat(),
883
- "actions": actions,
884
- "sentiment": sentiment
885
- }
886
- try:
887
- if os.path.exists(AUTO_TRADE_LOG_PATH):
888
- with open(AUTO_TRADE_LOG_PATH, "r") as f:
889
- log_data = json.load(f)
890
- else:
891
- log_data = []
892
- except Exception:
893
- log_data = []
894
- log_data.append(log_entry)
895
- with open(AUTO_TRADE_LOG_PATH, "w") as f:
896
- json.dump(log_data, f)
897
- time.sleep(AUTO_TRADE_INTERVAL)
898
-
899
- def load_auto_trade_log():
900
- try:
901
- with open(AUTO_TRADE_LOG_PATH, "r") as f:
902
- return json.load(f)
903
- except Exception:
904
- return None
905
-
906
 
907
  def get_market_times(alpaca_api):
908
  try:
@@ -935,7 +774,7 @@ def main():
935
  thread.start()
936
  st.session_state["auto_trade_thread_started"] = True
937
 
938
- # Dynamic market clock
939
  is_open, now, next_open, next_close = get_market_times(app.alpaca.alpaca)
940
  market_status = "🟢 Market is OPEN" if is_open else "🔴 Market is CLOSED"
941
  st.markdown(f"### {market_status}")
@@ -952,10 +791,6 @@ def main():
952
  seconds_left = int((next_open - now).total_seconds())
953
  st.markdown(f"**Time until open:** {pd.to_timedelta(seconds_left, unit='s')}")
954
 
955
- # Add auto-refresh for the clock every 5 seconds
956
- st.experimental_rerun()
957
- time.sleep(5)
958
-
959
  # User inputs and portfolio are now in the sidebar
960
  app.manual_trade()
961
 
 
742
  except Exception:
743
  return None
744
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
 
746
  def get_market_times(alpaca_api):
747
  try:
 
774
  thread.start()
775
  st.session_state["auto_trade_thread_started"] = True
776
 
777
+ # Static market clock (no auto-refresh)
778
  is_open, now, next_open, next_close = get_market_times(app.alpaca.alpaca)
779
  market_status = "🟢 Market is OPEN" if is_open else "🔴 Market is CLOSED"
780
  st.markdown(f"### {market_status}")
 
791
  seconds_left = int((next_open - now).total_seconds())
792
  st.markdown(f"**Time until open:** {pd.to_timedelta(seconds_left, unit='s')}")
793
 
 
 
 
 
794
  # User inputs and portfolio are now in the sidebar
795
  app.manual_trade()
796