-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconnection.py
More file actions
139 lines (122 loc) · 4.69 KB
/
Copy pathconnection.py
File metadata and controls
139 lines (122 loc) · 4.69 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import alpaca_trade_api as tradeapi
import logging
from config import (
ALPACA_API_KEY,
ALPACA_SECRET_KEY,
ALPACA_PAPER,
LOG_LEVEL,
LOG_FILE
)
# Configure logging
logging.basicConfig(
level=getattr(logging, LOG_LEVEL),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler(LOG_FILE),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
class AlpacaConnection:
def __init__(self):
self.api = None
self.connected = False
def connect(self):
"""Establish connection to Alpaca API"""
try:
if not self.connected:
if not ALPACA_API_KEY or not ALPACA_SECRET_KEY:
raise ValueError("Alpaca API keys not found in environment variables")
# Set the base URL based on paper trading setting
base_url = 'https://paper-api.alpaca.markets' if ALPACA_PAPER else 'https://api.alpaca.markets'
# Initialize the API
self.api = tradeapi.REST(
ALPACA_API_KEY,
ALPACA_SECRET_KEY,
base_url=base_url
)
# Test the connection
self.api.get_account()
self.connected = True
logger.info(f"Successfully connected to Alpaca {'Paper' if ALPACA_PAPER else 'Live'} Trading")
return True
except Exception as e:
logger.error(f"Failed to connect to Alpaca: {str(e)}")
return False
def disconnect(self):
"""Disconnect from Alpaca API"""
try:
if self.connected:
self.api = None
self.connected = False
logger.info("Disconnected from Alpaca")
except Exception as e:
logger.error(f"Error disconnecting from Alpaca: {str(e)}")
def get_account_info(self):
"""Get account information"""
try:
if not self.is_connected():
logger.error("Not connected to Alpaca")
return None
account = self.api.get_account()
return {
'cash': float(account.cash),
'portfolio_value': float(account.portfolio_value),
'buying_power': float(account.buying_power),
'equity': float(account.equity),
'long_market_value': float(account.long_market_value),
'short_market_value': float(account.short_market_value),
'initial_margin': float(account.initial_margin),
'maintenance_margin': float(account.maintenance_margin),
'last_equity': float(account.last_equity),
'status': account.status
}
except Exception as e:
logger.error(f"Error getting account info: {str(e)}")
return None
def get_positions(self):
"""Get current positions"""
try:
if not self.is_connected():
logger.error("Not connected to Alpaca")
return None
positions = self.api.list_positions()
return [{
'symbol': pos.symbol,
'qty': float(pos.qty),
'avg_entry_price': float(pos.avg_entry_price),
'current_price': float(pos.current_price),
'market_value': float(pos.market_value),
'unrealized_pl': float(pos.unrealized_pl),
'unrealized_plpc': float(pos.unrealized_plpc)
} for pos in positions]
except Exception as e:
logger.error(f"Error getting positions: {str(e)}")
return None
def is_connected(self):
"""Check if connected to Alpaca"""
return self.connected and self.api is not None
def is_market_open(self):
"""Check if the market is currently open"""
try:
if not self.is_connected():
return False
clock = self.api.get_clock()
return clock.is_open
except Exception as e:
logger.error(f"Error checking market status: {str(e)}")
return False
def get_market_status(self):
"""Get detailed market status"""
try:
if not self.is_connected():
return None
clock = self.api.get_clock()
return {
'is_open': clock.is_open,
'next_open': clock.next_open,
'next_close': clock.next_close
}
except Exception as e:
logger.error(f"Error getting market status: {str(e)}")
return None