This commit is contained in:
artin 2023-08-03 03:13:15 -07:00
parent 514a4dcf18
commit af2e0ba55b

352
index.js
View File

@ -1,30 +1,31 @@
const express = require('express')
var cors = require('cors')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')
import express from 'express'
import cors from 'cors'
import fs from 'fs'
impoprt morgan from 'morgan'
import path from 'path'
import fetch from 'node-fetch';
const app = express()
var pg = require('pg');
const client = new pg.Client({
host: 'citus1.home.neb',
port: 5432,
database: 'oversite',
user: 'postgres',
})
const client = new pg.Client("postgresql://crate@crate1.home.neb:5432/oversite")
client.connect()
const port = 3000
const host = "0.0.0.0"
const STATE = {};
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), {
flags: 'a'
})
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), { flags: 'a' })
app.use(morgan('combined', { stream: accessLogStream }))
app.use(morgan('combined', {
stream: accessLogStream
}))
const axios = require('axios').default;
@ -33,7 +34,11 @@ const APIURL = 'https://api-fxpractice.oanda.com/v3'
const accounts = {
'1': {
'ACCT': '101-001-8005237-001',
'APIKEY': '85397a3ddc7b96ef57b90c9feda6d410-18f0f2b634f9f05533d2c20046bb79df'
'APIKEY': 'e88218d201bd344c2dc3c469f8f8d1f3-e77504680a17f51f0baecf9dababa40b'
},
'4': {
'ACCT': '101-001-8005237-002',
'APIKEY': 'e88218d201bd344c2dc3c469f8f8d1f3-e77504680a17f51f0baecf9dababa40b'
},
'2': {
'APIKEY': 'b954456a3f4ac735de2555e1af50abf7-ed83ace2f9fb86412b76608daefc73a5',
@ -45,48 +50,45 @@ const accounts = {
}
}
async function getTransactionsAll(account,acct_id, api_key) {
async function getTransactionsAll(account, acct_id, api_key) {
for (const rg of [...Array(32).keys()]) {
try {
f = rg * 1000 + 1;
to = f + 1000;
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/transactions/idrange?from=${f}&to=${to}`,
method: 'get',
headers: {
'Authorization': `Bearer ${api_key}`
}
});
try {
f = rg * 1000 + 1;
to = f + 1000;
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/transactions/idrange?from=${f}&to=${to}`,
method: 'get',
headers: {
'Authorization': `Bearer ${api_key}`
}
});
for (const t of response.data.transactions){
qty = 0;
tp = "";
if(typeof(t['instrument']) !== undefined){
tp = t['instrument']
}
if(typeof(t['units']) !== undefined){
qty = t['units']
}
await client.query(`insert into orders (order_id, account_id, tpair, order_type, order_ref, order_reason, order_date, order_data, quantity) values ($1,$2,$3,$4,$5,$6,$7,$8,$9)`, [t.id, account, tp, t.type, t.batchID, t.reason, t.time, t, qty]);
for (const t of response.data.transactions) {
qty = 0;
tp = "";
if (typeof(t['instrument']) !== undefined) {
tp = t['instrument']
}
if (typeof(t['units']) !== undefined) {
qty = t['units']
}
await client.query(`insert into orders (order_id, account_id, tpair, order_type, order_ref, order_reason, order_date, order_data, quantity) values ($1,$2,$3,$4,$5,$6,$7,$8,$9)`, [t.id, account, tp, t.type, t.batchID, t.reason, t.time, t, qty]);
}
} catch (error) {
console.error(error);
}
} catch (error) {
console.error(error);
}
}
}
async function getTransactions(account,acct_id, api_key) {
// for (const rg of [...Array(32).keys()]) {
async function getTransactions(account, acct_id, api_key) {
// for (const rg of [...Array(32).keys()]) {
try {
console.log(`SELECT max(order_id) from orders where account_id = ${account}`);
const res = await client.query(`SELECT max(order_id) as order_id from orders where account_id = ${account}`)
console.log(res.rows[0].order_id) // Hello w
console.log(res.rows[0]) // Hello w
f = res.rows[0].order_id;
to = f + 1000;
const res = await client.query(`SELECT max(order_id) as order_id from orders where account_id = ${account}`)
f = res.rows[0].order_id;
to = f + 1000;
const response = await axios.request({
url: `${APIURL}/accounts/${acct_id}/transactions/idrange?from=${f}&to=${to}`,
method: 'get',
@ -95,20 +97,20 @@ async function getTransactions(account,acct_id, api_key) {
}
});
for (const t of response.data.transactions){
qty = 0;
tp = "";
if(typeof(t['instrument']) !== undefined){
tp = t['instrument']
}
if(typeof(t['units']) !== undefined){
qty = t['units']
}
await client.query(`insert into orders (order_id, account_id, tpair, order_type, order_ref, order_reason, order_date, order_data, quantity) values ($1,$2,$3,$4,$5,$6,$7,$8,$9)`, [t.id, account, tp, t.type, t.batchID, t.reason, t.time, t, qty]);
for (const t of response.data.transactions) {
qty = 0;
tp = "";
if (typeof(t['instrument']) !== undefined) {
tp = t['instrument']
}
if (typeof(t['units']) !== undefined) {
qty = t['units']
}
await client.query(`insert into orders (order_id, account_id, tpair, order_type, order_ref, order_reason, order_date, order_data, quantity) values ($1,$2,$3,$4,$5,$6,$7,$8,$9)`, [t.id, account, tp, t.type, t.batchID, t.reason, t.time, t, qty]);
}
} catch (error) {
console.error(error);
}
@ -142,7 +144,7 @@ async function getTradesByInstrument(acct_id, api_key, instrument) {
'Authorization': `Bearer ${api_key}`
}
});
console.log(response)
//console.log(response)
if (response.data.trades.length == 0) {
return
} else {
@ -173,21 +175,21 @@ async function order(acct_id, api_key, instrument, quantity) {
try {
let dist = "0.0005"
let pdist = "0.0005"
let dist = "0.001"
let pdist = "0.001"
if (instrument.includes("JPY")) {
dist = "0.05"
pdist = "0.05"
dist = "0.1"
pdist = "0.1"
}
data = {
"order": {
"trailingStopLossOnFill": {
/*"trailingStopLossOnFill": {
"timeInForce": "GTC",
"distance": dist
},
},*/
/*"takeProfitOnFill": {
"distance": pdist
},*/
@ -206,23 +208,8 @@ async function order(acct_id, api_key, instrument, quantity) {
},
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);
@ -350,20 +337,20 @@ 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) =>{
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)
}
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)
@ -371,14 +358,14 @@ console.log(error)
app.get('/transactionsAll/:account', async (req, res) => {
let account = req.params.account;
let r = {}
let response = await getTransactions(account,accounts[account]['ACCT'], accounts[account]['APIKEY'])
try {
r = {};
} catch(error) {
console.log(error)
}
let response = await getTransactionsAll(account, accounts[account]['ACCT'], accounts[account]['APIKEY'])
try {
r = {};
} catch (error) {
console.log(error)
}
res.header('Access-Control-Allow-Origin', '*')
res.json("ok")
})
@ -386,12 +373,12 @@ app.get('/transactions', async (req, res) => {
let r = {}
for (account of Object.keys(accounts)) {
let response = await getTransactions(account,accounts[account]['ACCT'], accounts[account]['APIKEY'])
try {
r = {};
} catch(error) {
console.log(error)
}
let response = await getTransactions(account, accounts[account]['ACCT'], accounts[account]['APIKEY'])
try {
r = {};
} catch (error) {
console.log(error)
}
}
res.header('Access-Control-Allow-Origin', '*')
res.json("ok")
@ -402,25 +389,47 @@ 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)
}
try {
r[account] = response.data;
} catch (error) {
console.log(error)
}
}
res.header('Access-Control-Allow-Origin', '*')
res.json(r)
})
app.get('/accounts/del/:user_id/:account_id', async(req,res) => {
await client.query(`delete from accounts where user_id = ${req.params.user_id} and id = ${req.params.account_id}`);
app.get('/accounts/:user_id', async (req, res) => {
accts = await client.query(`select * from accounts where user_id = ${req.params.user_id} `);
res.header('Access-Control-Allow-Origin', '*');
res.json('ok');
res.json(accts.rows);
})
app.get('/accounts/add/:user_id/:a_number/:akey', async(req,res) => {
await client.query(`insert into accounts (user_id, account_number, apikey, account_type) values (${req.params.user_id},'${req.params.a_number}','${req.params.akey}', 'oanda')`)
app.get('/accounts', async (req, res) => {
accts = await client.query(`select * from accounts `);
res.header('Access-Control-Allow-Origin', '*');
res.json('ok');
r = {};
console.log(accts);
for (const a of accts.rows) {
if (typeof(r[a['user_id']]) === 'undefined') {
r[a['user_id']] = [a];
} else {
r[a['user_id']].push( a );
}
}
res.json(r);
})
app.get('/accounts/del/:user_id/:account_id', async (req, res) => {
await client.query(`delete from accounts where user_id = ${req.params.user_id} and id = ${req.params.account_id}`);
res.header('Access-Control-Allow-Origin', '*');
res.json('ok');
})
app.get('/accounts/add/:user_id/:a_number/:akey', async (req, res) => {
await client.query(`insert into accounts (user_id, account_number, apikey, account_type) values (${req.params.user_id},'${req.params.a_number}','${req.params.akey}', 'oanda')`)
res.header('Access-Control-Allow-Origin', '*');
res.json('ok');
})
app.get('/trailingStop/:instrument', async (req, res) => {
@ -429,61 +438,74 @@ app.get('/trailingStop/:instrument', async (req, res) => {
res.header('Access-Control-Allow-Origin', '*')
res.json(response.data)
})
app.get('/tradesByInstrument/:instrument', async (req, res) => {
res.header('Access-Control-Allow-Origin', '*')
r = {};
for (account of Object.keys(accounts)) {
r[account] = await getTradesByInstrument(accounts[account]['ACCT'], accounts[account]['APIKEY'], req.params.instrument);
}
res.json(r);
r = "";
data = await client.query(`select * from orders where account_id = 2 and order_date > now()- interval '1 day'`);
for (const row of data.rows) {
delete(row['order_data']);
r += `${Object.values(row).join(',')} \n`;
}
//r[account] = await getTradesByInstrument(accounts[2]['ACCT'], accounts[2]['APIKEY'], req.params.instrument);
res.header('Content-Type', 'text/csv');
res.send(r);
})
app.get('/order/:instrument/:quantity', async (req, res) => {
r = {};
/*td = await getTradesByInstrument(accounts['2']['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['2']['ACCT'], accounts['1']['APIKEY'], td["id"], dist)
}
} else {
response = await order(accounts['2']['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)) {
td = await getTradesByInstrument(accounts[account]['ACCT'], accounts[account]['APIKEY'], req.params.instrument);
if (td['state'] != "OPEN" || td['state'] != "PENDING") {
response = await order(accounts[account]['ACCT'], accounts[account]['APIKEY'], req.params.instrument, req.params.quantity);
}
if (td == null || (td['state'] != "OPEN" && td['state'] != "PENDING")) {
response = await order(accounts[account]['ACCT'], accounts[account]['APIKEY'], req.params.instrument, req.params.quantity);
console.log(response["data"]);
if (typeof(response["data"]["orderFillTransaction"]) !== "undefined"){
delta = 0.0012;
if (req.params.instrument.includes("JPY")){ delta = 0.12;}
STATE[account][req.params.instrument]["base"] = response["data"]["orderFillTransaction"]["price"] + delta;
STATE[account][req.params.instrument]["trigger"] = (response["data"]["orderFillTransaction"]["price"] + delta) * 1.05;
STATE[account][req.params.instrument]["TP"] = false;
STATE[account][req.params.instrument]["qty"] = req.params.quantity;
STATE[account][req.params.instrument]["trade_id"] = response["data"]["orderFillTransaction"]["tradeOpened"]["tradeID"];
if (req.params.quantity > 0) {
STATE[account][req.params.instrument]["watch"] = "ask";
} else {
STATE[account][req.params.instrument]["watch"] = "bid";
}
}
}
}
res.header('Access-Control-Allow-Origin', '*')
res.json("ok")
})
app.listen(port, host, () => {
console.log(`osapi started`);
})
const response = await fetch('https://stream-fxpractice.oanda.com/v3/accounts/101-001-8005237-001/pricing/stream?instruments=GBP_CAD%2CNZD_CAD%2CEUR_CHF%2CEUR_CAD%2CNZD_CHF%2CCHF_JPY%2CUSD_CHF%2CAUD_JPY%2CEUR_USD%2CNZD_USD%2CUSD_JPY%2CGBP_AUD%2CEUR_AUD%2CCAD_JPY%2CEUR_GBP%2CAUD_CAD%2CEUR_JPY%2CAUD_CHF%2CCAD_CHF%2CGBP_JPY%2CUSD_CAD%2CNZD_JPY%2CUSD_SGD%2CAUD_USD%2CGBP_CHF%2CAUD_NZD%2CGBP_USD', { method: 'GET', headers: {'Authorization': 'Bearer e88218d201bd344c2dc3c469f8f8d1f3-e77504680a17f51f0baecf9dababa40b'} });
try {
for await (const chunk of response.body) {
try {
const x = JSON.parse(chunk.toString());
if (x['type'] == "Price") {
client.query(`insert into pricing (instrument, price_data, tick, bid,ask,spread) values ($1,$2,$3,$4,$5,$6)`, [x["instrument"], x, x["time"], x["asks"][0]["price"], x["asks"][0]["price"], x["bids"][0]["price"] = x["bids"][0]["price"]]);
}
} catch(e) {
}
}
} catch (err) {
console.error(err.stack);
}