Guest User

Untitled

a guest
Jun 30th, 2024
402
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1.  
  2. import os
  3. import openai
  4. import pandas as pd
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. from datetime import datetime
  8. import json
  9. from alpha_vantage.timeseries import TimeSeries
  10. import sqlite3
  11. from time import sleep
  12.  
  13. # Set your OpenAI and Alpha Vantage API keys
  14. os.environ["OPENAI_API_KEY"] = ''
  15. openai.api_key = os.getenv("OPENAI_API_KEY")
  16. alpha_vantage_api_key = "" # Replace with your Alpha Vantage API key
  17.  
  18. # Database connection
  19. def create_connection(db_file):
  20. conn = None
  21. try:
  22. conn = sqlite3.connect(db_file)
  23. print(f"Connected to SQLite database {db_file}")
  24. except Exception as e:
  25. print(f"Error connecting to database: {e}")
  26. return conn
  27.  
  28. def create_table(conn):
  29. try:
  30. c = conn.cursor()
  31. c.execute('''CREATE TABLE IF NOT EXISTS stock_data (
  32. timestamp TEXT PRIMARY KEY,
  33. open REAL,
  34. high REAL,
  35. low REAL,
  36. close REAL,
  37. volume INTEGER,
  38. macd REAL,
  39. macd_signal REAL,
  40. rsi REAL,
  41. bollinger_high REAL,
  42. bollinger_low REAL,
  43. signal INTEGER
  44. )''')
  45. conn.commit()
  46. except Exception as e:
  47. print(f"Error creating table: {e}")
  48.  
  49. def save_to_database(conn, data):
  50. try:
  51. cursor = conn.cursor()
  52. for index, row in data.iterrows():
  53. cursor.execute("""
  54. INSERT OR IGNORE INTO stock_data (timestamp, open, high, low, close, volume, macd, macd_signal, rsi, bollinger_high, bollinger_low, signal)
  55. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  56. """, (
  57. index.strftime("%Y-%m-%d %H:%M:%S"), # Format the timestamp
  58. float(row['open']),
  59. float(row['high']),
  60. float(row['low']),
  61. float(row['close']),
  62. int(row['volume']),
  63. float(row['macd']),
  64. float(row['macd_signal']),
  65. float(row['rsi']),
  66. float(row['bollinger_high']),
  67. float(row['bollinger_low']),
  68. int(row.get('signal', None)) if row.get('signal', None) is not None else None
  69. ))
  70. conn.commit()
  71. print("Data saved to database.")
  72. except Exception as e:
  73. print(f"Error saving data to database: {e}")
  74.  
  75. # Fetch 60-minute intraday stock data from Alpha Vantage
  76. def fetch_60min_data_from_alpha_vantage(ticker):
  77. ts = TimeSeries(key=alpha_vantage_api_key, output_format='pandas')
  78. try:
  79. data, meta_data = ts.get_intraday(symbol=ticker, interval='60min', outputsize='full')
  80. data.rename(columns={
  81. "1. open": "open",
  82. "2. high": "high",
  83. "3. low": "low",
  84. "4. close": "close",
  85. "5. volume": "volume"
  86. }, inplace=True)
  87. data = data[['open', 'high', 'low', 'close', 'volume']]
  88. return data
  89. except Exception as e:
  90. print(f"Error fetching 60-minute intraday stock data from Alpha Vantage: {e}")
  91. return None
  92.  
  93. # Handle missing data by filling or interpolating
  94. def handle_missing_data(data):
  95. data = data.sort_index()
  96. data = data.resample('60T').ffill() # Forward fill missing data points
  97. return data
  98.  
  99. # Calculate technical indicators
  100. def calculate_technical_indicators(data, params):
  101. # MACD
  102. short_ema = data['close'].ewm(span=params['macd']['short_ema'], adjust=False).mean()
  103. long_ema = data['close'].ewm(span=params['macd']['long_ema'], adjust=False).mean()
  104. data['macd'] = short_ema - long_ema
  105. data['macd_signal'] = data['macd'].ewm(span=params['macd']['signal_line'], adjust=False).mean()
  106.  
  107. # RSI
  108. delta = data['close'].diff()
  109. gain = (delta.where(delta > 0, 0)).rolling(window=params['rsi']['period']).mean()
  110. loss = (-delta.where(delta < 0, 0)).rolling(window=params['rsi']['period']).mean()
  111. rs = gain / loss
  112. data['rsi'] = 100 - (100 / (1 + rs))
  113.  
  114. # Bollinger Bands
  115. rolling_mean = data['close'].rolling(window=params['bollinger_bands']['period']).mean()
  116. rolling_std = data['close'].rolling(window=params['bollinger_bands']['period']).std()
  117. data['bollinger_high'] = rolling_mean + (rolling_std * params['bollinger_bands']['standard_deviation'])
  118. data['bollinger_low'] = rolling_mean - (rolling_std * params['bollinger_bands']['standard_deviation'])
  119.  
  120. return data
  121.  
  122. # Generate trading signals based on optimized parameters using OpenAI
  123. def generate_trading_signals(data, params):
  124. recent_data = data.tail(50) # Only use the most recent 50 data points to stay within token limits
  125. data_json = recent_data.reset_index().to_json(orient='records', date_format='iso') # Include timestamps
  126. params_json = json.dumps(params)
  127.  
  128. prompt = (
  129. f"Given the following stock data with technical indicators in JSON format:\n{data_json}\n"
  130. f"and the following optimized parameters for the technical indicators:\n{params_json}\n"
  131. "Generate trading signals based on the following conditions:\n"
  132. "- Buy signal (1) if MACD crosses above the MACD signal line, RSI is below 30, or the closing price crosses above the lower Bollinger Band.\n"
  133. "- Sell signal (-1) if MACD crosses below the MACD signal line, RSI is above 70, or the closing price crosses below the upper Bollinger Band.\n"
  134. "Also, provide exit points based on the generated signals. Provide the output in JSON format with the structure:\n"
  135. "[\n"
  136. " {\"timestamp\": \"YYYY-MM-DDTHH:MM:SS\", \"signal\": 1/-1, \"exit\": \"YYYY-MM-DDTHH:MM:SS\"},\n"
  137. " ...\n"
  138. "]"
  139. "Ensure the timestamps are in chronological order and valid."
  140. )
  141.  
  142. try:
  143. response = openai.ChatCompletion.create(
  144. model="gpt-4",
  145. messages=[
  146. {"role": "system", "content": "You are a financial expert."},
  147. {"role": "user", "content": prompt}
  148. ],
  149. max_tokens=1500
  150. )
  151.  
  152. signals_text = response['choices'][0]['message']['content'].strip()
  153. print(f"Raw response from OpenAI: {signals_text}")
  154.  
  155. # Extract JSON from the response
  156. start_index = signals_text.find("[")
  157. end_index = signals_text.rfind("]") + 1
  158. signals_json = signals_text[start_index:end_index]
  159.  
  160. signals = json.loads(signals_json)
  161.  
  162. # Sort signals by timestamp to ensure chronological order
  163. signals = sorted(signals, key=lambda x: x['timestamp'])
  164.  
  165. # Add exit points based on the next signal's timestamp
  166. for i in range(len(signals) - 1):
  167. signals[i]['exit'] = signals[i + 1]['timestamp']
  168. signals[-1]['exit'] = None # Last signal has no exit point
  169.  
  170. return signals
  171. except json.JSONDecodeError as e:
  172. print(f"Error parsing signals: {e}")
  173. print(f"Response from OpenAI: {signals_text}")
  174. except Exception as e:
  175. print(f"Error fetching trading signals from OpenAI: {e}")
  176.  
  177. return None
  178.  
  179. # Execute trades based on signals
  180. def execute_trades(signals, current_position):
  181. for signal in signals:
  182. timestamp = pd.to_datetime(signal['timestamp'])
  183. # Check if the signal timestamp is within market hours
  184. if timestamp.time() >= datetime.strptime("09:30", "%H:%M").time() and timestamp.time() <= datetime.strptime("16:00", "%H:%M").time():
  185. if signal['signal'] == 1 and current_position == 0:
  186. print(f"Executing buy trade at {signal['timestamp']}")
  187. current_position = 1 # Enter long position
  188. elif signal['signal'] == -1 and current_position == 1:
  189. print(f"Executing sell trade at {signal['timestamp']}")
  190. current_position = 0 # Exit long position
  191. elif signal['signal'] == -1 and current_position == 0:
  192. print(f"Executing short trade at {signal['timestamp']}")
  193. current_position = -1 # Enter short position
  194. elif signal['signal'] == 1 and current_position == -1:
  195. print(f"Executing cover trade at {signal['timestamp']}")
  196. current_position = 0 # Exit short position
  197. return current_position
  198.  
  199. # Main function to execute the script
  200. def main():
  201. ticker = 'IBM' # Specify the ticker for IBM
  202. db_file = 'stock_data.db' # Database file
  203.  
  204. # Create database connection and table
  205. conn = create_connection(db_file)
  206. create_table(conn)
  207.  
  208. # Initial parameters for technical indicators (you can fetch these from OpenAI if desired)
  209. initial_params = {
  210. "macd": {"short_ema": 12, "long_ema": 26, "signal_line": 9},
  211. "rsi": {"period": 14},
  212. "bollinger_bands": {"period": 20, "standard_deviation": 2}
  213. }
  214.  
  215. current_position = 0 # 0 = no position, 1 = long, -1 = short
  216.  
  217. while True:
  218. print(f"Fetching latest intraday stock data for {ticker}...")
  219. new_data = fetch_60min_data_from_alpha_vantage(ticker)
  220. if new_data is None:
  221. print("Failed to fetch new stock data. Retrying in an hour...")
  222. sleep(3600) # Wait for an hour before retrying
  223. continue
  224.  
  225. # Handle missing data
  226. new_data = handle_missing_data(new_data)
  227.  
  228. # Calculate technical indicators for the new data
  229. new_data_with_indicators = calculate_technical_indicators(new_data, initial_params)
  230.  
  231. # Generate trading signals and exit points using OpenAI
  232. signals = generate_trading_signals(new_data_with_indicators, initial_params)
  233. if signals is None:
  234. print("Failed to generate trading signals. Retrying in an hour...")
  235. sleep(3600) # Wait for an hour before retrying
  236. continue
  237.  
  238. # Update database with new data and signals
  239. save_to_database(conn, new_data_with_indicators)
  240.  
  241. # Execute trades based on signals
  242. current_position = execute_trades(signals, current_position)
  243.  
  244. print("Waiting for the next update...")
  245. sleep(3600) # Wait for an hour before fetching new data
  246.  
  247. if __name__ == "__main__":
  248. main()
Advertisement
Add Comment
Please, Sign In to add comment