tradermade-sdk-nodejs 1.0.0
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.
- package/README.md +113 -0
- package/index.js +218 -0
- package/lib/tradermade.js +6 -0
- package/package.json +36 -0
- package/src/client.js +34 -0
- package/src/constants.js +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# TraderMade Node.js SDK
|
|
2
|
+
|
|
3
|
+
Official Node.js client library for the TraderMade Data API.
|
|
4
|
+
|
|
5
|
+
## 🚀 Installation
|
|
6
|
+
|
|
7
|
+
Install the package via npm:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install tradermade-sdk-nodejs
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 🔑 Getting Started
|
|
15
|
+
|
|
16
|
+
First, import the library and initialize the client with your API key.
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
import TraderMade from 'tradermade-sdk-nodejs';
|
|
20
|
+
|
|
21
|
+
const tm = new TraderMade();
|
|
22
|
+
tm.setRestApiKey(process.env.TRADERMADE_API_KEY);
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 📚 Usage Examples
|
|
29
|
+
|
|
30
|
+
After creating the client, making calls to the TraderMade API is easy. Below are examples for fetching different types of market data.
|
|
31
|
+
|
|
32
|
+
### 1. Get Historical Tick Data
|
|
33
|
+
|
|
34
|
+
Fetch raw tick data for a specific currency pair and time range.
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
import TraderMade from 'tradermade-nodejs-sdk';
|
|
38
|
+
|
|
39
|
+
const tm = new TraderMade();
|
|
40
|
+
tm.setRestApiKey(process.env.TRADERMADE_API_KEY);
|
|
41
|
+
|
|
42
|
+
async function example_GetHistoricalTickData() {
|
|
43
|
+
try {
|
|
44
|
+
const data = await tm.getHistoricalTickData(
|
|
45
|
+
"GBPUSD",
|
|
46
|
+
"2026-01-12 15:00",
|
|
47
|
+
"2026-01-12 15:30"
|
|
48
|
+
);
|
|
49
|
+
console.log(data);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
example_GetHistoricalTickData();
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. Get Minute Historical Data
|
|
60
|
+
|
|
61
|
+
Retrieve OHLC (Open, High, Low, Close) data for a specific minute.
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
import TraderMade from 'tradermade-nodejs-sdk';
|
|
65
|
+
|
|
66
|
+
const tm = new TraderMade();
|
|
67
|
+
tm.setRestApiKey(process.env.TRADERMADE_API_KEY);
|
|
68
|
+
|
|
69
|
+
async function example_GetMinuteHistoricalData() {
|
|
70
|
+
try {
|
|
71
|
+
const data = await tm.getMinuteHistoricalData(
|
|
72
|
+
"2019-10-10-13:24",
|
|
73
|
+
"EURUSD"
|
|
74
|
+
);
|
|
75
|
+
console.log(data);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
example_GetMinuteHistoricalData();
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 3. Get Time Series Data
|
|
86
|
+
|
|
87
|
+
Fetch daily time series data for analysis.
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
import TraderMade from 'tradermade-nodejs-sdk';
|
|
91
|
+
|
|
92
|
+
const tm = new TraderMade();
|
|
93
|
+
tm.setRestApiKey(process.env.TRADERMADE_API_KEY);
|
|
94
|
+
|
|
95
|
+
async function example_GetTimeSeriesData() {
|
|
96
|
+
try {
|
|
97
|
+
const data = await tm.getTimeSeriesData(
|
|
98
|
+
"EURUSD",
|
|
99
|
+
"2026-01-08",
|
|
100
|
+
"2026-01-10",
|
|
101
|
+
"daily",
|
|
102
|
+
"1",
|
|
103
|
+
"records"
|
|
104
|
+
);
|
|
105
|
+
console.log(data);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
console.error(error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
example_GetTimeSeriesData();
|
|
112
|
+
|
|
113
|
+
```
|
package/index.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { Client } from "./src/client.js";
|
|
3
|
+
import {
|
|
4
|
+
TIME_SERIES_FORMAT,
|
|
5
|
+
TIME_SERIES_INTERVAL,
|
|
6
|
+
TIME_SERIES_PERIOD,
|
|
7
|
+
DATA_EXPORTS_PANDAS_DF_FIELDS,
|
|
8
|
+
DATA_EXPORTS_PANDAS_DF_FORMAT,
|
|
9
|
+
} from "./src/constants.js";
|
|
10
|
+
|
|
11
|
+
class TraderMade {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.apiKey = null;
|
|
14
|
+
this.client = null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
_validateApiKey(apiKey) {
|
|
18
|
+
if (typeof apiKey !== "string" || apiKey.trim() === "") {
|
|
19
|
+
throw new Error("Api key must be a non empty string.");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//Set Rest api key
|
|
24
|
+
setRestApiKey(apiKey) {
|
|
25
|
+
this._validateApiKey(apiKey);
|
|
26
|
+
this.apiKey = apiKey;
|
|
27
|
+
this.client = new Client(apiKey);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//Get Rest api key
|
|
31
|
+
getRestApiKey() {
|
|
32
|
+
return this.apiKey;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//Get Live Exchange Rates​
|
|
36
|
+
async getLiveExchangeRates() {
|
|
37
|
+
const data = await this.client.get("/live");
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//Get List of Live Currencies​
|
|
42
|
+
async getLiveCurrencyList() {
|
|
43
|
+
const data = await this.client.get("/live_currencies_list");
|
|
44
|
+
return data;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//Get List of Streaming Instruments​
|
|
48
|
+
async getStreamCurrencyList() {
|
|
49
|
+
const data = await this.client.get("/streaming_currencies_list");
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//Get List of Live Cryptocurrencies​
|
|
54
|
+
async getCryptoList() {
|
|
55
|
+
const data = await this.client.get("/live_crypto_list");
|
|
56
|
+
return data;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//Get List of Historical Currencies​
|
|
60
|
+
async getHistoricalCurrencyList() {
|
|
61
|
+
const data = await this.client.get("/historical_currencies_list");
|
|
62
|
+
return data;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//Get List of Available CFDs​
|
|
66
|
+
async getCfdList() {
|
|
67
|
+
const data = await this.client.get("/cfd_list");
|
|
68
|
+
return data;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
//Get Historical Exchange Rates​
|
|
72
|
+
async getHistoricalExchangeRates(date, currency) {
|
|
73
|
+
if (!date || !currency) {
|
|
74
|
+
throw new Error("date_time,currency are required.");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const data = await this.client.get("/historical", {
|
|
78
|
+
currency,
|
|
79
|
+
date,
|
|
80
|
+
});
|
|
81
|
+
return data;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//Get Hourly Historical Data​
|
|
85
|
+
async getHourlyHistoricalData(date_time, currency) {
|
|
86
|
+
if (!date_time || !currency) {
|
|
87
|
+
throw new Error("date_time,currency are required.");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const data = await this.client.get("/hour_historical", {
|
|
91
|
+
date_time,
|
|
92
|
+
currency,
|
|
93
|
+
});
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//Get Minute Historical Data​
|
|
98
|
+
async getMinuteHistoricalData(date_time, currency) {
|
|
99
|
+
if (!date_time || !currency) {
|
|
100
|
+
throw new Error("date_time,currency are required.");
|
|
101
|
+
}
|
|
102
|
+
const data = await this.client.get("/minute_historical", {
|
|
103
|
+
date_time,
|
|
104
|
+
currency,
|
|
105
|
+
});
|
|
106
|
+
return data;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//Get Historical Tick Data​
|
|
110
|
+
async getHistoricalTickData(symbol, startDate, endDate) {
|
|
111
|
+
if (!symbol || !startDate || !endDate) {
|
|
112
|
+
throw new Error("symbol, startDate and endDate are required.");
|
|
113
|
+
}
|
|
114
|
+
const start = encodeURIComponent(startDate);
|
|
115
|
+
const end = encodeURIComponent(endDate);
|
|
116
|
+
const data = await this.client.get(
|
|
117
|
+
`/tick_historical/${symbol}/${start}/${end}`,
|
|
118
|
+
{ format: "json" }
|
|
119
|
+
);
|
|
120
|
+
return data;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async getHistoricalTickDataSample(symbol, startDate, endDate) {
|
|
124
|
+
if (!symbol || !startDate || !endDate) {
|
|
125
|
+
throw new Error("Symbol,startDateTime and endDateTime are required.");
|
|
126
|
+
}
|
|
127
|
+
const startDateAndTime = encodeURIComponent(startDate);
|
|
128
|
+
const endDateAndTime = encodeURIComponent(endDate);
|
|
129
|
+
const data = await this.client.get(
|
|
130
|
+
`/tick_historical_sample/${symbol}/${startDateAndTime}/${endDateAndTime}`,
|
|
131
|
+
{ format: "json" }
|
|
132
|
+
);
|
|
133
|
+
return data;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
//Get Time Series Data
|
|
137
|
+
async getTimeSeriesData(
|
|
138
|
+
currency,
|
|
139
|
+
startDate,
|
|
140
|
+
endDate,
|
|
141
|
+
interval,
|
|
142
|
+
period,
|
|
143
|
+
format
|
|
144
|
+
) {
|
|
145
|
+
if (!TIME_SERIES_FORMAT.includes(format)) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
`Invalid format.Please use one of : ${TIME_SERIES_FORMAT}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
if (!TIME_SERIES_INTERVAL.includes(interval)) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Invalid interval.Please use one of : ${TIME_SERIES_INTERVAL}`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
const periodNum = Number(period);
|
|
156
|
+
if (!TIME_SERIES_PERIOD[interval]?.includes(periodNum)) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Invalid period.Please use one of : ${TIME_SERIES_PERIOD[interval].join(
|
|
159
|
+
", "
|
|
160
|
+
)} `
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
const data = await this.client.get("/timeseries", {
|
|
164
|
+
currency,
|
|
165
|
+
start_date: startDate,
|
|
166
|
+
end_date: endDate,
|
|
167
|
+
interval,
|
|
168
|
+
period: periodNum,
|
|
169
|
+
format,
|
|
170
|
+
});
|
|
171
|
+
return data;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
//Get Market Open Status
|
|
175
|
+
async getOpenMarketStatus() {
|
|
176
|
+
const data = await this.client.get("/market_open_status");
|
|
177
|
+
return data;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//Get Market Opening Times
|
|
181
|
+
async getMarketOpenTiming() {
|
|
182
|
+
const data = await this.client.get("/market_opening_times");
|
|
183
|
+
return data;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
//Convert Currency Amount
|
|
187
|
+
async getConvertCurrencyAmount(from, to, amount) {
|
|
188
|
+
const data = await this.client.get("/convert", {
|
|
189
|
+
from,
|
|
190
|
+
to,
|
|
191
|
+
amount,
|
|
192
|
+
});
|
|
193
|
+
return data;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
//Get Data as Pandas DataFrame
|
|
197
|
+
async getDataAsPandasDataFrame(currency, startDate, endDate, format, fields) {
|
|
198
|
+
if (!DATA_EXPORTS_PANDAS_DF_FORMAT.includes(format)) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Invalid format.Please use one of : ${DATA_EXPORTS_PANDAS_DF_FORMAT}`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (!DATA_EXPORTS_PANDAS_DF_FIELDS.includes(fields)) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
`Invalid format.Please use one of : ${DATA_EXPORTS_PANDAS_DF_FIELDS}`
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
const data = await this.client.get("/pandasDF", {
|
|
209
|
+
currency,
|
|
210
|
+
start_date: startDate,
|
|
211
|
+
end_date: endDate,
|
|
212
|
+
format,
|
|
213
|
+
fields,
|
|
214
|
+
});
|
|
215
|
+
return data;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export default TraderMade;
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tradermade-sdk-nodejs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official TRADERMADE Node.js SDK",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node index.js",
|
|
8
|
+
"test": "node tests/test.js"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "",
|
|
12
|
+
"url": ""
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"tardermade.com",
|
|
16
|
+
"forex api",
|
|
17
|
+
"crypto api",
|
|
18
|
+
"api",
|
|
19
|
+
"sdk"
|
|
20
|
+
],
|
|
21
|
+
"contributors": [
|
|
22
|
+
{
|
|
23
|
+
"name": "TraderMade Support",
|
|
24
|
+
"email": "support@tradermade.com"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"type": "module",
|
|
30
|
+
"homepage": "",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"axios": "^1.13.2",
|
|
33
|
+
"dotenv": "^17.2.3",
|
|
34
|
+
"tradermade-nodejs-sdk": "^1.0.0"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/client.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { DEFAULT_BASE_URL } from "./constants.js"
|
|
3
|
+
|
|
4
|
+
export class Client{
|
|
5
|
+
constructor(apiKey)
|
|
6
|
+
{
|
|
7
|
+
this.apiKey = apiKey;
|
|
8
|
+
this.api = axios.create({
|
|
9
|
+
baseURL: DEFAULT_BASE_URL,
|
|
10
|
+
params:{ api_key : apiKey}
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async get(endpoint, queryParams={})
|
|
15
|
+
{
|
|
16
|
+
try {
|
|
17
|
+
const response = await this.api.get(endpoint,{params:queryParams});
|
|
18
|
+
return response.data
|
|
19
|
+
} catch (error) {
|
|
20
|
+
this._handleError(error)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
_handleError(error) {
|
|
25
|
+
if (error.response) {
|
|
26
|
+
const message = error.response.data?.message || error.response.statusText;
|
|
27
|
+
throw new Error(`API Error ${error.response.status}: ${message}`);
|
|
28
|
+
} else if (error.request) {
|
|
29
|
+
throw new Error("Network Error: No response received from server. Please check your internet connection.");
|
|
30
|
+
} else {
|
|
31
|
+
throw new Error(`Request Setup Error: ${error.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//Base url https://marketdata.tradermade.com/api/v1
|
|
2
|
+
export const DEFAULT_BASE_URL = "https://marketdata.tradermade.com/api/v1";
|
|
3
|
+
|
|
4
|
+
export const TIME_SERIES_FORMAT = ["records","csv","index","columns","split"];
|
|
5
|
+
export const TIME_SERIES_INTERVAL = ["daily","hourly","minute"];
|
|
6
|
+
export const TIME_SERIES_PERIOD = {
|
|
7
|
+
"daily": [1],
|
|
8
|
+
"hourly":[1,2,4,6,8,24],
|
|
9
|
+
"minute":[1,5,10,15,30]
|
|
10
|
+
};
|
|
11
|
+
export const DATA_EXPORTS_PANDAS_DF_FIELDS = ["close","ohlc"];
|
|
12
|
+
export const DATA_EXPORTS_PANDAS_DF_FORMAT = ["records","columns","index","split"];
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|