That makes sense. I was thinking of a system where plugin/booking/interpolation iterate over the same entries until no more modifications occur. This would involve some thought to prove (a) commutativity (order doesn't matter), and (b) convergence (no infinite iterations).
Reg. the other approach -- i.e., supporting this in core booking algos: even outside crypto, isn't the philosophy you've put forth "works on unambiguous source"? Given that, is there a syntax that removes ambiguity? For example: *2020-01-01 * "Transfer"* * Asset:BrokerageA -10 HOOLI {}* * Asset:BrokerageB: 10 HOOLI {}* might be unambiguous for FIFO, LIFO, and STRICT, and arguably for NONE (and AVG in the future). I.e., identical CostSpec after inverting the sign of one. I haven't thought deeply about all cases, and anyway, not the most important thing for v3. On Tuesday, December 29, 2020 at 9:29:55 PM UTC-8 bl...@furius.ca wrote: > Ahh yes, indeed. That's a bit of a problem. I don't have a good solution > for this yet. > Simply providing parser-level plugin functionality wouldn't work here, > because the information for the postings to be transferred is filled in by > the interpolation code. This is a feature that would need to be applied in > the booking code, e.g., apply the inventory updates based on the result of > the transfers. > > If this is the defining/key feature that enables working with crypto > currencies, we could consider supporting this explicitly in the core > booking algos (in v3, not touching v2 much anymore). > > Another idea would be to create a new kind of hook, one that is registered > from a plugin, e.g. a callback of yours invoked by the booking code itself, > and whose results applied to a transaction are immediately reflected on the > state of the affected inventories. Maybe this is the right place to do this > (I've never had this idea before.) Now, imagine generalizing this further > to provide and implement all opf the current booking mechanisms that are > currently built in the core. Call this "customizable booking." > > > > > On Tue, Dec 29, 2020 at 7:34 PM redst...@gmail.com <redst...@gmail.com> > wrote: > >> This is interesting. From what I can tell: >> >> - Beancount's loader proceeds thus: parse -> booking+interpolation -> >> plugins -> validate. >> - Therefore, when booking+interpolation is run on your parsed source, >> the transfer plugin has not had a chance to transform the entries and >> transfer the lots. >> - This means, that the reduction in your source (-120 XYZ {}) can't >> be done because there are no lots to reduce at booking+interpolation. >> Therefore, it's interpreted as an augmentation (aka buying a short >> position). (Side note: your "sell" transaction should look like "-120 XYZ >> {} @@ 480 EUR", or " -120 XYZ {} @ 4 EUR", so it's a reduction, and not >> an >> augmentation, and should include an "Income:" posting to capture >> gain/loss, which you'll need to do anyway once this problem is fixed) >> >> AFAICT, this means that the transfer lots plugin won't work without some >> rethinking of the loader, perhaps allowing for pre-booking plugins. Martin >> may have other ideas or workarounds though. >> >> >> On Tuesday, December 29, 2020 at 12:23:38 PM UTC-8 David Terry wrote: >> >>> Hey, >>> >>> Just getting started with beancount and I ran into this problem when >>> entering some crypto trades. I tried out the transfer_lots plugin in the >>> beanlabs repo, and I ran into some issues that I don't really understand. I >>> can attach cost basis and buy and sell lots within one account without >>> issue (see here >>> <https://gist.github.com/xwvvvvwx/75acb4c05dd9b061e8eb46636dbcbc18#file-works-bean>), >>> >>> however when I transfer some assets to a new account and then attempt to >>> see them, I'm running into problems (example file >>> <https://gist.github.com/xwvvvvwx/75acb4c05dd9b061e8eb46636dbcbc18#file-broken-bean> >>> ). >>> >>> Once there is a transfer involved, beancount no longer seems to reduce >>> lots according to FIFO, and instead seems to attach a new cost basis to the >>> removed lots based on the price at the time of the sale. The output from >>> running `bean-doctor context` against the last trade in the problematic >>> file is below. You can see that the sale has resulted in an extra 120 lots >>> @ 4EUR being deducted from the inventory. Is this a bug, or am I using the >>> plugin wrong? >>> >>> ------------ Balances before transaction >>> >>> Assets:Binance:XYZ 100 XYZ {2 EUR, 2020-12-25} >>> Assets:Binance:XYZ 50 XYZ {3 EUR, 2020-12-25} >>> >>> Assets:Binance:EUR >>> >>> >>> ------------ Transaction >>> >>> 2020-12-25 * "Binance" "Sell 120 XYZ" >>> Assets:Binance:XYZ -120 XYZ {4 EUR, 2020-12-25} ; -480 EUR >>> Assets:Binance:EUR 480 EUR ; 480 EUR >>> >>> >>> Basis: (-480 EUR) >>> >>> ------------ Balances after transaction >>> >>> Assets:Binance:XYZ 100 XYZ {2 EUR, 2020-12-25} >>> Assets:Binance:XYZ 50 XYZ {3 EUR, 2020-12-25} >>> * Assets:Binance:XYZ -120 XYZ {4 EUR, 2020-12-25} >>> >>> * Assets:Binance:EUR 480 EUR >>> >>> >>> On Saturday, December 26, 2020 at 5:17:08 PM UTC+1 bl...@furius.ca >>> wrote: >>> >>>> Here, refined further to show how it's leveraging the reduction spec: >>>> >>>> https://github.com/beancount/beancount/blob/master/experiments/plugins/transfer_lots_test.py >>>> >>>> Maybe this should be part of the builtin plugins. >>>> Love my little plugin system >>>> >>>> >>>> >>>> >>>> On Sat, Dec 26, 2020 at 11:14 AM Martin Blais <bl...@furius.ca> wrote: >>>> >>>>> Here, that's what I meant: >>>>> >>>>> https://github.com/beancount/beancount/commit/9e6e8f8c3793982a6de5af5321e3026d326f8170 >>>>> This plugin does what you want (I think). >>>>> >>>>> On Sat, Dec 26, 2020 at 10:29 AM Martin Blais <bl...@furius.ca> wrote: >>>>> >>>>>> On Wed, Dec 23, 2020 at 11:11 PM Justus Pendleton <jus...@ryoohki.net> >>>>>> wrote: >>>>>> >>>>>>> On Wednesday, December 23, 2020 at 11:03:44 AM UTC+7 bl...@furius.ca >>>>>>> wrote: >>>>>>> >>>>>>>> Short answer is: no, but that's quickly becoming a FAQ from crypto >>>>>>>> users. >>>>>>>> It could be designed, but that would be a new feature. >>>>>>>> >>>>>>> >>>>>>> I only use Spec ID booking so I might be missing something but isn't >>>>>>> moving lots just a small 5 or 6 line python script iterating over >>>>>>> beancount.ops.holdings.get_final_holdings? Would this work or is it >>>>>>> more >>>>>>> complicated? I'm not sure that a plugin is simpler/clearer than just >>>>>>> generating the transaction externally and then inserting it into the >>>>>>> beancount file. >>>>>>> >>>>>> >>>>>> There's that. OTOH if this is super common for crypto, I'm thinking >>>>>> we should design it in and make it convenient in the input syntax to >>>>>> make >>>>>> such transfers. >>>>>> >>>>>> In theory it *could* be done with a plugin today as Ben suggest: I >>>>>> imagined it more like this though: >>>>>> >>>>>> 2020-12-19 T "Binance" "Transfer BTC Coinbase-Pro => Binance" >>>>>> Assets:Crypto:BTC:Binance 0.2 BTC {} >>>>>> Assets:Crypto:BTC:Coinbase-Pro >>>>>> >>>>>> whereby the plugin would know to select transactions with flag 'T' >>>>>> (or perhaps a tag given in its config, whatever) and convert the posting >>>>>> on >>>>>> Assets:Crypto:BTC:Coinbase-Pro to include all the original matched >>>>>> reductions. I think this should be doable today actually. >>>>>> >>>>>> >>>>>> >>>>>> holdings = beancount.ops.holdings.get_final_holdings(entries, >>>>>>> included_account_types=('Assets',)) >>>>>>> print(f'{datetime.date.today()} * "ACATS" "Autogenerated lot >>>>>>> transfer to new account"') >>>>>>> for h in filter(match, holdings): >>>>>>> cost_date = None >>>>>>> print(f' {h.account} -{h.number} {h.currency} {{ {cost_date}, >>>>>>> {h.cost_number} {h.cost_currency} }}') >>>>>>> print(f' {args.destination} {h.number} {h.currency} {{ >>>>>>> {cost_date}, {h.cost_number} {h.cost_currency} }}') >>>>>>> >>>>>>> The only problem I see is that get_final_holdings returns a Holding >>>>>>> tuple that doesn't include the acquisition date. But there's a note in >>>>>>> the >>>>>>> code saying the Holding tuple should go away and just be replaced by a >>>>>>> Position, which would hold the acquisition date. >>>>>>> >>>>>> >>>>>> beancount.ops.holdings is gone in v3. It was superfluous anyway (well >>>>>> when I started it I wasn't sure if it would start acquiring more >>>>>> features >>>>>> than just an inventory). Now you can simply aggregate over an inventory >>>>>> and >>>>>> enumerate its contents (positions). >>>>>> >>>>>> -- >> You received this message because you are subscribed to the Google Groups >> "Beancount" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to beancount+...@googlegroups.com. >> > To view this discussion on the web visit >> https://groups.google.com/d/msgid/beancount/58b12132-c3cd-401b-98e5-3035d034846dn%40googlegroups.com >> >> <https://groups.google.com/d/msgid/beancount/58b12132-c3cd-401b-98e5-3035d034846dn%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "Beancount" group. To unsubscribe from this group and stop receiving emails from it, send an email to beancount+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/beancount/682270b8-812a-4098-a8fc-fcc4655737f9n%40googlegroups.com.