-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmain.py
123 lines (106 loc) · 4.7 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import sys
import ast
import pytz
import keyring
import logging
import traceback
import pandas as pd
import pandas_market_calendars as mcal
from bot import Bot
from datetime import datetime, time
from requests.exceptions import HTTPError
from exceptions import HardToBorrowException
# Retrieve credentials from keyring
consumer_key = keyring.get_password("etrade", "consumer_key")
consumer_secret = keyring.get_password("etrade", "consumer_secret")
sandbox_key = keyring.get_password("etrade", "sandbox_key")
sandbox_secret = keyring.get_password("etrade", "sandbox_secret")
web_username = keyring.get_password("etrade", "web_username")
web_password = keyring.get_password("etrade", "web_password")
account_id = keyring.get_password("etrade", "account_id")
etrade_cookie = ast.literal_eval(keyring.get_password("etrade", "etrade_cookie"))
account_id_key = keyring.get_password("etrade", "account_id_key")
def is_market_open():
now = datetime.now(pytz.timezone('US/Eastern'))
market_open_time = time(hour=9, minute=30)
market_close_time = time(hour=16, minute=0)
nyse = mcal.get_calendar('NYSE')
# Check if current time is within market hours and a weekday
if market_open_time <= now.time() <= market_close_time and now.weekday() < 5:
current_date = now.date()
# Convert current_date to string format
current_date_str = current_date.strftime('%Y-%m-%d')
# Check if the current date is a holiday
holidays = nyse.holidays().holidays
if current_date in holidays:
return False, "The market is closed today due to a holiday."
try:
# Get the market schedule for the current date
schedule = nyse.schedule(start_date=current_date_str, end_date=current_date_str)
# Check if the schedule is empty (market closed) or not
if schedule.empty:
return False, "The market is closed today for an unknown reason."
else:
return True, None
except Exception as e:
traceback.print_exc() # Print detailed traceback
return False, f"An error occurred: {e}"
else:
return False, "The market is closed now. It's outside trading hours or it's a weekend."
# Define the main function
def main(preview_mode=True, strategy_name='example_strategy'):
# Set up logging
log_dir = os.path.join(os.path.dirname(__file__), 'logs')
os.makedirs(log_dir, exist_ok=True)
log_file = datetime.now().strftime('bot_log_%Y%m%d_%H%M%S.txt')
log_path = os.path.join(log_dir, log_file)
logging.basicConfig(filename=log_path, level=logging.DEBUG,
format='%(asctime)s %(levelname)s: %(message)s')
# Initialize a bot object with the retrieved credentials
bot = Bot(
consumer_key=consumer_key,
consumer_secret=consumer_secret,
web_username=web_username,
web_password=web_password,
account_id=account_id,
etrade_cookie=etrade_cookie,
strategy_name=strategy_name,
sandbox_key=sandbox_key,
sandbox_secret=sandbox_secret,
account_id_key=account_id_key,
dev=False, # Set to False for production, True for sandbox
headless=True, # Set to False to show browser window, True to hide
browser='chrome', # Set to 'chrome'
preview=preview_mode, # Set to False to execute trades, True to preview
prints=True, # Set to True to print information to console
)
# Run the strategy and log the output
market_open, reason = is_market_open()
if bot.preview or (not bot.preview and market_open):
logging.info('Starting bot...')
while True:
try:
bot.run()
break
except HTTPError as e:
print(e.response.text)
except HardToBorrowException as e:
ticker = e.ticker
bounds_df = pd.read_csv('data/bounds.csv')
if ticker not in bounds_df['TICKER'].values:
new_row = {'TICKER': ticker, 'MIN': 0.0, 'MAX': 1.0}
bounds_df = bounds_df.append(new_row, ignore_index=True)
bounds_df.to_csv('data/bounds.csv', index=False)
# continue the while loop to try running the bot again
continue
logging.info('Bot run complete.')
print('\nBot run complete.')
elif not bot.preview and not market_open:
logging.info(f"Bot not running because: {reason}")
print(f"\nBot not running because: {reason}")
if __name__ == '__main__':
main(
sys.argv[1].lower() == 'true' if len(sys.argv) > 1 else True,
sys.argv[2] if len(sys.argv) > 2 else 'example_strategy'
)