【问题标题】:Working on two-dimensional arrays to calculate win/lose处理二维数组以计算输赢
【发布时间】:2018-11-09 15:19:45
【问题描述】:

我正在两个对象数组中跟踪我的交易组合。

特定交易货币的卖出和买入如下:

var sell {
    sold_amount: sold,
    bought_amount: bought,
    price : price
}


var buy {
    sold_amount: sold,
    bought_amount: bought,
    price : price
}

我正在尝试以下操作:

LIFO 的方式计算我的输赢百分比。这意味着我想从最近一次卖出的价格中减去最近一次买入的价格/金额,然后向后移动。

如果我的卖出量足够大,这意味着我不仅需要查看之前的购买,还需要搜索未知数量的之前的购买,直到我的所有卖出金额都用完,以便我可以计算我的赢/输。

我的困难在于,由于买卖是按不同的数量/价格进行的,所以我很难计算结果。

这意味着例如:

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,

这意味着在每次卖出时,我都需要向后看,递归地查看我买入的价格,并根据卖出/买入的数量计算赢/输。

我不是在寻找解决方案,只是一些指导或建议。

【问题讨论】:

  • 也许我理解错了,但为什么不尝试将它们全部转换为他们共享的共同价值——比如金钱?这不是让计算更简单吗?此外,您并没有真正为一只股票与另一只股票一起支付 - 这本身似乎是对模型的一种扭曲。
  • 能给一些测试用例吗?所以我的意思是一些有效的 javascript 输入以及您希望代码返回什么?
  • 你的卖或买对象中没有单位,也许放一个你的js数据的例子
  • 是的,至少 5-10 个测试用例可以帮助我们找到解决问题的方法。
  • 'c++' !== '$c++'?还是错字?

标签: javascript algorithm trading


【解决方案1】:

您可以进行交易并为总单位和总价格维护两个指标。售价与实际购买产品的计算无关。

请查看FIFO and LIFO accounting

要获得某些已售商品的实际价值,会检查最后一次购买,如果最后的单位数量小于或等于已售单位,则更新总值以及实际单位,直到所有单位取自最近一次购买。

如果某个购买有剩余的单位,则将此信息添加到 items 数组中。

因此,将维护一个包含最后购买和销售的动态数组。

                                                  ------------------
                                                       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; }

【讨论】:

  • c++ 和 $c++ 确实是一个错字。感谢您的回答,但这仅捕获了每个单元与其自身相比的变化。 LIFO 很重要,因为例如,如果我一次以 10 美元买入一只股票,然后我再次以 20 美元买入,然后以 20 美元卖出 1 只,我想使用最后买入的价格进行比较并向后移动
  • “读取到 items 数组”是什么意思“从项目数组中读取”?还是别的什么?
  • @PeterMortensen,抱歉不清楚,重新添加,但现在我将句子更改为 如果有些购买有剩余的单位,那么此信息被添加到 items 数组中。
【解决方案2】:

如果我们想到 LIFO 交易,我们可以将其转化为称为堆栈的数据结构中的元素的概念,它具有推送/弹出操作:

每笔交易都有五个变量:买入金额、买入类型、卖出金额、卖出类型和日期。

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 年的加密货币收益的税收。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    相关资源
    最近更新 更多