initial load

This commit is contained in:
artin 2023-07-11 11:45:37 +00:00
parent 8d8dd61dbf
commit d1d902f91a
2 changed files with 371 additions and 0 deletions

354
index.js Normal file
View File

@ -0,0 +1,354 @@
const express = require('express')
var cors = require('cors')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')
const app = express()
const port = 3000
const host = "0.0.0.0"
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })
app.use(morgan('combined', { stream: accessLogStream }))
const axios = require('axios').default;
const APIURL = 'https://api-fxpractice.oanda.com/v3'
const accounts = {
'1': {
'ACCT': '101-001-8005237-001',
'APIKEY': '85397a3ddc7b96ef57b90c9feda6d410-18f0f2b634f9f05533d2c20046bb79df'
},
'2': {
'APIKEY': 'b954456a3f4ac735de2555e1af50abf7-ed83ace2f9fb86412b76608daefc73a5',
'ACCT': '101-001-23367262-002'
},
'3': {
'APIKEY': 'd4ea6095fe8017841279416437520aee-fa23a0556fb501520ceedbff5f405267',
'ACCT': '101-002-26241098-001'
}
}
async function getTrades(acct_id, api_key) {
try {
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/openTrades`,
method: 'get',
headers: {
'Authorization': `Bearer ${api_key}`
}
});
return (response)
} catch (error) {
console.error(error);
}
}
async function getTradesByInstrument(acct_id, api_key, instrument) {
try {
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/trades?instrument=${instrument}`,
method: 'get',
headers: {
'Authorization': `Bearer ${api_key}`
}
});
console.log(response)
if (response.data.trades.length == 0) {
return
} else {
return (response.data.trades[0])
}
} catch (error) {
console.error(error);
}
}
async function getPositions(acct_id, api_key) {
try {
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/openPositions`,
method: 'get',
headers: {
'Authorization': `Bearer ${api_key}`
}
});
return (response);
} catch (error) {
console.error(error);
}
}
async function order(acct_id, api_key, instrument, quantity) {
try {
let dist = "0.005"
let pdist = "0.005"
if (instrument.includes("JPY")) {
dist = "0.5"
pdist = "0.5"
}
data = {
"order": {
"trailingStopLossOnFill": {
"timeInForce": "GTC",
"distance": dist
},
/*"takeProfitOnFill": {
"distance": pdist
},*/
"timeInForce": "FOK",
"instrument": instrument,
"units": quantity,
"type": "MARKET",
"positionFill": "DEFAULT"
}
};
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/orders`,
method: 'post',
headers: {
'Authorization': `Bearer ${api_key}`
},
data: data
});
console.log(data)
return (response)
/*try {
delta = response.data.orderFillTransaction.price * .00164;
price = response.data.orderFillTransaction.price;
units = response.data.orderFillTransaction.units;
pres = price.toString().split('.')[1].length
if (units > 0) {
price = price - delta;
} else {
price = price + delta
}
return await stopLoss(acct_id, api_key, response.data.orderFillTransaction.id, Number(price).toFixed(pres).toString())
} catch (error) {
console.log(error)
return (error)
}*/
} catch (error) {
console.error(error);
}
}
async function closeOrder(acct_id, api_key, tradeID) {
try {
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/trades/${tradeID}/close`,
method: 'put',
headers: {
'Authorization': `Bearer ${api_key}`
},
});
console.log(response.data);
return (response);
} catch (error) {
console.error(error);
}
}
async function trailingStopLoss(acct_id, api_key, instrument) {
const trade = await getTradesByInstrument(acct_id, api_key, instrument)
const tradeID = trade.id;
console.log(tradeID);
if (!tradeID) {
return
}
dist = "0.00164"
if (instrument.includes("JPY")) {
dist = "0.16"
}
try {
data = {
"trailingStopLoss": {
"timeInForce": "GTC",
"distance": dist
}
};
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/trades/${tradeID}/orders`,
method: 'put',
headers: {
'Authorization': `Bearer ${api_key}`
},
data: data
});
console.log(data)
console.log(response.data);
return (response);
} catch (error) {
console.error(error);
}
}
async function stopLoss(acct_id, api_key, tradeID, price) {
try {
data = {
"stopLoss": {
"timeInForce": "GTC",
"distance": "0.30"
//"price": price
}
};
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/trades/${tradeID}/orders`,
method: 'put',
headers: {
'Authorization': `Bearer ${api_key}`
},
data: data
});
console.log(data)
console.log(response.data);
return (response);
} catch (error) {
console.error(error);
}
}
async function takeProfit(acct_id, api_key, tradeID, dist) {
try {
data = {
"takeProfit": {
"timeInForce": "GTC",
"distance": dist
}
};
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/trades/${tradeID}/orders`,
method: 'put',
headers: {
'Authorization': `Bearer ${api_key}`
},
data: data
});
return (response);
} catch (error) {
console.error(error);
}
}
app.get('/closeAll', async (req, res) => {
for (account of Object.keys(accounts)) {
let trades = await getTrades(accounts[account]['ACCT'], accounts[account]['APIKEY'])
for (const t of trades.data['trades']) {
await closeOrder(accounts[account]['ACCT'], accounts[account]['APIKEY'], t['id'])
}
}
res.json('done')
})
app.get('/tradesData', async (req, res) => {
let r = [];
for (account of Object.keys(accounts)) {
let response = await getTrades(accounts[account]['ACCT'], accounts[account]['APIKEY'])
try {
//Object.(response.data['trades']).forEach(([a, t]) =>{
response.data['trades'].forEach(( t) =>{
t["Account"] = account;
delete t['lastTransactionID'];
delete t['trailingStopLossOrder'];
console.log(t);
r.push(t)
});
} catch(error) {
console.log(error)
}
}
res.header('Access-Control-Allow-Origin', '*')
res.json(r)
})
app.get('/trades', async (req, res) => {
let r = {}
for (account of Object.keys(accounts)) {
let response = await getTrades(accounts[account]['ACCT'], accounts[account]['APIKEY'])
try {
r[account] = response.data;
} catch(error) {
console.log(error)
}
}
res.header('Access-Control-Allow-Origin', '*')
res.json(r)
})
app.get('/trailingStop/:instrument', async (req, res) => {
const response = await trailingStopLoss(ACCT, APIKEY, req.params.instrument);
console.log(response);
res.header('Access-Control-Allow-Origin', '*')
res.json(response.data)
})
app.get('/tradesByInstrument/:instrument', async (req, res) => {
res.header('Access-Control-Allow-Origin', '*')
res.json(await getTradesByInstrument(ACCT, APIKEY, req.params.instrument))
})
app.get('/order/:instrument/:quantity', async (req, res) => {
r = {};
/*td = await getTradesByInstrument(accounts['1']['ACCT'], accounts['1']['APIKEY'], req.params.instrument);
if (td) {
if (td["initialUnits"] != req.params.quantity) {
let dist = "0.005"
if (req.params.instrument.includes("JPY")) {
let dist = "0.5"
}
await takeProfit(accounts['1']['ACCT'], accounts['1']['APIKEY'], td["id"], dist)
}
} else {
response = await order(accounts['1']['ACCT'], accounts['1']['APIKEY'], req.params.instrument, req.params.quantity);
}*/
/*td = await getTradesByInstrument(accounts['2']['ACCT'], accounts['2']['APIKEY'], req.params.instrument);
if (td) {
if (td["initialUnits"] != req.params.quantity) {
let dist = "0.005"
if (req.params.instrument.includes("JPY")) {
let dist = "0.5"
}
await takeProfit(accounts['2']['ACCT'], accounts['2']['APIKEY'], td["id"], dist)
}
} else {
response = await order(accounts['2']['ACCT'], accounts['2']['APIKEY'], req.params.instrument, req.params.quantity);
} */
for (account of Object.keys(accounts)) {
response = await order(accounts[account]['ACCT'], accounts[account]['APIKEY'], req.params.instrument, req.params.quantity);
}
res.header('Access-Control-Allow-Origin', '*')
res.json("ok")
})
app.listen(port, host, () => {
console.log(`osapi started`);
})

17
package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "osapi",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.4.0",
"cors": "^2.8.5",
"express": "^4.18.2",
"morgan": "^1.10.0"
}
}