使用二维数组计算 win/lose
Working on two-dimensional arrays to calculate win/lose
我在两个对象数组中跟踪我的交易组合。
特定交易货币的卖出和买入如下:
var sell {
sold_amount: sold,
bought_amount: bought,
price : price
}
var buy {
sold_amount: sold,
bought_amount: bought,
price : price
}
我正在尝试以下操作:
以LIFO的方式计算我的输赢百分比。这意味着我想采用最近的卖出并开始从最近的买入中减去 price/amount,然后向后移动。
如果我的卖出量足够大,这意味着我不仅需要查看之前的买入量,还需要搜索未知数量的先前买入量,直到我的卖出量用完,这样我才能可以算出我的win/lose.
我的难处在于,由于卖出和买入是在不同的amount/prices上进行的,所以我很难计算出结果。
这意味着例如:
I bought 20 units of $javascript paying 32 units of $c++ ,
I bought 17 units of $javascript paying 29 units of $c++ ,
I sold 57 units of $c++ paying 31 units of $javascript,
I bought 22 units of $javascript paying 22 units of c++,
I sold 12 units of c++ paing 11 units of $javascript,
这意味着在每次卖出时我都需要向后看并递归地查看我购买它的价格并根据金额 sold/bought.
计算 win/lose
我不是在寻找解决方案,只是在寻找一些指南或建议。
如果我们想到 LIFO 交易,我们可以将其转化为称为堆栈的数据结构中元素的概念,其中具有操作 push/pop:
每笔交易有五个变量:买入金额、买入类型、卖出金额、卖出类型和日期。
function Trade(buyAmount, buyType, sellAmount, sellType, date) {
this.buyAmount = buyAmount;
this.buyType = buyType;
this.sellAmount = sellType;
this.date = date;
}
这是一个JavaScript对象的构造函数,可以这样调用:
var trade = new Trade("Bitcoin", 1.0, "Ethereum", 10.0, new Date("5/30/2018"));
函数调用前的关键字 new
创建一个对象,并且在该函数中使用的 this
成为对该新对象的引用。然后将该对象分配给变量trade
。 (研究this
很厉害。)
无论如何,接下来您需要创建一个按日期排序的数组,并创建一个算法,使每笔交易的毛利交易与所售商品的类型相关,即类似于以下内容的字典:
var profit = { Bitcoin: 0, Ethereum: 0 }
这是一个很好的起点,我使用这种相同类型的数据结构来计算 2017 年我的加密货币收益的税收。
您可以获取交易并维护总单位数和总价两个指标。售价与实际购买商品的计算无关
要获得一些已售商品的实际价值,将检查最后一次购买,如果最后一次购买的单位数量小于或等于已售出的单位,则更新总价值以及实际单位,直到所有单位均取自最新购买。
如果某些购买有剩余的单位,则将此信息添加到项目数组中。
因此,维护了一个包含最后购买和销售的动态数组。
------------------
t o t a l
action units price calc price units price comment
-------- -------- -------- -------- -------- -------- -------- -----------------
buy 20 32 20 * 32 640 20 640
buy 17 29 17 * 29 493 37 1133
sell 22 22 -17 * 29 -493 20 640 take last first
- 5 * 32 -160 15 480 take next to last
buy 31 57 31 * 57 1767 46 2247
sell 11 12 -11 * 57 -627 35 1620
------------------
var transactions = [
{ action: 'buy', product: 'foo', units: 20, price: 32 },
{ action: 'buy', product: 'foo', units: 17, price: 29 },
{ action: 'sell', product: 'foo', units: 22, price: 22 },
{ action: 'buy', product: 'foo', units: 31, price: 57 },
{ action: 'sell', product: 'foo', units: 11, price: 12 }
],
accounts = {};
transactions.forEach(({ action, product, units, price }) => {
var last;
accounts[product] = accounts[product] || { items: [], totalUnits: 0, totalPrice: 0 };
if (action === 'buy') {
accounts[product].totalUnits += units;
accounts[product].totalPrice += units * price;
accounts[product].items.push({ units, price });
} else {
while (units) {
last = accounts[product].items.pop();
if (last.units <= units) {
accounts[product].totalUnits -= last.units;
accounts[product].totalPrice -= last.units * last.price;
units -= last.units;
continue;
}
accounts[product].totalUnits -= units;
accounts[product].totalPrice -= units * last.price;
last.units -= units;
units = 0;
accounts[product].items.push(last);
}
}
console.log(accounts);
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
我在两个对象数组中跟踪我的交易组合。
特定交易货币的卖出和买入如下:
var sell {
sold_amount: sold,
bought_amount: bought,
price : price
}
var buy {
sold_amount: sold,
bought_amount: bought,
price : price
}
我正在尝试以下操作:
以LIFO的方式计算我的输赢百分比。这意味着我想采用最近的卖出并开始从最近的买入中减去 price/amount,然后向后移动。
如果我的卖出量足够大,这意味着我不仅需要查看之前的买入量,还需要搜索未知数量的先前买入量,直到我的卖出量用完,这样我才能可以算出我的win/lose.
我的难处在于,由于卖出和买入是在不同的amount/prices上进行的,所以我很难计算出结果。
这意味着例如:
I bought 20 units of $javascript paying 32 units of $c++ ,
I bought 17 units of $javascript paying 29 units of $c++ ,
I sold 57 units of $c++ paying 31 units of $javascript,
I bought 22 units of $javascript paying 22 units of c++,
I sold 12 units of c++ paing 11 units of $javascript,
这意味着在每次卖出时我都需要向后看并递归地查看我购买它的价格并根据金额 sold/bought.
计算 win/lose我不是在寻找解决方案,只是在寻找一些指南或建议。
如果我们想到 LIFO 交易,我们可以将其转化为称为堆栈的数据结构中元素的概念,其中具有操作 push/pop:
每笔交易有五个变量:买入金额、买入类型、卖出金额、卖出类型和日期。
function Trade(buyAmount, buyType, sellAmount, sellType, date) {
this.buyAmount = buyAmount;
this.buyType = buyType;
this.sellAmount = sellType;
this.date = date;
}
这是一个JavaScript对象的构造函数,可以这样调用:
var trade = new Trade("Bitcoin", 1.0, "Ethereum", 10.0, new Date("5/30/2018"));
函数调用前的关键字 new
创建一个对象,并且在该函数中使用的 this
成为对该新对象的引用。然后将该对象分配给变量trade
。 (研究this
很厉害。)
无论如何,接下来您需要创建一个按日期排序的数组,并创建一个算法,使每笔交易的毛利交易与所售商品的类型相关,即类似于以下内容的字典:
var profit = { Bitcoin: 0, Ethereum: 0 }
这是一个很好的起点,我使用这种相同类型的数据结构来计算 2017 年我的加密货币收益的税收。
您可以获取交易并维护总单位数和总价两个指标。售价与实际购买商品的计算无关
要获得一些已售商品的实际价值,将检查最后一次购买,如果最后一次购买的单位数量小于或等于已售出的单位,则更新总价值以及实际单位,直到所有单位均取自最新购买。
如果某些购买有剩余的单位,则将此信息添加到项目数组中。
因此,维护了一个包含最后购买和销售的动态数组。
------------------
t o t a l
action units price calc price units price comment
-------- -------- -------- -------- -------- -------- -------- -----------------
buy 20 32 20 * 32 640 20 640
buy 17 29 17 * 29 493 37 1133
sell 22 22 -17 * 29 -493 20 640 take last first
- 5 * 32 -160 15 480 take next to last
buy 31 57 31 * 57 1767 46 2247
sell 11 12 -11 * 57 -627 35 1620
------------------
var transactions = [
{ action: 'buy', product: 'foo', units: 20, price: 32 },
{ action: 'buy', product: 'foo', units: 17, price: 29 },
{ action: 'sell', product: 'foo', units: 22, price: 22 },
{ action: 'buy', product: 'foo', units: 31, price: 57 },
{ action: 'sell', product: 'foo', units: 11, price: 12 }
],
accounts = {};
transactions.forEach(({ action, product, units, price }) => {
var last;
accounts[product] = accounts[product] || { items: [], totalUnits: 0, totalPrice: 0 };
if (action === 'buy') {
accounts[product].totalUnits += units;
accounts[product].totalPrice += units * price;
accounts[product].items.push({ units, price });
} else {
while (units) {
last = accounts[product].items.pop();
if (last.units <= units) {
accounts[product].totalUnits -= last.units;
accounts[product].totalPrice -= last.units * last.price;
units -= last.units;
continue;
}
accounts[product].totalUnits -= units;
accounts[product].totalPrice -= units * last.price;
last.units -= units;
units = 0;
accounts[product].items.push(last);
}
}
console.log(accounts);
});
.as-console-wrapper { max-height: 100% !important; top: 0; }