Created
August 5, 2020 12:43
-
-
Save ericjuta/c8183e9c48ab4cdc9aae98e44d83e9f7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as ccxt from 'ccxt'; | |
import * as functions from 'firebase-functions'; | |
const exchangeId = 'binance', | |
exchangeClass = ccxt[exchangeId], | |
exchange = new exchangeClass({ | |
apiKey: functions.config().binance.apikey, | |
secret: functions.config().binance.secret, | |
timeout: 30000, | |
enableRateLimit: true | |
}); | |
const riskRatio = 0.05; | |
const placeLimitBuyOrder = (symbol: string, entryPrice: string, stopLossCommand: string) => | |
exchange | |
.loadMarkets() | |
.then(_ => { | |
return exchange.fetchBalance().then(currentBalances => { | |
return exchange | |
.fetchTicker(symbol) | |
.then(ticker => { | |
const type = 'limit'; | |
const side = 'buy'; | |
const params = { | |
// test: true | |
}; | |
let amount = 0; | |
const currentBalance = currentBalances[symbol.split('/')[1]].total; | |
switch (stopLossCommand.split('=')[0]) { | |
case 'RANGE': { | |
// double.parse(((((riskPercentage / 100) * capitalSize) / | |
// (candleRangePercentage / 100)) / | |
// (entryPrice)) | |
// .toStringAsPrecision(8)) | |
const candleRangePercentage = stopLossCommand.split('=')[1]; | |
amount = Number( | |
( | |
(riskRatio * currentBalance) / | |
(Number(candleRangePercentage) / 100) / | |
Number(entryPrice) | |
).toPrecision(8) | |
); | |
break; | |
} | |
case 'STOPLOSS': { | |
// double.parse( | |
// (((riskPercentage / 100) * capitalSize) / (entryPrice - stopPrice)) | |
// .toStringAsPrecision(8)); | |
const stoplossPrice = stopLossCommand.split('=')[1]; | |
amount = Number( | |
((riskRatio * currentBalance) / (Number(entryPrice) - Number(stoplossPrice))).toPrecision(8) | |
); | |
break; | |
} | |
default: { | |
throw new Error('INVALID STOPLOSS COMMAND NOOB, use RANGE=0 or STOPLOSS=0'); | |
} | |
} | |
// Test gann box percentile orders | |
return Promise.all( | |
[0, 1, 2, 3, 4].map(gannPercentile => { | |
const gannDivisionPrice = | |
gannPercentile * | |
((stopLossCommand.split('=')[0] === 'RANGE' | |
? Number(entryPrice) * (Number(stopLossCommand.split('=')[1]) / 100) | |
: Number(entryPrice) - Number(stopLossCommand.split('=')[1])) / | |
5); | |
const gannOrderPrice = Number(entryPrice) - gannDivisionPrice; | |
const gannDivisionAmount = amount / 5; | |
return exchange | |
.createOrder(symbol, type, side, gannDivisionAmount, gannOrderPrice, params) | |
.then(result => result) | |
.catch(err => console.error(err)); | |
}) | |
); | |
// return exchange | |
// .createOrder(symbol, type, side, amount, price, params) | |
// .then(result => result) | |
// .catch(err => console.error(err)); | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
}); | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
const checkSymbolFunds = (symbol: string) => | |
exchange | |
.fetchBalance() | |
.then(balances => { | |
const shitcoin = symbol.split('/')[0]; | |
const shitcoinFunds = balances[shitcoin].total; | |
return shitcoinFunds; | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
const placeLimitSellOrder = (symbol: string) => | |
checkSymbolFunds(symbol) | |
.then(amount => { | |
return exchange | |
.loadMarkets() | |
.then(_ => { | |
return exchange | |
.fetchTicker(symbol) | |
.then(ticker => { | |
const bestBuyingPrice = ticker.bid; | |
const type = 'limit'; | |
const side = 'sell'; | |
const price = bestBuyingPrice * 0.9; | |
const params = { | |
// test: true | |
}; | |
return exchange.fetchOpenOrders(symbol).then(orders => { | |
// Cancel all open orders on account before closing position | |
return Promise.all(orders.map(order => exchange.cancelOrder(order.id, ticker.symbol))).then(() => { | |
if (amount > 0) { | |
return exchange | |
.createOrder(symbol, type, side, amount, price, params) | |
.then(result => true) | |
.catch(err => console.error(err)); | |
} else { | |
throw new Error(`'Closed all open orders but no available funds for ${symbol} to limit sell'`); | |
} | |
}); | |
}); | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
const isLastTradeHigherThanCurrentAsk = (symbol: string) => | |
exchange.fetchMyTrades(symbol).then((shitcoinTrades: [{ price: number }]) => { | |
const lastShitcoinTradePrice = shitcoinTrades[shitcoinTrades.length - 1].price; | |
return exchange | |
.loadMarkets() | |
.then(_ => | |
exchange | |
.fetchTicker(symbol) | |
.then(ticker => { | |
const bestSellingPrice = ticker.ask; | |
return lastShitcoinTradePrice > bestSellingPrice; | |
}) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}) | |
) | |
.catch(err => { | |
console.error(err); | |
throw err; | |
}); | |
}); | |
export const openLong = (symbol: string, entryPrice: string, stopLossCommand: string) => | |
checkSymbolFunds(symbol) | |
.then(funds => { | |
const shitcoin = symbol.split('/')[0]; | |
const isInPosition = shitcoin === 'BTC' ? true : funds > 1; | |
if (!isInPosition) { | |
return placeLimitBuyOrder(symbol, entryPrice, stopLossCommand) | |
.then(result => true) | |
.catch(err => console.error(err)); | |
} else { | |
// IF in position && last trade is higher than current, buy again to average out position | |
if (isLastTradeHigherThanCurrentAsk) { | |
return placeLimitBuyOrder(symbol, entryPrice, stopLossCommand) | |
.then(result => true) | |
.catch(err => console.error(err)); | |
} | |
return false; | |
} | |
}) | |
.catch(err => console.error(err)); | |
export const closePosition = (symbol: string) => | |
placeLimitSellOrder(symbol) | |
.then(result => true) | |
.catch(err => { | |
console.error(err); | |
return false; | |
}); | |
// console.log(exchange.getMarket('eth/usdt').symbol); | |
// console.log(exchange.id); | |
// console.log(exchange.symbols); | |
// exchange.getMarket('eth/usdt').symbol; | |
//const openLong = (symbol: string) => exchange.createLimitBuyOrder (symbol, amount, price[, params]) | |
//const closePosition = (symbol: string) exchange.createLimitSellOrder (symbol, amount, price[, params]) | |
//# sourceMappingURL=trade.js.map | |
/* | |
get current price of symbol | |
get firebase config amount of current balance in btc | |
create buy order to resolve instantly | |
buy order function should check firebase store if there's a position already open for that ticker | |
create sell order to resolve instantly | |
//const openLong = (symbol: string) => exchange.createLimitBuyOrder (symbol, amount, price[, params]) | |
//const closePosition = (symbol: string) exchange.createLimitSellOrder (symbol, amount, price[, params]) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment