tradermade 0.9.0__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.
Potentially problematic release.
This version of tradermade might be problematic. Click here for more details.
tradermade/__init__.py
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
import numpy as np
|
|
3
|
+
import requests
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
_api_key = None
|
|
7
|
+
_stats = {}
|
|
8
|
+
api_url = "https://marketdata.tradermade.com/api/v1/"
|
|
9
|
+
cfd_dict = {"UK100":"FTSE 100","GER30":"DAX 30","SPX500": "SP500","FRA40":"CAC 40", "JPN225":"Nikkei 225",
|
|
10
|
+
"NAS100":"Nasdaq", "USA30":"DOW 30", "HKG33":"Hang Seng", "AUS200":"ASX200","COPPER":"Copper","UKOIL":"Brent",
|
|
11
|
+
"OIL":"Nymex","NATGAS":"Natural GAS","AAPL":"Apple", "FB":"Facebook", "AMZN":"Amazon","NFLX":"Netflix",
|
|
12
|
+
"TSLA":"Tesla","GOOGL":"Alphabet", "BABA":"Alibaba", "TWTR":"Twitter","BAC":"Bank of America","BIDU":"Baidu"}
|
|
13
|
+
|
|
14
|
+
cfd_crct = {"UK100U":"UK100","GER30U":"GER30","FRA40U":"FRA40","USA30U":"USA30", "HKG33U":"HKG33","UKOILU":"UKOIL",
|
|
15
|
+
"OILUSD":"OIL","AAPLUS":"AAPL", "FBUSD":"FB", "AMZNUS":"AMZN","NFLXUS":"NFLX",
|
|
16
|
+
"TSLAUS":"TSLA","GOOGLU":"GOOGL", "BABAUS":"BABA", "TWTRUS":"TWTR","BACUSD":"BAC","BIDUUS":"BIDU"}
|
|
17
|
+
|
|
18
|
+
def set_rest_api_key(api_key):
|
|
19
|
+
global _api_key
|
|
20
|
+
_api_key = api_key
|
|
21
|
+
|
|
22
|
+
def api_key():
|
|
23
|
+
return _api_key
|
|
24
|
+
|
|
25
|
+
def get_stats():
|
|
26
|
+
try:
|
|
27
|
+
allowed = _stats["X-RateLimit-Limit"]
|
|
28
|
+
remaining = _stats["X-RateLimit-Remaining"]
|
|
29
|
+
resets = _stats["X-RateLimit-Reset"]
|
|
30
|
+
return {"allowance":allowed,"remaining": remaining,"resets":resets}
|
|
31
|
+
except:
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
def get_rest_api_key():
|
|
35
|
+
return api_key
|
|
36
|
+
|
|
37
|
+
def get_api_usage():
|
|
38
|
+
return usage
|
|
39
|
+
|
|
40
|
+
def currency_list():
|
|
41
|
+
if _api_key == None:
|
|
42
|
+
return "please set your apikey using function set_rest_api_key"
|
|
43
|
+
df = pd.read_json("https://marketdata.tradermade.com/api/v1/live_currencies_list?api_key="+_api_key)
|
|
44
|
+
df = df[["available_currencies"]]
|
|
45
|
+
df = df.reset_index()
|
|
46
|
+
return df
|
|
47
|
+
|
|
48
|
+
def cfd_list():
|
|
49
|
+
df = pd.DataFrame.from_dict(list(cfd_dict.items()),orient='columns', dtype=None, columns=None)
|
|
50
|
+
df = df.rename(columns={0:"index",1:"intrument"})
|
|
51
|
+
|
|
52
|
+
return df
|
|
53
|
+
|
|
54
|
+
def live(currency,fields=None):
|
|
55
|
+
if _api_key == None:
|
|
56
|
+
return "please set your apikey using function set_rest_api_key"
|
|
57
|
+
if type(fields) != type([]) and fields != None:
|
|
58
|
+
return {"error":"fields must be a list, ex ['bid','ask']"}
|
|
59
|
+
url = api_url+"live"
|
|
60
|
+
|
|
61
|
+
querystring = {"currency":currency,"api_key":_api_key}
|
|
62
|
+
|
|
63
|
+
response = requests.get(url, params=querystring)
|
|
64
|
+
#print(response.json())
|
|
65
|
+
column_list = ["instrument","timestamp"]
|
|
66
|
+
try:
|
|
67
|
+
df = pd.DataFrame(response.json()["quotes"])
|
|
68
|
+
except:
|
|
69
|
+
return response.json()
|
|
70
|
+
try:
|
|
71
|
+
df["instrument"] = np.where(df["base_currency"].isnull(),df["instrument"],df["base_currency"]+df["quote_currency"])
|
|
72
|
+
except:
|
|
73
|
+
try:
|
|
74
|
+
df["instrument"] = df["base_currency"]+df["quote_currency"]
|
|
75
|
+
except:
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
#df["instrument"] = df["base_currency"]+df["quote_currency"]
|
|
79
|
+
df["timestamp"] = response.json()["timestamp"]
|
|
80
|
+
df["timestamp"] = pd.to_datetime(df["timestamp"], unit="s")
|
|
81
|
+
|
|
82
|
+
global _stats
|
|
83
|
+
_stats = response.headers
|
|
84
|
+
|
|
85
|
+
if fields == None:
|
|
86
|
+
df = df[["instrument","timestamp","bid","mid","ask"]]
|
|
87
|
+
return df
|
|
88
|
+
else:
|
|
89
|
+
column_list = column_list+fields
|
|
90
|
+
df = df[column_list]
|
|
91
|
+
return df
|
|
92
|
+
|
|
93
|
+
def historical(currency, date, fields=None, interval='daily'):
|
|
94
|
+
if _api_key == None:
|
|
95
|
+
return "please set your apikey using function set_rest_api_key"
|
|
96
|
+
if type(fields) != type([]) and fields != None:
|
|
97
|
+
return {"error":"fields must be a list, ex ['close']"}
|
|
98
|
+
fx = currency.split(',')
|
|
99
|
+
if interval.lower() == 'daily':
|
|
100
|
+
freq = ''
|
|
101
|
+
array = []
|
|
102
|
+
else:
|
|
103
|
+
if interval == "hourly":
|
|
104
|
+
interval = "hour"
|
|
105
|
+
freq = interval+'_'
|
|
106
|
+
array = []
|
|
107
|
+
|
|
108
|
+
url = api_url+freq+'historical'
|
|
109
|
+
if interval.lower() != 'daily':
|
|
110
|
+
column_list = ["instrument","date_time"]
|
|
111
|
+
for i in fx:
|
|
112
|
+
querystring = {"currency":i,"date_time":date, "api_key":_api_key}
|
|
113
|
+
response = requests.get(url, params=querystring)
|
|
114
|
+
#print(response.json())
|
|
115
|
+
array.append(response.json())
|
|
116
|
+
try:
|
|
117
|
+
df = pd.DataFrame(array)
|
|
118
|
+
except:
|
|
119
|
+
return response.json()
|
|
120
|
+
try:
|
|
121
|
+
df["instrument"] = np.where(df["currency"].isnull(),df["instrument"],df["currency"])
|
|
122
|
+
except:
|
|
123
|
+
try:
|
|
124
|
+
df["instrument"] = df["currency"]
|
|
125
|
+
except:
|
|
126
|
+
pass
|
|
127
|
+
else:
|
|
128
|
+
column_list = ["instrument","date"]
|
|
129
|
+
for n, i in enumerate(fx):
|
|
130
|
+
if i.upper() in cfd_dict:
|
|
131
|
+
fx[n] = i+"USD"
|
|
132
|
+
currency = ",".join(fx)
|
|
133
|
+
querystring = {"currency":currency,"date":date,"api_key":_api_key}
|
|
134
|
+
response = requests.get(url, params=querystring)
|
|
135
|
+
# print(response.json())
|
|
136
|
+
if "error" in response.json()["quotes"][0]:
|
|
137
|
+
return response.json()["quotes"][0]
|
|
138
|
+
df = pd.DataFrame.from_dict(response.json()["quotes"], orient='columns', dtype=None, columns=None)
|
|
139
|
+
|
|
140
|
+
df["date"] = response.json()["date"]
|
|
141
|
+
df["date"] = pd.to_datetime(df["date"])
|
|
142
|
+
inst_list = []
|
|
143
|
+
for i in range(len(df)):
|
|
144
|
+
newcur = df.iloc[i]["base_currency"]+df.iloc[i]["quote_currency"]
|
|
145
|
+
|
|
146
|
+
if newcur in cfd_crct:
|
|
147
|
+
inst_list.append(cfd_crct[newcur])
|
|
148
|
+
else:
|
|
149
|
+
inst_list.append(newcur)
|
|
150
|
+
|
|
151
|
+
df["instrument"] = inst_list
|
|
152
|
+
|
|
153
|
+
global _stats
|
|
154
|
+
_stats = response.headers
|
|
155
|
+
if fields == None:
|
|
156
|
+
column_list=column_list+["open","high","low","close"]
|
|
157
|
+
df = df[column_list]
|
|
158
|
+
return df
|
|
159
|
+
else:
|
|
160
|
+
column_list = column_list+fields
|
|
161
|
+
df = df[column_list]
|
|
162
|
+
return df
|
|
163
|
+
|
|
164
|
+
def timeseries(currency, start, end, fields=None, interval='daily', period=15):
|
|
165
|
+
if _api_key == None:
|
|
166
|
+
return "please set your apikey using function set_rest_api_key"
|
|
167
|
+
fx = currency.split(',')
|
|
168
|
+
if type(fields) != type([]) and fields != None:
|
|
169
|
+
return {"error":"fields must be a list, ex ['close']"}
|
|
170
|
+
else:
|
|
171
|
+
if fields != ["close"] and len(fx) > 1:
|
|
172
|
+
return {"error":"fields must be ['close'] when selecting multiple pairs"}
|
|
173
|
+
array = []
|
|
174
|
+
|
|
175
|
+
format = "split"
|
|
176
|
+
dataframe = []
|
|
177
|
+
url = api_url+"timeseries"
|
|
178
|
+
|
|
179
|
+
if len(fx) > 1:
|
|
180
|
+
dataframe = []
|
|
181
|
+
#column_list = ["instrument","date_time"]
|
|
182
|
+
for number, i in enumerate(fx):
|
|
183
|
+
querystring = {"currency":i,"api_key":_api_key, "start_date":start,
|
|
184
|
+
"interval":interval, "end_date":end, "period":period, "format":format}
|
|
185
|
+
response = requests.get(url, params=querystring)
|
|
186
|
+
try:
|
|
187
|
+
df = pd.DataFrame(response.json())
|
|
188
|
+
except:
|
|
189
|
+
return response.json()
|
|
190
|
+
df = pd.DataFrame(df.quotes['data'], columns=df.quotes['columns'])
|
|
191
|
+
df = df.set_index('date')
|
|
192
|
+
df = df.rename(columns={"close": i})
|
|
193
|
+
if number == 0:
|
|
194
|
+
hf = df[i]
|
|
195
|
+
else:
|
|
196
|
+
hf = pd.merge(hf,df[i], on="date",how='outer')
|
|
197
|
+
df = hf.reset_index()
|
|
198
|
+
df['date'] = pd.to_datetime(df['date'])
|
|
199
|
+
df = df.sort_values(by='date')
|
|
200
|
+
else:
|
|
201
|
+
#column_list = ["instrument","date"]
|
|
202
|
+
querystring = {"currency":currency,"api_key":_api_key, "start_date":start,
|
|
203
|
+
"interval":interval, "end_date":end, "period":period, "format":format}
|
|
204
|
+
|
|
205
|
+
response = requests.get(url, params=querystring)
|
|
206
|
+
try:
|
|
207
|
+
df = pd.DataFrame(response.json())
|
|
208
|
+
except:
|
|
209
|
+
return response.json()
|
|
210
|
+
df = pd.DataFrame(df.quotes['data'], columns=df.quotes['columns'])
|
|
211
|
+
|
|
212
|
+
global _stats
|
|
213
|
+
_stats = response.headers
|
|
214
|
+
if fields == None:
|
|
215
|
+
return df
|
|
216
|
+
else:
|
|
217
|
+
if len(fx) > 1:
|
|
218
|
+
return df
|
|
219
|
+
else:
|
|
220
|
+
column_list = ["date"]+fields
|
|
221
|
+
df = df[column_list]
|
|
222
|
+
return df
|
|
223
|
+
|
|
224
|
+
|
tradermade/stream.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import websocket
|
|
2
|
+
import tradermade
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
import _thread as thread
|
|
6
|
+
except ImportError:
|
|
7
|
+
import threading as thread
|
|
8
|
+
|
|
9
|
+
ws = None
|
|
10
|
+
_api_key = None
|
|
11
|
+
_symbol = 'GBPUSD'
|
|
12
|
+
message_callback = None # Added callback variable
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def set_ws_key(api_key):
|
|
16
|
+
global _api_key
|
|
17
|
+
_api_key = api_key
|
|
18
|
+
|
|
19
|
+
def set_symbols(symbol):
|
|
20
|
+
global _symbol
|
|
21
|
+
_symbol = symbol
|
|
22
|
+
|
|
23
|
+
def stream_data(callback):
|
|
24
|
+
global message_callback
|
|
25
|
+
message_callback = callback
|
|
26
|
+
|
|
27
|
+
def get_symbols():
|
|
28
|
+
return _symbol
|
|
29
|
+
|
|
30
|
+
def api_key():
|
|
31
|
+
return _api_key
|
|
32
|
+
|
|
33
|
+
def on_message(ws, message):
|
|
34
|
+
|
|
35
|
+
# Call the callback function with the received message
|
|
36
|
+
if message_callback:
|
|
37
|
+
message_callback(message)
|
|
38
|
+
|
|
39
|
+
def on_error(ws, error):
|
|
40
|
+
print(error)
|
|
41
|
+
|
|
42
|
+
def on_close(ws, close_status_code, close_msg):
|
|
43
|
+
print("### closed ###")
|
|
44
|
+
|
|
45
|
+
def on_open(ws):
|
|
46
|
+
def run(*args):
|
|
47
|
+
cred = '{"userKey":"' + _api_key + '", "symbol":"' + _symbol + '"}'
|
|
48
|
+
ws.send(cred)
|
|
49
|
+
thread.start_new_thread(run, ())
|
|
50
|
+
|
|
51
|
+
def connect():
|
|
52
|
+
global ws
|
|
53
|
+
ws = websocket.WebSocketApp("wss://marketdata.tradermade.com/feedadv",
|
|
54
|
+
on_message=on_message,
|
|
55
|
+
on_error=on_error,
|
|
56
|
+
on_close=on_close)
|
|
57
|
+
ws.on_open = on_open
|
|
58
|
+
ws.run_forever()
|
|
59
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: tradermade
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: A package that helps you get Forex data from TraderMade data API
|
|
5
|
+
Home-page: https://github.com/tradermade
|
|
6
|
+
Author: TraderMade
|
|
7
|
+
Author-email: support@tradermade.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Platform: UNKNOWN
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Requires-Dist: numpy
|
|
16
|
+
Requires-Dist: pandas
|
|
17
|
+
Requires-Dist: requests
|
|
18
|
+
Requires-Dist: websockets
|
|
19
|
+
|
|
20
|
+
tradermade SDK
|
|
21
|
+
==============
|
|
22
|
+
|
|
23
|
+
tradermade is Python SDK for getting forex data via REST API or
|
|
24
|
+
Websocket.
|
|
25
|
+
|
|
26
|
+
Installation
|
|
27
|
+
------------
|
|
28
|
+
|
|
29
|
+
Use the package manager `pip`_ to install foobar.
|
|
30
|
+
|
|
31
|
+
.. code:: bash
|
|
32
|
+
|
|
33
|
+
pip install tradermade
|
|
34
|
+
|
|
35
|
+
Get API key by signing up for `free`_
|
|
36
|
+
|
|
37
|
+
Usage
|
|
38
|
+
-----
|
|
39
|
+
|
|
40
|
+
REST API
|
|
41
|
+
~~~~~~~~
|
|
42
|
+
|
|
43
|
+
.. code:: python
|
|
44
|
+
|
|
45
|
+
import tradermade as tm
|
|
46
|
+
|
|
47
|
+
# set api key
|
|
48
|
+
tm.set_rest_api_key(api_key)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
tm.live(currency='EURUSD,GBPUSD',fields=["bid", "mid", "ask"]) # returns live data - fields is optional
|
|
52
|
+
|
|
53
|
+
tm.historical(currency='EURUSD,GBPUSD', date="2021-04-22",interval="daily", fields=["open", "high", "low","close"]) # returns historical data for the currency requested interval is daily, hourly, minute - fields is optional
|
|
54
|
+
|
|
55
|
+
tm.timeseries(currency='EURUSD', start="2021-04-20",end="2021-04-22",interval="hourly",fields=["open", "high", "low","close"]) # returns timeseries data for the currency requested interval is daily, hourly, minute - fields is optional
|
|
56
|
+
|
|
57
|
+
tm.cfd_list() # gets list of all cfds available
|
|
58
|
+
|
|
59
|
+
tm.currency_list() # gets list of all currency codes available add two codes to get code for currencypair ex EUR + USD gets EURUSD
|
|
60
|
+
|
|
61
|
+
Streaming Data
|
|
62
|
+
~~~~~~~~~~~~~~
|
|
63
|
+
|
|
64
|
+
.. code:: python
|
|
65
|
+
|
|
66
|
+
from tradermade import stream
|
|
67
|
+
|
|
68
|
+
def print_message(data):
|
|
69
|
+
print(f"Received: {data}")
|
|
70
|
+
|
|
71
|
+
api_key = "api_key"
|
|
72
|
+
|
|
73
|
+
# set streaming key - not the same as rest API key
|
|
74
|
+
stream.set_ws_key(api_key)
|
|
75
|
+
|
|
76
|
+
stream.set_symbols("USDJPY,EURGBP")
|
|
77
|
+
|
|
78
|
+
# Set the callback for receiving messages
|
|
79
|
+
stream.stream_data(print_message)
|
|
80
|
+
|
|
81
|
+
stream.connect()
|
|
82
|
+
|
|
83
|
+
Contributing
|
|
84
|
+
------------
|
|
85
|
+
|
|
86
|
+
For changes, please open an issue to discuss what you would like to
|
|
87
|
+
change.
|
|
88
|
+
|
|
89
|
+
License
|
|
90
|
+
-------
|
|
91
|
+
|
|
92
|
+
`MIT`_
|
|
93
|
+
|
|
94
|
+
.. _pip: https://pip.pypa.io/en/stable/
|
|
95
|
+
.. _free: https://marketdata.tradermade.com/signup
|
|
96
|
+
.. _MIT: https://choosealicense.com/licenses/mit/
|
|
97
|
+
|
|
98
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
tradermade/__init__.py,sha256=II-JfiVU94rdFmsmvqXgFkWCOFilRqOMcRBgttkNbLo,7381
|
|
2
|
+
tradermade/stream.py,sha256=JAUzSgPnXiK2nLJLwHvp01nZmj4FzyVDj6ySBvGlJpA,1272
|
|
3
|
+
tradermade-0.9.0.dist-info/METADATA,sha256=hgLTRU9EJew590uoqOx7kRZ56BBlwc7YW4kOiDKiekM,2426
|
|
4
|
+
tradermade-0.9.0.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
|
5
|
+
tradermade-0.9.0.dist-info/top_level.txt,sha256=EmR7fXnfSMEwG75_DEtILWs0riLZ9uKkcV7rVKKVw3c,11
|
|
6
|
+
tradermade-0.9.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tradermade
|