-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxdvf.js
119 lines (98 loc) · 2.9 KB
/
xdvf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const DVF = require('./dvf')
const _ = require('lodash')
const { splitSymbol, prepareAmount, preparePrice } = require('dvf-utils')
const { PRIVATE_KEY, ALCHEMY_URL } = require('./config')
const request = require('request-promise')
const PAIR = 'DVF:xDVF'
let dvf
let lastMidPrice
let tokenQuote
let tokenBase
onStartUp()
let pair, routeBuy, routeSell, buySide, sellSide, midPrice
async function marketMake () {
periodicReplace()
setInterval(periodicReplace, 600000)
}
async function periodicReplace() {
midPrice = await getOraclePrice()
console.log(midPrice)
const haveOpenOrders = await checkIfOpenOrders()
if (midPrice !== lastMidPrice || !haveOpenOrders) {
lastMidPrice = midPrice
replaceOrders()
}
}
async function onStartUp () {
dvf = await DVF()
await syncBalances()
console.log('Starting balances: ', balanceA, balanceB)
marketMake()
}
// Trading Functions
let balanceA
let balanceB
async function cancelOpenOrders () {
const orders = await dvf.getOrders()
orders.forEach(o => {
if (o.symbol != PAIR) return
dvf.cancelOrder(o._id)
})
}
async function checkIfOpenOrders () {
const orders = await dvf.getOrders()
return orders.length > 0
}
async function syncBalances () {
const balances = _.chain(await dvf.getBalance())
.keyBy('token')
.mapValues('available')
.value()
const [quote, base] = splitSymbol(PAIR)
balanceA = dvf.token.fromQuantizedAmount(quote, balances[quote])
balanceB = dvf.token.fromQuantizedAmount(base, balances[base])
balanceA = balanceA === 'NaN' ? 0 : balanceA
balanceB = balanceB === 'NaN' ? 0 : balanceB
}
async function replaceOrders () {
await cancelOpenOrders()
setTimeout(async() => {
await syncBalances()
const balanceToSell = Math.min(0.9 * balanceA, 500000 / lastMidPrice)
placeOrder(-1 * balanceToSell)
const balanceToBuy = Math.min(0.9 * balanceB / lastMidPrice, 500000 / lastMidPrice)
placeOrder(balanceToBuy)
}, 2000)
}
async function placeOrder (amount) {
amount = 100 * Math.trunc(prepareAmount(amount, 0) / 100)
if (amount === '0') return
const [quote, base] = splitSymbol(PAIR)
let price
if (amount > 0) {
price = preparePrice(lastMidPrice * 0.9999)
console.log('Place buy at:', price)
} else {
price = preparePrice(lastMidPrice * 1.00)
console.log('Place sell at:', price)
}
if (!price) return
console.log(amount, price)
try {
await dvf.submitOrder({
symbol: PAIR,
amount,
price,
starkPrivateKey: PRIVATE_KEY.substring(2)
})
} catch (e) {
const error = (e.error && e.error.details && e.error.details.error) || {}
console.warn(`Trade not completed: ${error.error}`)
}
}
let config, quote, base
async function getOraclePrice () {
// TODO: Call the xDVF contract to get the balance of DVF it holds, and the total balance, and calc exchange rate. Or create an API for this
console.log('Oracle price: 1')
return 1
}