Skip to content

Instantly share code, notes, and snippets.

@davidlondono
Last active February 25, 2021 19:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save davidlondono/800c48398e55db79a9b907fd86c1bc3f to your computer and use it in GitHub Desktop.
Save davidlondono/800c48398e55db79a9b907fd86c1bc3f to your computer and use it in GitHub Desktop.
Analysis of strategies of https://bitcoinvsaltcoins.com
import fetch from 'node-fetch';
import readline from "readline";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const margin_pairs = new Set([
"ADABTC",
"ATOMBTC",
"BATBTC",
"BCHBTC",
"BNBBTC",
"DASHBTC",
"EOSBTC",
"ETCBTC",
"ETHBTC",
"IOSTBTC",
"IOTABTC",
"LINKBTC",
"LTCBTC",
"MATICBTC",
"NEOBTC",
"ONTBTC",
"QTUMBTC",
"RVNBTC",
"TRXBTC",
"VETBTC",
"XLMBTC",
"XMRBTC",
"XRPBTC",
"XTZBTC",
"ZECBTC",
]);
interface TradesBN {
id: string;
stratid: string;
stratname: string;
pair: string;
type: "LONG" | "SHORT";
buy_time: string;
updated_time: string;
buy_price: string;
sell_price: string;
pnl: string;
yo: boolean;
}
// https://stackoverflow.com/questions/56252742/find-all-permutations-of-2-arrays-in-js
const transpose = <T>(array: T[][]) => array.reduce<T[][]>((r, a) => a.map<T[]>((v, i) => [...(r[i] || []), v]), []);
const combinations = <T>(array: T[][]) => array.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));
interface RunOptions {
types: TradesBN['type'][]
}
const run = async (strategy: string | number, ops: RunOptions = { types: ['LONG', 'SHORT']}) => {
const data: TradesBN[] = await fetch(`https://bitcoinvsaltcoins.com/api/strategy?id=${strategy}`)
.then(response => response.json() );
const orderData = data.filter(d => ops.types.includes(d.type));
const enterOperation = orderData.map((e) => ({
time: Number(e.buy_time),
operation: 'enter',
...e,
}));
const exitOperation = orderData.map((e) => ({
time: Number(e.updated_time),
operation: 'exit',
...e,
}));
const history = [...enterOperation,...exitOperation]
.sort((a,b) => a.time - b.time)
.filter(e => !e.yo);
const times = history.map(h => h.time);
const timeDif = Math.max(...times) - Math.min(...times)
const interes = 0.00125 / 100;
const hours = timeDif / (1000 * 60 * 60)
const executeTrades = ({ trades, tradeDivide, balance }: {
trades: typeof history, tradeDivide: number, balance: number
}) => {
let theNewBalance = balance
const tradesOpen = new Set();
let operationLost = 0;
const tradeAmount = balance * tradeDivide;
trades.forEach(d => {
if (d.operation === 'enter' && theNewBalance > tradeAmount) {
tradesOpen.add(d.id)
theNewBalance -= tradeAmount;
} else if (d.operation === 'exit' && tradesOpen.has(d.id)) {
if(d.type === 'SHORT') {
const amount = tradeAmount / Number(d.sell_price);
const traded = amount * Number(d.buy_price);
theNewBalance += traded
} else {
const amount = tradeAmount / Number(d.buy_price);
const traded = amount * Number(d.sell_price);
theNewBalance += traded
}
} else if (d.operation === 'enter') {
operationLost += 1;
// console.log("LOST TRADE", d, balance)
}
});
return {
balance: theNewBalance,
operationLost
}
}
const execute = (tradeDivide: number, divide: number) => {
const balance = 1 * divide;
const balancePreMargin = (1 - balance);
const balanceMargin = balancePreMargin * 3.9;
const borrowed = balanceMargin - balancePreMargin;
// console.log({balance,balancePreMargin,balanceMargin,borrowed})
const tradesMargin = history.filter((trade) => margin_pairs.has(trade.pair));
const tradesSpot = history.filter((trade) => !margin_pairs.has(trade.pair));
const executedMargin = executeTrades({
trades:tradesMargin,
tradeDivide,
balance: balanceMargin
});
const executedSpot = executeTrades({
trades: tradesSpot,
tradeDivide,
balance
});
const lostTades = executedMargin.operationLost + executedSpot.operationLost
// console.log({ executedMargin, executedSpot })
const totalInteres = interes * hours * borrowed;
const finalBalance = executedMargin.balance + executedSpot.balance - (borrowed + totalInteres)
// console.log("finalBalance", finalBalance)
return {
lostTades,
finalBalance,
totalInteres
};
}
//execute(0.5, 0.5)
//execute(0, 0)
type TheBestCase = {from: number, to: number, steps: number}
const findTheBest = (table: [TheBestCase,TheBestCase], fn: (one: number, two: number) => number) => {
const counts = 10;
// console.log("steps",step)
// console.log("to",to);
const [stepsOne, stepsTwo] = table.map(({ from, to , steps }) => (to - from) / counts)
const [listOne, listTwo] = table.map(({ from, to, steps }) => {
const step = (to - from) / steps;
return [...Array(steps)].map((_,x) => from + x * step)
});
let max = 0;
let best: number[] = [];
listOne.forEach(val => {
listTwo.forEach(val2 => {
const value = fn(val, val2);
if (max < value) {
max = value;
best = [val, val2];
// console.log(val, val2, max)
process.stdout.write(`\r best match tradeAmount: ${val.toFixed(10)} divide: ${val2.toFixed(10)}`);
}
})
})
process.stdout.write(`\r\n`);
return {
max,
best
};
}
const theBestMatch = findTheBest([{ from: 0, to: 1, steps: 1000},{ from: 0, to: 1, steps: 100}], (a,b) => execute(a,b).finalBalance);
const { lostTades, totalInteres } = execute(theBestMatch.best[0], theBestMatch.best[1]);
const days = timeDif / (1000*60*60*24);
console.log(`Earning %${(100 * (theBestMatch.max - 1) / days).toFixed(2)} a day`, )
console.log("lostTrades", lostTades)
console.log("totalInteres", totalInteres)
console.log(theBestMatch)
}
const requestCode = () => {
rl.question("what code", function(code) {
run(code);
requestCode()
});
}
requestCode()
rl.on("close", function() {
console.log("\nBYE BYE !!!");
process.exit(0);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment