Trader-AngleOne 1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Trader_AngleOne/__init__.py +2 -0
- Trader_AngleOne/main.py +108 -0
- Trader_AngleOne/map_stock.py +1905 -0
- trader_angleone-1.3.dist-info/METADATA +109 -0
- trader_angleone-1.3.dist-info/RECORD +8 -0
- trader_angleone-1.3.dist-info/WHEEL +5 -0
- trader_angleone-1.3.dist-info/licenses/LICENSE +21 -0
- trader_angleone-1.3.dist-info/top_level.txt +1 -0
Trader_AngleOne/main.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import time
|
|
3
|
+
import pyotp
|
|
4
|
+
import logging
|
|
5
|
+
import contextlib
|
|
6
|
+
import pandas as pd
|
|
7
|
+
from .map_stock import stocklist
|
|
8
|
+
from SmartApi import SmartConnect
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TraderAngleOne:
|
|
14
|
+
def __init__(self, api_key, secret_key, totp, userid, pwd,**kwargs):
|
|
15
|
+
# Initialize API credentials
|
|
16
|
+
self.api_key = api_key
|
|
17
|
+
self.secret_key = secret_key
|
|
18
|
+
self.totp = totp
|
|
19
|
+
self.userid = userid
|
|
20
|
+
self.pwd = pwd
|
|
21
|
+
|
|
22
|
+
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
|
|
23
|
+
self.smartApi = SmartConnect(api_key=self.api_key)
|
|
24
|
+
|
|
25
|
+
print('\n',20*'-',"YOU ARE LOGIN",20*'-','\n')
|
|
26
|
+
self._generate_session()
|
|
27
|
+
|
|
28
|
+
self.TIMEFRAME_MAPPING = {
|
|
29
|
+
'1': "ONE_MINUTE",
|
|
30
|
+
'3': "THREE_MINUTE",
|
|
31
|
+
'5': "FIVE_MINUTE",
|
|
32
|
+
'10': "TEN_MINUTE",
|
|
33
|
+
'15': "FIFTEEN_MINUTE",
|
|
34
|
+
'30': "THIRTY_MINUTE",
|
|
35
|
+
"1H": "ONE_HOUR",
|
|
36
|
+
"1D": "ONE_DAY",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def _generate_session(self):
|
|
40
|
+
"""Generate a session with the API."""
|
|
41
|
+
data = self.smartApi.generateSession(self.userid, self.pwd, pyotp.TOTP(self.totp).now())
|
|
42
|
+
self.autoken = data['data']['jwtToken']
|
|
43
|
+
self.refreshToken = data['data']['refreshToken']
|
|
44
|
+
self.smartApi.getProfile(self.refreshToken)
|
|
45
|
+
self.feedtoken = self.smartApi.getfeedToken()
|
|
46
|
+
|
|
47
|
+
def _fetch_historical_data(self, symbol, interval, fromdate, todate,exchange='NSE', max_retries=3, retry_delay=1):
|
|
48
|
+
"""Helper function to fetch historical data with retry logic."""
|
|
49
|
+
token = stocklist.get(symbol)
|
|
50
|
+
if not token:
|
|
51
|
+
raise ValueError(f"Symbol {symbol} not found in stocklist.")
|
|
52
|
+
|
|
53
|
+
for attempt in range(max_retries):
|
|
54
|
+
try:
|
|
55
|
+
historicParam = {
|
|
56
|
+
"exchange": exchange,
|
|
57
|
+
"symboltoken": token,
|
|
58
|
+
"interval": self.TIMEFRAME_MAPPING.get(interval),
|
|
59
|
+
"fromdate": fromdate,
|
|
60
|
+
"todate": todate
|
|
61
|
+
}
|
|
62
|
+
response = self.smartApi.getCandleData(historicParam)
|
|
63
|
+
if not response or 'data' not in response or not response['data']:
|
|
64
|
+
raise ValueError("No data found in API response.")
|
|
65
|
+
|
|
66
|
+
historicalData = pd.DataFrame(response['data'])
|
|
67
|
+
if len(historicalData.columns) >= 6:
|
|
68
|
+
historicalData = historicalData.rename(columns={
|
|
69
|
+
0: "Datetime", # Assuming the first column is the timestamp
|
|
70
|
+
1: "o", # Open
|
|
71
|
+
2: "h", # High
|
|
72
|
+
3: "l", # Low
|
|
73
|
+
4: "c", # Close
|
|
74
|
+
5: "vol" # Volume
|
|
75
|
+
})
|
|
76
|
+
else:
|
|
77
|
+
raise ValueError("API response does not contain enough columns.")
|
|
78
|
+
|
|
79
|
+
historicalData["Datetime"] = pd.to_datetime(historicalData["Datetime"])
|
|
80
|
+
historicalData = historicalData.set_index('Datetime')
|
|
81
|
+
return historicalData
|
|
82
|
+
except Exception as e:
|
|
83
|
+
print(f"Attempt {attempt + 1} failed for {symbol}: {e}")
|
|
84
|
+
if attempt < max_retries - 1:
|
|
85
|
+
print(f"Retrying in {retry_delay} seconds...")
|
|
86
|
+
time.sleep(retry_delay)
|
|
87
|
+
else:
|
|
88
|
+
print(f"Max retries reached for {symbol}. Skipping this symbol.")
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
# angle.get_history_data(stockName,'5',f'2023-01-02 09:15',f'2023-01-02 15:30')
|
|
92
|
+
def get_history_data(self, symbol, interval, fromdate, todate,exchange="NSE"):
|
|
93
|
+
"""Get historical data for a specific period."""
|
|
94
|
+
ff = fromdate[:10]
|
|
95
|
+
to = todate[:10]
|
|
96
|
+
ff = datetime.strptime(ff, '%Y-%m-%d')
|
|
97
|
+
to = datetime.strptime(to, '%Y-%m-%d')
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if (ff > to) or (ff > datetime.strptime(datetime.now().strftime("%Y-%m-%d") + " 00:00:00", "%Y-%m-%d %H:%M:%S")):
|
|
101
|
+
print(f"Provided date {fromdate} is a holiday. Try for the next date.")
|
|
102
|
+
return None
|
|
103
|
+
|
|
104
|
+
return self._fetch_historical_data(symbol, interval, fromdate, todate,exchange)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|