1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295 |
- \input texinfo @c -*-texinfo-*-
- @setfilename ledger3.info
- @include version.texi
- @set FIXME:UNDOCUMENTED @sc{undocumented}! Please help by contributing documentation for this feature.
- @set InternalUseOnly For internal use only.
- @settitle Ledger: Command-Line Accounting
- @c Before release, run C-u C-c C-u C-a (texinfo-all-menus-update with
- @c a prefix arg). This updates the node pointers, which texinfmt.el
- @c needs.
- @c | Formating | Indexing | |
- @c | | @cindex | concept |
- @c | @command | @findex | Ledger CLI Command (like balance) |
- @c | @option | @findex | Ledger CLI Option (like --market) |
- @c | @var | | Ledger CLI option Variable (like -f FILE) |
- @c | | | Ledger file Syntax |
- @c | @samp | | Valued example or single char |
- @c | @file | | File, Buffer |
- @c | @file | | Program (like ledger, report, acprep) |
- @c Restructuring manual ideas
- @c http://beyondgrep.com/documentation/ack-2.04-man.html
- @c How to make documented ledger examples validate automatically.
- @c
- @c The test/DocTests.py script will be run along with the other tests
- @c when using ctest or acprep check.
- @c The script parses the texinfo file and looks for three kinds of
- @c specially marked @smallexamples, then it will run the ledger
- @c command from the example, and compare the results with the output
- @c from the documentation.
- @c
- @c To specially mark a @smallexample append @c command:UUID, where
- @c UUID is the first 7 digits from the commands sha1sum, e.g.:
- @c
- @c @smallexample @c command:CDE330A
- @c $ ledger -f sample.dat reg expenses
- @c @end smallexample
- @c
- @c Then DocTests.py will look for corresponding documented output,
- @c which may appear anywhere in the file, and is marked with
- @c @smallexample @c output:UUID where UUID is the UUID from the
- @c corresponding ledger command example, e.g.:
- @c
- @c @smallexample @c output:CDE330A
- @c 04-May-27 Book Store Expenses:Books $20.00 $20.00
- @c Expenses:Cards $40.00 $60.00
- @c Expenses:Docs $30.00 $90.0
- @c @end smallexample
- @c
- @c Now where does this data in sample.dat come from?
- @c DocTests.py is a bit smart about ledger's file argument, since
- @c it will check if the given filename exists in the test/input/
- @c directory.
- @c
- @c Sometimes the journal data for an example is specified within
- @c the documentation itself, in that case the journal example data
- @c needs to be specially marked as well using @smallexample @c input:UUID,
- @c again with the UUID being the UUID of the corresponding ledger example
- @c command. If multiple inputs with the same UUID are found they will be
- @c concatenated together and given as one set of data to the example command.
- @c
- @c @smallexample @c input:35CB2A3
- @c 2014/02/09 The Italian Place
- @c Expenses:Food:Dining $ 36.84
- @c Assets:Cash
- @c @end smallexample
- @c
- @c @smallexample @c command:35CB2A3
- @c $ ledger -f inline.dat accounts
- @c @end smallexample
- @c
- @c @smallexample @c output:35CB2A3
- @c Assets:Cash
- @c Expenses:Food:Dining
- @c @end smallexample
- @c
- @c To use different example commands with the same input from the documentation
- @c add with_input:UUID to the example command, where UUID is the UUID of the input,
- @c e.g.:
- @c
- @c @smallexample @c command:94FD2B6,with_input:35CB2A3
- @c $ ledger -f inline.dat bal expenses
- @c @end smallexample
- @c
- @c @smallexample @c output:94FD2B6
- @c $ 36.84 Expenses:Food:Dining
- @c @end smallexample
- @c
- @c To pass additional input to ledger for certain commands, e.g. convert add
- @c with_file:filename to the example command and add a file:UUID to an example
- @c that holds the additional input, where UUID is the UUID of the command,
- @c e.g.:
- @c
- @c @smallexample @c file:download.csv
- @c 767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
- @c @end smallexample
- @c
- @c @smallexample @c command:94FD2B6,with_file:download.csv
- @c $ ledger -f sample.dat convert download.csv
- @c @end smallexample
- @c
- @c Additionally DocTests.py will pass --args-only and --columns 80 to ledger
- @c to ignore any default arguments from the environment or .ledgerrc.
- @c
- @c To manually run the tests in this file run:
- @c $ ./test/DocTests.py -vv --ledger ./ledger --file ./doc/ledger3.texi
- @copying
- Copyright @copyright{} 2003–2015, John Wiegley. All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- @itemize
- @item
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- @item
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- @item
- Neither the name of New Artisans LLC nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
- @end itemize
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- @end copying
- @dircategory User Applications
- @direntry
- * Ledger3: (ledger3). Command-Line Accounting
- @end direntry
- @documentencoding UTF-8
- @iftex
- @finalout
- @end iftex
- @titlepage
- @title Ledger: Command-Line Accounting
- @subtitle For Version @value{VERSION} of Ledger
- @author John Wiegley
- @page
- @vskip 0pt plus 1filll
- @insertcopying
- @end titlepage
- @contents
- @ifnottex
- @node Top, Introduction to Ledger, (dir), (dir)
- @top Overview
- Ledger is a command-line accounting tool that provides double-entry
- accounting based on a text journal. It provides no bells or whistles,
- and returns the user to the days before user interfaces were even a
- twinkling in their father's CRT.
- @end ifnottex
- @menu
- * Introduction to Ledger::
- * Ledger Tutorial::
- * Principles of Accounting with Ledger::
- * Keeping a Journal::
- * Transactions::
- * Building Reports::
- * Reporting Commands::
- * Command-Line Syntax::
- * Budgeting and Forecasting::
- * Time Keeping::
- * Value Expressions::
- * Format Strings::
- * Extending with Python::
- * Ledger for Developers::
- * Major Changes from version 2.6::
- * Example Journal File::
- * Miscellaneous Notes::
- * Concepts Index::
- * Commands & Options Index::
- @end menu
- @node Introduction to Ledger, Ledger Tutorial, Top, Top
- @chapter Introduction to Ledger
- @menu
- * Fat-free Accounting::
- * Building the program::
- * Getting help::
- @end menu
- @node Fat-free Accounting, Building the program, Introduction to Ledger, Introduction to Ledger
- @section Fat-free Accounting
- Ledger is an accounting tool with the moxie to exist. It provides no
- bells or whistles, and returns the user to the days before user
- interfaces were even a twinkling in their father's CRT.
- What it does offer is a double-entry accounting journal with all the
- flexibility and muscle of its modern day cousins, without any of the
- fat. Think of it as the Bran Muffin of accounting tools.
- To use it, you need to start keeping a journal. This is the basis of
- all accounting, and if you haven't started yet, now is the time to
- learn. The little booklet that comes with your checkbook is a journal,
- so we'll describe double-entry accounting in terms of that.
- @c If you use another GUI accounting program like GnuCash, the vast
- @c majority of its functionality is geared towards helping you keep
- @c a journal.
- A checkbook journal records debits (subtractions, or withdrawals) and
- credits (additions, or deposits) with reference to a single account:
- the checking account. Where the money comes from, and where it goes
- to, are described in the payee field, where you write the person or
- company's name. The ultimate aim of keeping a checkbook journal is to
- know how much money is available to spend. That's really the aim of
- all journals.
- @cindex postings
- What computers add is the ability to walk through these postings,
- and tell you things about your spending habits; to let you devise
- budgets and get control over your spending; to squirrel away money
- into virtual savings account without having to physically move money
- around; etc. As you keep your journal, you are recording information
- about your life and habits, and sometimes that information can start
- telling you things you aren't aware of. Such is the aim of all good
- accounting tools.
- The next step up from a checkbook journal, is a journal that keeps
- track of all your accounts, not just checking. In such a journal, you
- record not only who gets paid---in the case of a debit---but where the
- money came from. In a checkbook journal, it's assumed that all the
- money comes from your checking account. But in a general journal, you
- write postings in two lines: the source account and target account.
- @emph{There must always be a debit from at least one account for every
- credit made to another account}. This is what is meant by
- ``double-entry'' accounting: the journal must always balance to zero,
- with an equal number of debits and credits.
- For example, let's say you have a checking account and a brokerage
- account, and you can write checks from both of them. Rather than keep
- two checkbooks, you decide to use one journal for both. In this
- general journal you need to record a payment to Pacific Bell for your
- monthly phone bill, and a transfer (via check) from your brokerage
- account to your checking account. The Pacific Bell bill is $23.00,
- let's say, and you want to pay it from your checking account. In the
- general journal you need to say where the money came from, in addition
- to where it's going to. These transactions might look like this:
- @smallexample
- 9/29 Pacific Bell $23.00 $23.00
- Checking $-23.00 0
- 9/30 Checking $100.00 $100.00
- (123) Brokerage $-100.00 0
- @end smallexample
- The posting must balance to $0: $23 went to Pacific Bell, $23 came
- from Checking. The next entry shows check number 123 written against
- your brokerage account, transferring money to your checking account.
- There is nothing left over to be accounted for, since the money has
- simply moved from one account to another in both cases. This is the
- basis of double-entry accounting: money never pops in or out of
- existence; it is always a posting from one account to another.
- Keeping a general journal is the same as keeping two separate
- journals: One for Pacific Bell and one for Checking. In that case,
- each time a payment is written into one, you write a corresponding
- withdrawal into the other. This makes it easier to write in
- a ``running balance'', since you don't have to look back at the last
- time the account was referenced---but it also means having a lot of
- journal books, if you deal with multiple accounts.
- @cindex account, meaning of
- @cindex meaning of account
- Here is a good place for an aside on the use of the word ``account''.
- Most private people consider an account to be something that holds
- money at an institution for them. Ledger uses a more general
- definition of the word. An account is anywhere money can go. Other
- finance programs use ``categories'', Ledger uses accounts. So, for
- example, if you buy some groceries at Trader Joe's, then more groceries
- at Whole Food Market, you might assign the transactions like this
- @smallexample @c input:validate
- 2011/03/15 Trader Joe's
- Expenses:Groceries $100.00
- Assets:Checking
- 2011/03/15 Whole Food Market
- Expenses:Groceries $75.00
- Assets:Checking
- @end smallexample
- In both cases the money goes to the @samp{Groceries} account, even
- though the payees were different. You can set up your accounts in any
- way you choose.
- Enter the beauty of computerized accounting. The purpose of the
- Ledger program is to make general journal accounting simple, by
- keeping track of the balances for you. Your only job is to enter the
- postings. If an individual posting does not balance, Ledger displays
- an error and indicates the incorrect posting.@footnote{In some special
- cases, it automatically balances this transaction for you.}
- In summary, there are two aspects of Ledger use: updating the journal
- data file, and using the Ledger tool to view the summarized result of
- your transactions.
- And just for the sake of example---as a starting point for those who
- want to dive in head-first---here are the journal transactions from
- above, formatted as the Ledger program wishes to see them:
- @smallexample @c input:48DDF26
- 2004/09/29 Pacific Bell
- Expenses:Pacific Bell $23.00
- Assets:Checking
- @end smallexample
- The account balances and registers in this file, if saved as
- @file{ledger.dat}, could be reported using:
- @smallexample @c command:48DDF26
- $ ledger -f ledger.dat balance
- @end smallexample
- @smallexample @c output:48DDF26
- $-23.00 Assets:Checking
- $23.00 Expenses:Pacific Bell
- --------------------
- 0
- @end smallexample
- Or
- @smallexample @c command:8C7295F,with_input:48DDF26
- $ ledger -f ledger.dat register checking
- @end smallexample
- @smallexample @c output:8C7295F
- 04-Sep-29 Pacific Bell Assets:Checking $-23.00 $-23.00
- @end smallexample
- And even:
- @smallexample @c command:BB32EF2,with_input:48DDF26
- $ ledger -f ledger.dat register Bell
- @end smallexample
- @smallexample @c output:BB32EF2
- 04-Sep-29 Pacific Bell Expenses:Pacific Bell $23.00 $23.00
- @end smallexample
- An important difference between Ledger and other finance packages is
- that Ledger will never alter your input file. You can create and edit
- that file in any way you prefer, but Ledger is only for analyzing the
- data, not for altering it.
- @node Building the program, Getting help, Fat-free Accounting, Introduction to Ledger
- @section Building the program
- Ledger is written in ANSI C++, and should compile on any unix platform.
- The easiest way to build and install ledger is to use the prepared
- acprep script, that does a lot of the footwork:
- @smallexample
- # to install missing dependencies
- ./acprep dependencies
- # building ledger
- ./acprep update
- # to run the actual installation
- make install
- @end smallexample
- See the `help` subcommand to `acprep`, which explains some of its many
- options. You can run `make check` to confirm the result, and `make
- install` to install. If these intructions do not work for you can check the
- `INSTALL.md` in the source directory for more up do date build instructions.
- @node Getting help, , Building the program, Introduction to Ledger
- @section Getting help
- @findex help
- Ledger has a complete online help system based on GNU Info. This manual
- can be searched directly from the command-line using @code{info ledger},
- which will bring up this entire manual in your TTY. Alternatively, the
- shorter man page can be accessed from the command-line either via
- @code{man ledger} or @code{ledger --help}
- If you need help on how to use Ledger, or run into problems, you can
- join the Ledger mailing list at
- @url{http://groups.google.com/group/ledger-cli}.
- You can also find help in the @code{#ledger} channel on the IRC server
- @code{irc.freenode.net}.
- @node Ledger Tutorial, Principles of Accounting with Ledger, Introduction to Ledger, Top
- @chapter Ledger Tutorial
- @cindex tutorial
- @menu
- * Start a Journal File::
- * Run a Few Reports::
- @end menu
- @node Start a Journal File, Run a Few Reports, Ledger Tutorial, Ledger Tutorial
- @section Start a Journal File
- @cindex journals
- A journal is a record of your financial transactions and will be central
- to using Ledger. For now we just want to get a taste of what Ledger can
- do. An example journal is included with the source code distribution,
- called @file{drewr3.dat} (@pxref{Example Journal File}). Copy it
- someplace convenient and open up a terminal window in that directory.
- If you would rather start with your own journal right away please
- @pxref{Keeping a Journal}.
- @node Run a Few Reports, , Start a Journal File, Ledger Tutorial
- @section Run a Few Reports
- @menu
- * Balance Report::
- * Register Report::
- * Cleared Report::
- * Using the Windows Command-Line::
- @end menu
- Please note that as a command-line program, Ledger is controlled from
- your shell. There are several different command shells that all
- behave slightly differently with respect to some special characters.
- In particular, the ``bash'' shell will interpret @samp{$} signs
- differently than ledger and they must be escaped to reach the actual
- program. Another example is ``zsh'', which will interpret @samp{^}
- differently than ledger expects. In all cases that follow you should
- take that into account when entering the command-line arguments as given.
- There are too many variations between shells to give concrete examples
- for each.
- @node Balance Report, Register Report, Run a Few Reports, Run a Few Reports
- @subsection Balance Report
- @cindex balance report
- @findex balance
- To find the balances of all of your accounts, run this command:
- @smallexample @c command:1071890
- $ ledger -f drewr3.dat balance
- @end smallexample
- Ledger will generate:
- @smallexample @c output:1071890
- $ -3,804.00 Assets
- $ 1,396.00 Checking
- $ 30.00 Business
- $ -5,200.00 Savings
- $ -1,000.00 Equity:Opening Balances
- $ 6,654.00 Expenses
- $ 5,500.00 Auto
- $ 20.00 Books
- $ 300.00 Escrow
- $ 334.00 Food:Groceries
- $ 500.00 Interest:Mortgage
- $ -2,030.00 Income
- $ -2,000.00 Salary
- $ -30.00 Sales
- $ -63.60 Liabilities
- $ -20.00 MasterCard
- $ 200.00 Mortgage:Principal
- $ -243.60 Tithe
- --------------------
- $ -243.60
- @end smallexample
- @noindent
- Showing you the balance of all accounts. Options and search terms can
- pare this down to show only the accounts you want.
- A more useful report is to show only your Assets and Liabilities:
- @smallexample @c command:5BF4D8E
- $ ledger -f drewr3.dat balance Assets Liabilities
- @end smallexample
- @smallexample @c output:5BF4D8E
- $ -3,804.00 Assets
- $ 1,396.00 Checking
- $ 30.00 Business
- $ -5,200.00 Savings
- $ -63.60 Liabilities
- $ -20.00 MasterCard
- $ 200.00 Mortgage:Principal
- $ -243.60 Tithe
- --------------------
- $ -3,867.60
- @end smallexample
- @node Register Report, Cleared Report, Balance Report, Run a Few Reports
- @subsection Register Report
- @cindex register report
- @findex register
- To show all transactions and a running total:
- @smallexample @c command:66E3A2C
- $ ledger -f drewr3.dat register
- @end smallexample
- @noindent
- Ledger will generate:
- @smallexample @c output:66E3A2C
- 10-Dec-01 Checking balance Assets:Checking $ 1,000.00 $ 1,000.00
- Equit:Opening Balances $ -1,000.00 0
- 10-Dec-20 Organic Co-op Expense:Food:Groceries $ 37.50 $ 37.50
- Expense:Food:Groceries $ 37.50 $ 75.00
- Expense:Food:Groceries $ 37.50 $ 112.50
- Expense:Food:Groceries $ 37.50 $ 150.00
- Expense:Food:Groceries $ 37.50 $ 187.50
- Expense:Food:Groceries $ 37.50 $ 225.00
- Assets:Checking $ -225.00 0
- 10-Dec-28 Acme Mortgage Lia:Mortgage:Principal $ 200.00 $ 200.00
- Expe:Interest:Mortgage $ 500.00 $ 700.00
- Expenses:Escrow $ 300.00 $ 1,000.00
- Assets:Checking $ -1,000.00 0
- 11-Jan-02 Grocery Store Expense:Food:Groceries $ 65.00 $ 65.00
- Assets:Checking $ -65.00 0
- 11-Jan-05 Employer Assets:Checking $ 2,000.00 $ 2,000.00
- Income:Salary $ -2,000.00 0
- (Liabilities:Tithe) $ -240.00 $ -240.00
- 11-Jan-14 Bank Assets:Savings $ 300.00 $ 60.00
- Assets:Checking $ -300.00 $ -240.00
- 11-Jan-19 Grocery Store Expense:Food:Groceries $ 44.00 $ -196.00
- Assets:Checking $ -44.00 $ -240.00
- 11-Jan-25 Bank Assets:Checking $ 5,500.00 $ 5,260.00
- Assets:Savings $ -5,500.00 $ -240.00
- 11-Jan-25 Tom's Used Cars Expenses:Auto $ 5,500.00 $ 5,260.00
- Assets:Checking $ -5,500.00 $ -240.00
- 11-Jan-27 Book Store Expenses:Books $ 20.00 $ -220.00
- Liabilities:MasterCard $ -20.00 $ -240.00
- 11-Dec-01 Sale Asse:Checking:Business $ 30.00 $ -210.00
- Income:Sales $ -30.00 $ -240.00
- (Liabilities:Tithe) $ -3.60 $ -243.60
- @end smallexample
- @noindent
- To limit this to a more useful subset, simply add the accounts you are
- interested in seeing transactions for:
- @cindex accounts, limiting by
- @cindex limiting by accounts
- @smallexample @c command:96B0EB3
- $ ledger -f drewr3.dat register Groceries
- @end smallexample
- @smallexample @c output:96B0EB3
- 10-Dec-20 Organic Co-op Expense:Food:Groceries $ 37.50 $ 37.50
- Expense:Food:Groceries $ 37.50 $ 75.00
- Expense:Food:Groceries $ 37.50 $ 112.50
- Expense:Food:Groceries $ 37.50 $ 150.00
- Expense:Food:Groceries $ 37.50 $ 187.50
- Expense:Food:Groceries $ 37.50 $ 225.00
- 11-Jan-02 Grocery Store Expense:Food:Groceries $ 65.00 $ 290.00
- 11-Jan-19 Grocery Store Expense:Food:Groceries $ 44.00 $ 334.00
- @end smallexample
- @noindent
- Which matches the balance reported for the @samp{Groceries} account:
- @smallexample @c command:AECD64E
- $ ledger -f drewr3.dat balance Groceries
- @end smallexample
- @smallexample @c output:AECD64E
- $ 334.00 Expenses:Food:Groceries
- @end smallexample
- @noindent
- If you would like to find transaction to only a certain payee use
- @samp{payee} or @samp{@@}:
- @smallexample @c command:C6BC57E
- $ ledger -f drewr3.dat register payee "Organic"
- @end smallexample
- @smallexample @c output:C6BC57E
- 10-Dec-20 Organic Co-op Expense:Food:Groceries $ 37.50 $ 37.50
- Expense:Food:Groceries $ 37.50 $ 75.00
- Expense:Food:Groceries $ 37.50 $ 112.50
- Expense:Food:Groceries $ 37.50 $ 150.00
- Expense:Food:Groceries $ 37.50 $ 187.50
- Expense:Food:Groceries $ 37.50 $ 225.00
- Assets:Checking $ -225.00 0
- @end smallexample
- @node Cleared Report, Using the Windows Command-Line, Register Report, Run a Few Reports
- @subsection Cleared Report
- @cindex cleared report
- @findex cleared
- A very useful report is to show what your obligations are versus what
- expenditures have actually been recorded. It can take several days for
- a check to clear, but you should treat it as money spent. The
- @command{cleared} report shows just that (note that the
- @command{cleared} report will not format correctly for accounts that
- contain multiple commodities):
- @smallexample @c command:B86F6A6
- $ ledger -f drewr3.dat cleared
- @end smallexample
- @smallexample @c output:B86F6A6
- $ -3,804.00 $ 775.00 Assets
- $ 1,396.00 $ 775.00 10-Dec-20 Checking
- $ 30.00 0 Business
- $ -5,200.00 0 Savings
- $ -1,000.00 $ -1,000.00 10-Dec-01 Equity:Opening Balances
- $ 6,654.00 $ 225.00 Expenses
- $ 5,500.00 0 Auto
- $ 20.00 0 Books
- $ 300.00 0 Escrow
- $ 334.00 $ 225.00 10-Dec-20 Food:Groceries
- $ 500.00 0 Interest:Mortgage
- $ -2,030.00 0 Income
- $ -2,000.00 0 Salary
- $ -30.00 0 Sales
- $ -63.60 0 Liabilities
- $ -20.00 0 MasterCard
- $ 200.00 0 Mortgage:Principal
- $ -243.60 0 Tithe
- ---------------- ---------------- ---------
- $ -243.60 0
- @end smallexample
- @noindent
- The first column shows the outstanding balance, the second column
- shows the ``cleared'' balance.
- @node Using the Windows Command-Line, , Cleared Report, Run a Few Reports
- @subsection Using the Windows Command-Line
- @cindex windows cmd.exe
- @cindex currency symbol display on windows
- Using ledger under the windows command shell has one significant
- limitation. CMD.EXE is limited to standard ASCII characters and as
- such cannot display any currency symbols other than dollar signs
- @samp{$}.
- @node Principles of Accounting with Ledger, Keeping a Journal, Ledger Tutorial, Top
- @chapter Principles of Accounting with Ledger
- @menu
- * Accounting with Ledger::
- * Stating where money goes::
- * Assets and Liabilities::
- * Commodities and Currencies::
- * Accounts and Inventories::
- * Understanding Equity::
- * Dealing with Petty Cash::
- * Working with multiple funds and accounts::
- @end menu
- @node Accounting with Ledger, Stating where money goes, Principles of Accounting with Ledger, Principles of Accounting with Ledger
- @section Accounting with Ledger
- @cindex double-entry accounting
- Accounting is simply tracking your money. It can range from nothing,
- and just waiting for automatic overdraft protection to kick in, or
- not, to a full-blown double-entry accounting system. Ledger
- accomplishes the latter. With ledger you can handle your personal
- finances or your business's. Double-entry accounting scales.
- @node Stating where money goes, Assets and Liabilities, Accounting with Ledger, Principles of Accounting with Ledger
- @section Stating where money goes
- @cindex credits and debits
- Accountants will talk of ``credits'' and ``debits'', but the meaning
- is often different from the layman's understanding. To avoid
- confusion, Ledger uses only subtractions and additions, although the
- underlying intent is the same as standard accounting principles.
- Recall that every posting will involve two or more accounts.
- Money is transferred from one or more accounts to one or more other
- accounts. To record the posting, an amount is @emph{subtracted}
- from the source accounts, and @emph{added} to the target accounts.
- In order to write a Ledger transaction correctly, you must determine
- where the money comes from and where it goes to. For example, when
- you are paid a salary, you must add money to your bank account and
- also subtract it from an income account:
- @smallexample @c input:validate
- 9/29 My Employer
- Assets:Checking $500.00
- Income:Salary $-500.00
- @end smallexample
- @cindex income is negative
- @cindex why is income negative
- Why is the Income a negative figure? When you look at the balance
- totals for your ledger, you may be surprised to see that Expenses are
- a positive figure, and Income is a negative figure. It may take some
- getting used to, but to properly use a general ledger you must think
- in terms of how money moves. Rather than Ledger ``fixing'' the minus
- signs, let's understand why they are there.
- When you earn money, the money has to come from somewhere. Let's call
- that somewhere ``society''. In order for society to give you an
- income, you must take money away (withdraw) from society in order to
- put it into (make a payment to) your bank. When you then spend that
- money, it leaves your bank account (a withdrawal) and goes back to
- society (a payment). This is why Income will appear negative---it
- reflects the money you have drawn from society---and why Expenses will
- be positive---it is the amount you've given back. These additions and
- subtractions will always cancel each other out in the end, because you
- don't have the ability to create new money: it must always come from
- somewhere, and in the end must always leave. This is the beginning of
- economy, after which the explanation gets terribly difficult.
- Based on that explanation, here's another way to look at your balance
- report: every negative figure means that that account or person or
- place has less money now than when you started your ledger; and every
- positive figure means that that account or person or place has more
- money now than when you started your ledger. Make sense?
- @node Assets and Liabilities, Commodities and Currencies, Stating where money goes, Principles of Accounting with Ledger
- @section Assets and Liabilities
- @cindex assets and liabilities
- @cindex debts are liabilities
- Assets are money that you have, and Liabilities are money that you
- owe. ``Liabilities'' is just a more inclusive name for Debts.
- An Asset is typically increased by transferring money from an Income
- account, such as when you get paid. Here is a typical transaction:
- @smallexample @c input:6B43DD4
- 2004/09/29 My Employer
- Assets:Checking $500.00
- Income:Salary
- @end smallexample
- Money, here, comes from an Income account belonging to @samp{My
- Employer}, and is transferred to your checking account. The money is
- now yours, which makes it an Asset.
- Liabilities track money owed to others. This can happen when you
- borrow money to buy something, or if you owe someone money. Here is
- an example of increasing a MasterCard liability by spending money with
- it:
- @smallexample @c input:6B43DD4
- 2004/09/30 Restaurant
- Expenses:Dining $25.00
- Liabilities:MasterCard
- @end smallexample
- The Dining account balance now shows $25 spent on Dining, and
- a corresponding $25 owed on the MasterCard---and therefore shown as
- $-25.00. The MasterCard liability shows up as negative because it
- offsets the value of your assets.
- The combined total of your Assets and Liabilities is your net worth.
- So to see your current net worth, use this command:
- @smallexample @c command:6B43DD4
- $ ledger balance ^assets ^liabilities
- @end smallexample
- @smallexample @c output:6B43DD4
- $500.00 Assets:Checking
- $-25.00 Liabilities:MasterCard
- --------------------
- $475.00
- @end smallexample
- In a similar vein, your Income accounts show up negative, because they
- transfer money @emph{from} an account in order to increase your
- assets. Your Expenses show up positive because that is where the
- money went to. The combined total of Income and Expenses is your cash
- flow. A positive cash flow means you are spending more than you make,
- since income is always a negative figure. To see your current cash
- flow, use this command:
- @smallexample @c command:DB128F3,with_input:6B43DD4
- $ ledger balance ^income ^expenses
- @end smallexample
- @smallexample @c output:DB128F3
- $25.00 Expenses:Dining
- $-500.00 Income:Salary
- --------------------
- $-475.00
- @end smallexample
- Another common question to ask of your expenses is: How much do I
- spend each month on X? Ledger provides a simple way of displaying
- monthly totals for any account. Here is an example that summarizes
- your monthly automobile expenses:
- @smallexample @c command:DB524E4
- $ ledger -M register -f drewr3.dat expenses:auto
- @end smallexample
- @smallexample @c output:DB524E4
- 11-Jan-01 - 11-Jan-31 Expenses:Auto $ 5,500.00 $ 5,500.00
- @end smallexample
- This assumes, of course, that you use account names like
- @samp{Expenses:Auto:Gas} and @samp{Expenses:Auto:Repair}.
- @menu
- * Tracking reimbursable expenses::
- @end menu
- @node Tracking reimbursable expenses, , Assets and Liabilities, Assets and Liabilities
- @subsection Tracking reimbursable expenses
- @cindex reimbursable expense tracking
- Sometimes you will want to spend money on behalf of someone else, which
- will eventually get repaid. Since the money is still @emph{yours}, it
- is really an asset. And since the expenditure was for someone else, you
- don't want it contaminating your Expenses reports. You will need to
- keep an account for tracking reimbursements.
- This is fairly easy to do in ledger. When spending the money, spend
- it @emph{to} your Assets:Reimbursements, using a different account for
- each person or business that you spend money for. For example:
- @smallexample @c input:validate
- 2004/09/29 Circuit City
- Assets:Reimbursements:Company XYZ $100.00
- Liabilities:MasterCard
- @end smallexample
- This shows $100.00 spent on a MasterCard at Circuit City, with the
- expense was made on behalf of Company XYZ. Later, when Company XYZ
- pays the amount back, the money will transfer from that reimbursement
- account back to a regular asset account:
- @smallexample @c input:validate
- 2004/09/29 Company XYZ
- Assets:Checking $100.00
- Assets:Reimbursements:Company XYZ
- @end smallexample
- This deposits the money owed from Company XYZ into a checking account,
- presumably because they paid the amount back with a check.
- But what to do if you run your own business, and you want to keep
- track of expenses made on your own behalf, while still tracking
- everything in a single ledger file? This is more complex, because you
- need to track two separate things: 1) The fact that the money should
- be reimbursed to you, and 2) What the expense account was, so that you
- can later determine where your company is spending its money.
- This kind of posting is best handled with mirrored postings in
- two different files, one for your personal accounts, and one for your
- company accounts. But keeping them in one file involves the same
- kinds of postings, so those are what is shown here. First, the
- personal transaction, which shows the need for reimbursement:
- @smallexample @c input:validate
- 2004/09/29 Circuit City
- Assets:Reimbursements:Company XYZ $100.00
- Liabilities:MasterCard
- @end smallexample
- This is the same as above, except that you own Company XYZ, and are
- keeping track of its expenses in the same ledger file. This
- transaction should be immediately followed by an equivalent
- transaction, which shows the kind of expense, and also notes the fact
- that $100.00 is now payable to you:
- @smallexample @c input:validate
- 2004/09/29 Circuit City
- Company XYZ:Expenses:Computer:Software $100.00
- Company XYZ:Accounts Payable:Your Name
- @end smallexample
- This second transaction shows that Company XYZ has just spent $100.00
- on software, and that this $100.00 came from Your Name, which must be
- paid back.
- These two transactions can also be merged, to make things a little
- clearer. Note that all amounts must be specified now:
- @smallexample @c input:validate
- 2004/09/29 Circuit City
- Assets:Reimbursements:Company XYZ $100.00
- Liabilities:MasterCard $-100.00
- Company XYZ:Expenses:Computer:Software $100.00
- Company XYZ:Accounts Payable:Your Name $-100.00
- @end smallexample
- To ``pay back'' the reimbursement, just reverse the order of
- everything, except this time drawing the money from a company asset,
- paying it to accounts payable, and then drawing it again from the
- reimbursement account, and paying it to your personal asset account.
- It's easier shown than said:
- @smallexample @c input:validate
- 2004/10/15 Company XYZ
- Assets:Checking $100.00
- Assets:Reimbursements:Company XYZ $-100.00
- Company XYZ:Accounts Payable:Your Name $100.00
- Company XYZ:Assets:Checking $-100.00
- @end smallexample
- And now the reimbursements account is paid off, accounts payable is paid
- off, and $100.00 has been effectively transferred from the company's
- checking account to your personal checking account. The money simply
- ``waited''---in both @samp{Assets:Reimbursements:Company XYZ}, and
- @samp{Company XYZ:Accounts Payable:Your Name}---until such time as it
- could be paid off.
- The value of tracking expenses from both sides like that is that you
- do not contaminate your personal expense report with expenses made on
- behalf of others, while at the same time making it possible to
- generate accurate reports of your company's expenditures. It is more
- verbose than just paying for things with your personal assets, but it
- gives you a very accurate information trail.
- The advantage to keep these doubled transactions together is that they
- always stay in sync. The advantage to keeping them apart is that it
- clarifies the transfer's point of view. To keep the postings in
- separate files, just separate the two transactions that were joined
- above. For example, for both the expense and the pay-back shown
- above, the following four transactions would be created. Two in your
- personal ledger file:
- @smallexample @c input:990E0D1
- 2004/09/29 Circuit City
- Assets:Reimbursements:Company XYZ $100.00
- Liabilities:MasterCard $-100.00
- 2004/10/15 Company XYZ
- Assets:Checking $100.00
- Assets:Reimbursements:Company XYZ $-100.00
- @end smallexample
- And two in your company ledger file:
- @smallexample @c input:990E0D1
- apply account Company XYZ
- 2004/09/29 Circuit City
- Expenses:Computer:Software $100.00
- Accounts Payable:Your Name $-100.00
- 2004/10/15 Company XYZ
- Accounts Payable:Your Name $100.00
- Assets:Checking $-100.00
- end apply account
- @end smallexample
- (Note: The @code{apply account} above means that all accounts
- mentioned in the file are children of that account. In this case it
- means that all activity in the file relates to Company XYZ).
- After creating these transactions, you will always know that $100.00
- was spent using your MasterCard on behalf of Company XYZ, and that
- Company XYZ spent the money on computer software and paid it back
- about two weeks later.
- @smallexample @c command:990E0D1
- $ ledger balance --no-total
- @end smallexample
- @smallexample @c output:990E0D1
- $100.00 Assets:Checking
- 0 Company XYZ
- $-100.00 Assets:Checking
- $100.00 Expenses:Computer:Software
- $-100.00 Liabilities:MasterCard
- @end smallexample
- @node Commodities and Currencies, Accounts and Inventories, Assets and Liabilities, Principles of Accounting with Ledger
- @section Commodities and Currencies
- Ledger makes no assumptions about the commodities you use; it only
- requires that you specify a commodity. The commodity may be any
- non-numeric string that does not contain a period, comma, forward
- slash or at-sign. It may appear before or after the amount, although
- it is assumed that symbols appearing before the amount refer to
- currencies, while non-joined symbols appearing after the amount refer
- to commodities. Here are some valid currency and commodity
- specifiers:
- @smallexample
- $20.00 ; currency: twenty US dollars
- 40 AAPL ; commodity: 40 shares of Apple stock
- 60 DM ; currency: 60 Deutsch Mark
- £50 ; currency: 50 British pounds
- 50 EUR ; currency: 50 Euros (or use appropriate symbol)
- @end smallexample
- Ledger will examine the first use of any commodity to determine how
- that commodity should be printed on reports. It pays attention to
- whether the name of commodity was separated from the amount, whether
- it came before or after, the precision used in specifying the amount,
- whether thousand marks were used, etc. This is done so that printing
- the commodity looks the same as the way you use it.
- An account may contain multiple commodities, in which case it will
- have separate totals for each. For example, if your brokerage account
- contains both cash, gold, and several stock quantities, the balance
- might look like:
- @smallexample
- $200.00
- 100.00 AU
- AAPL 40
- BORL 100
- FEQTX 50 Assets:Brokerage
- @end smallexample
- This balance report shows how much of each commodity is in your
- brokerage account.
- Sometimes, you will want to know the current street value of your
- balance, and not the commodity totals. For this to happen, you must
- specify what the current price is for each commodity. The price can
- be any commodity, in which case the balance will be computed in terms
- of that commodity. The usual way to specify prices is with a price
- history file, which might look like this:
- @smallexample @c input:validate
- P 2004/06/21 02:18:01 FEQTX $22.49
- P 2004/06/21 02:18:01 BORL $6.20
- P 2004/06/21 02:18:02 AAPL $32.91
- P 2004/06/21 02:18:02 AU $400.00
- @end smallexample
- @findex --price-db @var{FILE}
- @findex --market
- Specify the price history to use with the @option{--price-db @var{FILE}}
- option, with the @option{--market (-V)} option to report in terms of
- current market value:
- @smallexample
- $ ledger --price-db prices.db -V balance brokerage
- @end smallexample
- The balance for your brokerage account will be reported in US dollars,
- since the prices database uses that currency.
- @smallexample
- $40880.00 Assets:Brokerage
- @end smallexample
- You can convert from any commodity to any other commodity. Let's say
- you had $5000 in your checking account, and for whatever reason you
- wanted to know many ounces of gold that would buy, in terms of the
- current price of gold:
- @smallexample
- $ ledger -T "@{1 AU@}*(O/P@{1 AU@})" balance checking
- @end smallexample
- Although the total expression appears complex, it is simply saying
- that the reported total should be in multiples of AU units, where the
- quantity is the account total divided by the price of one AU. Without
- the initial multiplication, the reported total would still use the
- dollars commodity, since multiplying or dividing amounts always keeps
- the left value's commodity. The result of this command might be:
- @smallexample
- 14.01 AU Assets:Checking
- @end smallexample
- @menu
- * Commodity price histories::
- * Commodity equivalences::
- @end menu
- @node Commodity price histories, Commodity equivalences, Commodities and Currencies, Commodities and Currencies
- @subsection Commodity price histories
- Whenever a commodity is purchased using a different commodity (such as
- a share of common stock using dollars), it establishes a price for
- that commodity on that day. It is also possible, by recording price
- details in a ledger file, to specify other prices for commodities at
- any given time. Such price transactions might look like those below:
- @smallexample @c input:validate
- P 2004/06/21 02:17:58 TWCUX $27.76
- P 2004/06/21 02:17:59 AGTHX $25.41
- P 2004/06/21 02:18:00 OPTFX $39.31
- P 2004/06/21 02:18:01 FEQTX $22.49
- P 2004/06/21 02:18:02 AAPL $32.91
- @end smallexample
- By default, ledger will not consider commodity prices when generating
- its various reports. It will always report balances in terms of the
- commodity total, rather than the current value of those commodities.
- To enable pricing reports, use one of the commodity reporting options.
- @node Commodity equivalences, , Commodity price histories, Commodities and Currencies
- @subsection Commodity equivalences
- Sometimes a commodity has several forms which are all equivalent. An
- example of this is time. Whether tracked in terms of minutes, hours
- or days, it should be possible to convert between the various forms.
- Doing this requires the use of commodity equivalences.
- For example, you might have the following two postings, one which
- transfers an hour of time into a @samp{Billable} account, and another
- which decreases the same account by ten minutes. The resulting report
- will indicate that fifty minutes remain:
- @smallexample @c input:DF3FEBE
- 2005/10/01 Work done for company
- Billable:Client 1h
- Project:XYZ
- 2005/10/02 Return ten minutes to the project
- Project:XYZ 10m
- Billable:Client
- @end smallexample
- Reporting the balance for this ledger file produces:
- @smallexample @c command:DF3FEBE
- $ ledger --no-total balance Billable Project
- @end smallexample
- @smallexample @c output:DF3FEBE
- 50.0m Billable:Client
- -50.0m Project:XYZ
- @end smallexample
- @findex C
- This example works because ledger already knows how to handle seconds,
- minutes and hours, as part of its time tracking support. Defining
- other equivalences is simple. The following is an example that
- creates data equivalences, helpful for tracking bytes, kilobytes,
- megabytes, and more:
- @smallexample @c input:validate
- C 1.00 Kb = 1024 b
- C 1.00 Mb = 1024 Kb
- C 1.00 Gb = 1024 Mb
- C 1.00 Tb = 1024 Gb
- @end smallexample
- Each of these definitions correlates a commodity (such as @samp{Kb})
- and a default precision, with a certain quantity of another commodity.
- In the above example, kilobytes are reported with two decimal places
- of precision and each kilobyte is equal to 1024 bytes.
- Equivalence chains can be as long as desired. Whenever a commodity
- would report as a decimal amount (less than @samp{1.00}), the next
- smallest commodity is used. If a commodity could be reported in terms
- of a higher commodity without resulting to a partial fraction, then
- the larger commodity is used.
- @node Accounts and Inventories, Understanding Equity, Commodities and Currencies, Principles of Accounting with Ledger
- @section Accounts and Inventories
- Since Ledger's accounts and commodity system is so flexible, you can
- have accounts that don't really exist, and use commodities that no one
- else recognizes. For example, let's say you are buying and selling
- various items in EverQuest, and want to keep track of them using a
- ledger. Just add items of whatever quantity you wish into your
- EverQuest account:
- @smallexample @c input:48F4E47
- 9/29 Get some stuff at the Inn
- Places:Black's Tavern -3 Apples
- Places:Black's Tavern -5 Steaks
- EverQuest:Inventory
- @end smallexample
- Now your EverQuest:Inventory has 3 apples and 5 steaks in it. The
- amounts are negative, because you are taking @emph{from} Black's
- Tavern in order to add to your Inventory account. Note that you don't
- have to use @samp{Places:Black's Tavern} as the source account. You
- could use @samp{EverQuest:System} to represent the fact that you
- acquired them online. The only purpose for choosing one kind of
- source account over another is to generate more informative reports
- later on. The more you know, the better the analysis you can perform.
- If you later sell some of these items to another player, the
- transaction would look like:
- @smallexample @c input:48F4E47
- 10/2 Sturm Brightblade
- EverQuest:Inventory -2 Steaks
- EverQuest:Inventory 15 Gold
- @end smallexample
- Now you've turned 2 steaks into 15 gold, courtesy of your customer,
- Sturm Brightblade.
- @smallexample @c command:48F4E47
- $ ledger balance EverQuest
- @end smallexample
- @smallexample @c output:48F4E47
- 3 Apples
- 15 Gold
- 3 Steaks EverQuest:Inventory
- @end smallexample
- @node Understanding Equity, Dealing with Petty Cash, Accounts and Inventories, Principles of Accounting with Ledger
- @section Understanding Equity
- The most confusing transaction in any ledger will be your equity
- account---because starting balances can't come out of nowhere.
- When you first start your ledger, you will likely already have money
- in some of your accounts. Let's say there's $100 in your checking
- account; then add a transaction to your ledger to reflect this amount.
- Where will the money come from? The answer: your equity.
- @smallexample @c input:validate
- 10/2 Opening Balance
- Assets:Checking $100.00
- Equity:Opening Balances
- @end smallexample
- But what is equity? You may have heard of equity when people talked
- about house mortgages, as ``the part of the house that you own''.
- Basically, equity is like the value of something. If you own a car
- worth $5000, then you have $5000 in equity in that car. In order to
- turn that car (a commodity) into a cash flow, or a credit to your bank
- account, you will have to debit the equity by selling it.
- When you start a ledger, you are probably already worth something.
- Your net worth is your current equity. By transferring the money in
- the ledger from your equity to your bank accounts, you are crediting
- the ledger account based on your prior equity. That is why, when you
- look at the balance report, you will see a large negative number for
- Equity that never changes: Because that is what you were worth (what
- you debited from yourself in order to start the ledger) before the
- money started moving around. If the total positive value of your
- assets is greater than the absolute value of your starting equity, it
- means you are making money.
- Clear as mud? Keep thinking about it. Until you figure it out, put
- @code{not Equity} at the end of your balance command, to remove the
- confusing figure from the total.
- @node Dealing with Petty Cash, Working with multiple funds and accounts, Understanding Equity, Principles of Accounting with Ledger
- @section Dealing with Petty Cash
- Something that stops many people from keeping a ledger at all is the
- insanity of tracking small cash expenses. They rarely generate a
- receipt, and there are often a lot of small postings, rather than
- a few large ones, as with checks.
- One solution is: don't bother. Move your spending to a debit card,
- but in general ignore cash. Once you withdraw it from the ATM, mark
- it as already spent to an @samp{Expenses:Cash} category:
- @smallexample @c input:validate
- 2004/03/15 ATM
- Expenses:Cash $100.00
- Assets:Checking
- @end smallexample
- If at some point you make a large cash expense that you want to track,
- just @emph{move} the amount of the expense from @samp{Expenses:Cash}
- into the target account:
- @smallexample @c input:validate
- 2004/03/20 Somebody
- Expenses:Food $65.00
- Expenses:Cash
- @end smallexample
- This way, you can still track large cash expenses, while ignoring all
- of the smaller ones.
- @node Working with multiple funds and accounts, , Dealing with Petty Cash, Principles of Accounting with Ledger
- @section Working with multiple funds and accounts
- There are situations when the accounts you're tracking are different
- between your clients and the financial institutions where money is
- kept. An example of this is working as the treasurer for a religious
- institution. From the secular point of view, you might be working
- with three different accounts:
- @itemize
- @item Checking
- @item Savings
- @item Credit Card
- @end itemize
- From a religious point of view, the community expects to divide its
- resources into multiple ``funds'', from which it makes purchases or
- reserves resources for later:
- @itemize
- @item School fund
- @item Building fund
- @item Community fund
- @end itemize
- The problem with this kind of setup is that, when you spend money, it
- comes from two or more places at once: the account and the fund. And
- yet, the correlation of amounts between funds and accounts is rarely
- one-to-one. What if the school fund has @samp{$500.00}, but
- @samp{$400.00} of that comes from Checking, and @samp{$100.00} from
- Savings?
- Traditional finance packages require that the money reside in only one
- place. But there are really two ``views'' of the data: from the
- account point of view and from the fund point of view---yet both sets
- should reflect the same overall expenses and cash flow. It's simply
- where the money resides that differs.
- This situation can be handled one of two ways. The first is using
- virtual postings to represent the fact that money is moving to and
- from two kind of accounts at the same time:
- @smallexample @c input:396F24E
- 2004/03/20 Contributions
- Assets:Checking $500.00
- Income:Donations
- 2004/03/25 Distribution of donations
- [Funds:School] $300.00
- [Funds:Building] $200.00
- [Assets:Checking] $-500.00
- @end smallexample
- The use of square brackets in the second transaction ensures that the
- virtual postings balance to zero. Now money can be spent directly
- from a fund at the same time as money is drawn from a physical
- account:
- @smallexample @c input:396F24E
- 2004/03/25 Payment for books (paid from Checking)
- Expenses:Books $100.00
- Assets:Checking $-100.00
- (Funds:School) $-100.00
- @end smallexample
- When reports are generated, by default they'll appear in terms of the
- funds. In this case, you will likely want to mask out your
- @samp{Assets} account, because otherwise the balance won't make much
- sense:
- @smallexample @c command:396F24E
- $ ledger --no-total bal not ^Assets
- @end smallexample
- @smallexample @c output:396F24E
- $100.00 Expenses:Books
- $400.00 Funds
- $200.00 Building
- $200.00 School
- $-500.00 Income:Donations
- @end smallexample
- @findex --real
- If the @option{--real} option is used, the report will be in terms of
- the real accounts:
- @smallexample @c command:2F1CB75,with_input:396F24E
- $ ledger --real --no-total bal
- @end smallexample
- @smallexample @c output:2F1CB75
- $400.00 Assets:Checking
- $100.00 Expenses:Books
- $-500.00 Income:Donations
- @end smallexample
- If more asset accounts are needed as the source of a posting, just
- list them as you would normally, for example:
- @smallexample @c input:validate
- 2004/03/25 Payment for books (paid from Checking)
- Expenses:Books $100.00
- Assets:Checking $-50.00
- Liabilities:Credit Card $-50.00
- (Funds:School) $-100.00
- @end smallexample
- The second way of tracking funds is to use transaction codes. In this
- respect the codes become like virtual accounts that embrace the entire
- set of postings. Basically, we are associating a transaction with a
- fund by setting its code. Here are two transactions that deposit money
- into, and spend money from, the @samp{Funds:School} fund:
- @smallexample @c input:AD068BA
- 2004/03/25 (Funds:School) Donations
- Assets:Checking $100.00
- Income:Donations
- 2004/03/25 (Funds:Building) Donations
- Assets:Checking $20.00
- Income:Donations
- 2004/04/25 (Funds:School) Payment for books
- Expenses:Books $50.00
- Assets:Checking
- @end smallexample
- Note how the accounts now relate only to the real accounts, and any
- balance or register reports will reflect this. That the transactions
- relate to a particular fund is kept only in the code.
- @findex --payee=code
- @findex --by-payee
- How does this become a fund report? By using the
- @option{--payee=code} option, you can generate a register report
- where the payee for each posting shows the code. Alone, this is not
- terribly interesting; but when combined with the @option{--by-payee
- (-P)} option, you will now see account subtotals for any postings
- related to a specific fund. So, to see the current monetary balances of
- all funds, the command would be:
- @smallexample @c command:AD068BA
- $ ledger --payee=code -P reg ^Assets
- @end smallexample
- @smallexample @c output:AD068BA
- 04-Mar-25 Funds:Building Assets:Checking $20.00 $20.00
- 04-Mar-25 Funds:School Assets:Checking $50.00 $70.00
- @end smallexample
- Or to see a particular fund's expenses, the @samp{School} fund in this
- case:
- @smallexample @c command:E30B2FC,with_input:AD068BA
- $ ledger --payee=code -P reg ^Expenses and code School
- @end smallexample
- @smallexample @c output:E30B2FC
- 04-Apr-25 Funds:School Expenses:Books $50.00 $50.00
- @end smallexample
- Both approaches yield different kinds of flexibility, depending on how
- you prefer to think of your funds: as virtual accounts, or as tags
- associated with particular transactions. Your own tastes will decide
- which is best for your situation.
- @node Keeping a Journal, Transactions, Principles of Accounting with Ledger, Top
- @chapter Keeping a Journal
- The most important part of accounting is keeping a good journal. If
- you have a good journal, tools can be written to work whatever
- mathematical tricks you need to better understand your spending
- patterns. Without a good journal, no tool, however smart, can help
- you.
- The Ledger program aims at making journal transactions as simple as
- possible. Since it is a command-line tool, it does not provide a user
- interface for keeping a journal. If you require an user interface to
- maintain journal transactions GnuCash is a good alternative.
- If you are not using GnuCash, but a text editor to maintain your
- journal, read on. Ledger has been designed to make data transactions
- as simple as possible, by keeping the journal format easy, and also by
- automagically determining as much information as possible based on the
- nature of your transactions.
- For example, you do not need to tell Ledger about the accounts you
- use. Any time Ledger sees a posting involving an account it knows
- nothing about, it will create it@footnote{This also means if you
- misspell an account it will end up getting counted separately from what
- you intended. The provided Emacs major mode provides for automatically
- filling in account names.}. If you use a commodity that is new to
- Ledger, it will create that commodity, and determine its display
- characteristics (placement of the symbol before or after the amount,
- display precision, etc.) based on how you used the commodity in the
- posting.
- @menu
- * The Most Basic Entry::
- * Starting up::
- * Structuring your Accounts::
- * Commenting on your Journal::
- * Currency and Commodities::
- * Keeping it Consistent::
- * Journal Format::
- * Converting from other formats::
- * Archiving Previous Years::
- @end menu
- @node The Most Basic Entry, Starting up, Keeping a Journal, Keeping a Journal
- @section The Most Basic Entry
- Here is the Pacific Bell example from above, given as a Ledger
- posting, with the addition of a check number:
- @smallexample @c input:validate
- 9/29 (1023) Pacific Bell
- Expenses:Utilities:Phone $23.00
- Assets:Checking $-23.00
- @end smallexample
- As you can see, it is very similar to what would be written on paper,
- minus the computed balance totals, and adding in account names that
- work better with Ledger's scheme of things. In fact, since Ledger is
- smart about many things, you don't need to specify the balanced
- amount, if it is the same as the first line:
- @smallexample @c input:validate
- 9/29 (1023) Pacific Bell
- Expenses:Utilities:Phone $23.00
- Assets:Checking
- @end smallexample
- For this transaction, Ledger will figure out that $-23.00 must come
- from @samp{Assets:Checking} in order to balance the transaction.
- Also note the structure of the account entries. There is an implied
- hierarchy established by separating with colons (@pxref{Structuring your
- Accounts}).
- @cindex spaces in postings
- @cindex posting format details
- @strong{The format is very flexible and it isn't necessary that you
- indent and space out things exactly as shown. The only requirements
- are that the start of the transaction (the date typically) is at the
- beginning of the first line of the transaction, and the accounts are
- indented by at least one space. If you omit the leading spaces in the
- account lines Ledger will generate an error. There must be at least
- two spaces, or a tab, between the amount and the account. If you do
- not have adequate separation between the amount and the account Ledger
- will give an error and stop calculating.}
- @node Starting up, Structuring your Accounts, The Most Basic Entry, Keeping a Journal
- @section Starting up
- @cindex initial equity
- @cindex beginning ledger
- @cindex opening balance
- Unless you have recently arrived from another planet, you already have
- a financial state. You need to capture that financial state so that
- Ledger has a starting point.
- At some convenient point in time you knew the balances and outstanding
- obligation of every financial account you have. Those amounts form the
- basis of the opening entry for ledger. For example if you chose the
- beginning of 2011 as the date to start tracking finances with ledger,
- your opening balance entry could look like this:
- @smallexample @c input:validate
- 2011/01/01 * Opening Balance
- Assets:Joint Checking $800.14
- Assets:Other Checking $63.44
- Assets:Savings $2805.54
- Assets:Investments:401K:Deferred 100.0000 VIFSX @@ $80.5227
- Assets:Investments:401K:Matching 50.0000 VIFSX @@ $83.7015
- Assets:Investments:IRA 250.0000 VTHRX @@ $20.5324
- Liabilities:Mortgage $-175634.88
- Liabilities:Car Loan $-3494.26
- Liabilities:Visa -$1762.44
- Equity:Opening Balances
- @end smallexample
- There is nothing special about the name ``Opening Balances'' as the
- payee of the account name, anything convenient that you understand will
- work.
- @node Structuring your Accounts, Commenting on your Journal, Starting up, Keeping a Journal
- @section Structuring your Accounts
- @cindex accounts, naming
- @cindex naming accounts
- There really are no requirements for how you do this, but to preserve
- your sanity we suggest some very basic structure to your accounting
- system.
- At the highest level you have five sorts of accounts:
- @enumerate
- @item Expenses: where money goes,
- @item Assets: where money sits,
- @item Income: where money comes from,
- @item Liabilities: money you owe,
- @item Equity: the real value of your property.
- @end enumerate
- Starting the structure off this way will make it simpler for you to get
- answers to the questions you really need to ask about your finances.
- Beneath these top level accounts you can have any level of detail you
- desire. For example, if you want to keep specific track of how much
- you spend on burgers and fries, you could have the following:
- @smallexample @c input:validate
- Expenses:Food:Hamburgers and Fries
- @end smallexample
- @node Commenting on your Journal, Currency and Commodities, Structuring your Accounts, Keeping a Journal
- @section Commenting on your Journal
- @cindex comments, characters
- @cindex block comments
- @cindex comments, block
- Comments are generally started using a @samp{;}. However, in order to
- increase compatibility with other text manipulation programs and
- methods, four additional comment characters are valid if used at the
- beginning of a line: @samp{#}, @samp{|}, and @samp{*} and @samp{%}.
- Block comments can be made by use @code{comment} ... @code{end
- comment}.
- @smallexample @c input:validate
- ; This is a single line comment,
- # and this,
- % and this,
- | and this,
- * and this.
- comment
- This is a block comment with
- multiple lines
- end comment
- @end smallexample
- There are several forms of comments within a transaction, for example:
- @smallexample @c input:validate
- ; this is a global comment that is not applied to a specific transaction
- ; it can start with any of the five characters but is not included in the
- ; output from 'print' or 'output'
- 2011/12/11 Something Sweet
- ; German Chocolate Cake
- ; :Broke Diet:
- Expenses:Food $10.00 ; Friends: The gang
- Assets:Credit Union:Checking
- @end smallexample
- @noindent
- The first comment is global and Ledger will not attach it to any
- specific transactions. The comments within the transaction must all
- start with @samp{;} and are preserved as part of the transaction. The
- @samp{:} indicates meta-data and tags (@pxref{Metadata}).
- @node Currency and Commodities, Keeping it Consistent, Commenting on your Journal, Keeping a Journal
- @section Currency and Commodities
- @cindex currency
- @cindex commodity
- Ledger is agnostic when it comes to how you value your accounts.
- Dollars, Euros, Pounds, Francs, Shares etc. are all just ``commodities''.
- Holdings in stocks, bonds, mutual funds and other financial
- instruments can be labeled using whatever is convenient for you (stock
- ticker symbols are suggested for publicly traded assets).@footnote{You
- can track @emph{anything}, even time or distance traveled. As long as
- it cannot be created or destroyed inside your accounting system.}
- For the rest of this manual, we will only use the word ``commodities''
- when referring to the units on a transaction value.
- This is fundamentally different than many common accounting packages,
- which assume the same currency throughout all of your accounts. This
- means if you typically operate in Euros, but travel to the US and have
- some expenses, you would have to do the currency conversion
- @emph{before} you made the entry into your financial system. With
- ledger this is not required. In the same journal you can have entries
- in any or all commodities you actually hold. You can use the
- reporting capabilities to convert all commodities to a single
- commodity for reporting purposes without ever changing the underlying
- entry.
- For example, the following entries reflect transactions made for a
- business trip to Europe from the US:
- @smallexample @c input:82150D9
- 2011/09/23 Cash in Munich
- Assets:Cash €50.00
- Assets:Checking $-66.00
- 2011/09/24 Dinner in Munich
- Expenses:Business:Travel €35.00
- Assets:Cash
- @end smallexample
- This says that $66.00 came out of checking and turned into 50
- Euros. The implied exchange rate was $1.32. Then 35.00 Euros were
- spent on Dinner in Munich.
- Running a ledger balance report shows:
- @smallexample @c command:82150D9
- $ ledger -f example.dat bal
- @end smallexample
- @smallexample @c output:82150D9
- $-66.00
- €15.00 Assets
- €15.00 Cash
- $-66.00 Checking
- €35.00 Expenses:Business:Travel
- --------------------
- $-66.00
- €50.00
- @end smallexample
- The top two lines show my current assets as $-66.00 in checking (in
- this very short example I didn't establish opening an opening balance
- for the checking account) and €15.00. After spending on dinner I have
- €15.00 in my wallet. The bottom line balances to zero, but is shown
- in two lines since we haven't told ledger to convert commodities.
- @menu
- * Naming Commodities::
- * Buying and Selling Stock::
- * Fixing Lot Prices::
- * Complete control over commodity pricing::
- @end menu
- @node Naming Commodities, Buying and Selling Stock, Currency and Commodities, Currency and Commodities
- @subsection Naming Commodities
- Commodity names can have any character, including white-space.
- However, if you include white-space or numeric characters, the
- commodity name must be enclosed in double quotes @samp{"}:
- @smallexample @c input:validate
- 1999/06/09 ! Achat
- Actif:SG PEE STK 49.957 "Arcancia Équilibre 454"
- Actif:SG PEE STK $-234.90
- 2000/12/08 ! Achat
- Actif:SG PEE STK 215.796 "Arcancia Équilibre 455"
- Actif:SG PEE STK $-10742.54
- @end smallexample
- @node Buying and Selling Stock, Fixing Lot Prices, Naming Commodities, Currency and Commodities
- @subsection Buying and Selling Stock
- @cindex buying stock
- Buying stock is a typical example that many will use that involves
- multiple commodities in the same transaction. The type of the share
- (AAPL for Apple Inc.) and the share purchase price in the currency
- unit you made the purchase in ($ for AAPL). Yes, the typical
- convention is as follows:
- @smallexample @c input:validate
- 2004/05/01 Stock purchase
- Assets:Broker 50 AAPL @@ $30.00
- Expenses:Broker:Commissions $19.95
- Assets:Broker $-1,519.95
- @end smallexample
- This assumes you have a brokerage account that is capable of managing
- both liquid and commodity assets. Now, on the day of the sale:
- @smallexample @c input:validate
- 2005/08/01 Stock sale
- Assets:Broker -50 AAPL @{$30.00@} @@ $50.00
- Expenses:Broker:Commissions $19.95
- Income:Capital Gains $-1,000.00
- Assets:Broker $2,480.05
- @end smallexample
- @noindent
- You can, of course, elide the amount of the last posting. It is there
- for clarity's sake.
- The @samp{@{$30.00@}} is a lot price. You can also use a lot date,
- @samp{[2004/05/01]}, or both, in case you have several lots of the
- same price/date and your taxation model is based on
- longest-held-first.
- @node Fixing Lot Prices, Complete control over commodity pricing, Buying and Selling Stock, Currency and Commodities
- @subsection Fixing Lot Prices
- @cindex fixing lot prices
- @cindex consumable commodity pricing
- Commodities that you keep in order to sell at a later time have
- a variable value that fluctuates with the market prices. Commodities
- that you consume should not fluctuate in value, but stay at the lot
- price they were purchased at. As an extension of ``lot pricing'', you
- can fix the per-unit price of a commodity.
- For example, say you buy 10 gallons of gas at $1.20. In future
- ``value'' reports, you don't want these gallons reported in terms of
- today's price, but rather the price when you bought it. At the same
- time, you also want other kinds of commodities---like stocks---
- reported in terms of today's price.
- This is supported as follows:
- @smallexample @c input:validate
- 2009/01/01 Shell
- Expenses:Gasoline 11 GAL @{=$2.299@}
- Assets:Checking
- @end smallexample
- This transaction actually introduces a new commodity, @samp{GAL
- @{=$2.29@}}, whose market value disregards any future changes in the
- price of gasoline.
- If you do not want price fixing, you can specify this same transaction
- in one of two ways, both equivalent (note the lack of the equal sign
- compared to the transaction above):
- @smallexample @c input:validate
- 2009/01/01 Shell
- Expenses:Gasoline 11 GAL @{$2.299@}
- Assets:Checking
- 2009/01/01 Shell
- Expenses:Gasoline 11 GAL @@ $2.299
- Assets:Checking
- @end smallexample
- There is no difference in meaning between these two forms. Why do
- both exist, you ask? To support things like this:
- @smallexample @c input:validate
- 2009/01/01 Shell
- Expenses:Gasoline 11 GAL @{=$2.299@} @@ $2.30
- Assets:Checking
- @end smallexample
- This transaction says that you bought 11 gallons priced at $2.299 per
- gallon at a @emph{cost to you} of $2.30 per gallon. Ledger
- auto-generates a balance posting in this case to Equity:Capital Losses
- to reflect the 1.1 cent difference, which is then balanced by
- Assets:Checking because its amount is null.
- @node Complete control over commodity pricing, , Fixing Lot Prices, Currency and Commodities
- @subsection Complete control over commodity pricing
- @findex --market
- @findex --exchange @var{COMMODITY}
- Ledger allows you to have very detailed control over how your
- commodities are valued. You can fine tune the results given using the
- @option{--market} or @option{--exchange @var{COMMODITY}} options. There
- are now several points of interception; you can specify the valuation
- method:
- @enumerate
- @item on a commodity itself,
- @item on a posting, via metadata (effect is largely the same as #1),
- @item on an xact, which then applies to all postings in that xact,
- @item on any posting via an automated transaction,
- @item on a per-account basis,
- @item on a per-commodity basis,
- @item by changing the journal default of @code{market}.
- @end enumerate
- Fixated pricing (such as @samp{@{=$20@}}) still plays a role in this
- scheme. As far as valuation goes, it's shorthand for writing
- @samp{((s,d,t -> market($20,d,t)))}.
- A valuation function receives three arguments:
- @table @code
- @item source
- A string identifying the commodity whose price is being asked for
- (example: @samp{EUR}).
- @item date
- The reference date the price should be relative.
- @item target
- A string identifying the ``target'' commodity, or the commodity the
- returned price should be in. This argument is null if @option{--market}
- was used instead of @option{--exchange @var{COMMODITY}}.
- @end table
- The valuation function should return an amount. If you've written
- your function in Python, you can return something like
- @samp{Amount("$100")}. If the function returns an explicit value,
- that value is always used, regardless of the commodity, the date, or
- the desired target commodity. For example,
- @smallexample @c input:validate
- define myfunc_seven(s, d, t) = 7 EUR
- @end smallexample
- In order to specify a fixed price, but still valuate that price into
- the target commodity, use something like this:
- @smallexample @c input:validate
- define myfunc_five(s, d, t) = market(5 EUR, d, t)
- @end smallexample
- The @code{value} directive sets the valuation used for all commodities
- used in the rest of the data stream. This is the fallback, if nothing
- more specific is found.
- @smallexample @c input:validate
- value myfunc_seven
- @end smallexample
- You can set a specific valuation function on a per-commodity basis.
- Instead of defining a function, you can also pass a lambda.
- @smallexample @c input:validate
- commodity $
- value s, d, t -> 6 EUR
- @end smallexample
- Each account can also provide a default valuation function for any
- commodities transferred to that account.
- @smallexample @c input:validate
- account Expenses:Food5
- value myfunc_five
- @end smallexample
- The metadata field @samp{Value}, if found, overrides the valuation
- function on a transaction-wide or per-posting basis.
- @smallexample @c input:validate
- = @@XACT and Food
- ; Value:: 8 EUR
- (Equity) $1
- = @@POST and Dining
- (Expenses:Food9) $1
- ; Value:: 9 EUR
- @end smallexample
- Lastly, you can specify the valuation function/value for any specific
- amount using the @samp{(( ))} commodity annotation.
- @smallexample @c input:814A366
- 2012-03-02 KFC
- Expenses:Food2 $1 ((2 EUR))
- Assets:Cash2
- 2012-03-03 KFC
- Expenses:Food3 $1
- ; Value:: 3 EUR
- Assets:Cash3
- 2012-03-04 KFC
- ; Value:: 4 EUR
- Expenses:Food4 $1
- Assets:Cash4
- 2012-03-05 KFC
- Expenses:Food5 $1
- Assets:Cash5
- 2012-03-06 KFC
- Expenses:Food6 $1
- Assets:Cash6
- 2012-03-07 KFC
- Expenses:Food7 1 CAD
- Assets:Cas7
- 2012-03-08 XACT
- Expenses:Food8 $1
- Assets:Cash8
- 2012-03-09 POST
- Expenses:Dining9 $1
- Assets:Cash9
- @end smallexample
- @smallexample @c command:814A366
- $ ledger reg -V food
- @end smallexample
- @smallexample @c output:814A366
- 12-Mar-02 KFC Expenses:Food2 2 EUR 2 EUR
- 12-Mar-03 KFC Expenses:Food3 3 EUR 5 EUR
- 12-Mar-04 KFC Expenses:Food4 4 EUR 9 EUR
- 12-Mar-05 KFC Expenses:Food5 $1 $1
- 9 EUR
- 12-Mar-06 KFC Expenses:Food6 $1 $2
- 9 EUR
- 12-Mar-07 KFC Expenses:Food7 1 CAD $2
- 1 CAD
- 9 EUR
- 12-Mar-08 XACT Expenses:Food8 $1 $3
- 1 CAD
- 9 EUR
- @end smallexample
- @node Keeping it Consistent, Journal Format, Currency and Commodities, Keeping a Journal
- @section Keeping it Consistent
- @findex --strict
- @findex accounts
- Sometimes Ledger's flexibility can lead to difficulties. Using a
- freeform text editor to enter transactions makes it easy to keep the
- data, but also easy to enter accounts or payees inconsistently or with
- spelling errors.
- In order to combat inconsistency you can define allowable accounts and
- payees. For simplicity, create a separate text file and define accounts
- and payees like
- @smallexample @c input:validate
- account Expenses
- account Expenses:Utilities
- @end smallexample
- Using the @option{--strict} option will cause Ledger to complain if any
- accounts are not previously defined:
- @smallexample
- $ ledger bal --strict
- Warning: "FinanceData/Master.dat", line 6: Unknown account 'Liabilities:Tithe Owed'
- Warning: "FinanceData/Master.dat", line 8: Unknown account 'Liabilities:Tithe Owed'
- Warning: "FinanceData/Master.dat", line 15: Unknown account 'Allocation:Equities:Domestic'
- @end smallexample
- If you have a large Ledger register already created use the
- @command{accounts} command to get started:
- @smallexample @c command:validate
- $ ledger accounts >> Accounts.dat
- @end smallexample
- @noindent
- You will have to edit this file to add the @code{account} directive in
- front of every line.
- @node Journal Format, Converting from other formats, Keeping it Consistent, Keeping a Journal
- @section Journal Format
- The ledger file format is quite simple, but also very flexible. It
- supports many options, though typically the user can ignore most of
- them. They are summarized below.
- @menu
- * Transactions and Comments::
- * Command Directives::
- @end menu
- @node Transactions and Comments, Command Directives, Journal Format, Journal Format
- @subsection Transactions and Comments
- The initial character of each line determines what the line means, and
- how it should be interpreted. Allowable initial characters are:
- @table @code
- @item NUMBER
- A line beginning with a number denotes a transaction. It may be
- followed by any number of lines, each beginning with white-space, to
- denote the transaction's account postings. The format of the first
- line is:
- @smallexample
- DATE[=EDATE] [*|!] [(CODE)] DESC
- @end smallexample
- If @samp{*} appears after the date (with optional effective date), it
- indicates the transaction is ``cleared'', which can mean whatever the
- user wants it to mean. If @samp{!} appears after the date, it
- indicates the transaction is ``pending''; i.e., tentatively cleared
- from the user's point of view, but not yet actually cleared. If
- a @code{CODE} appears in parentheses, it may be used to indicate
- a check number, or the type of the posting. Following these is the
- payee, or a description of the posting.
- The format of each following posting is:
- @smallexample
- ACCOUNT AMOUNT [; NOTE]
- @end smallexample
- The @code{ACCOUNT} may be surrounded by parentheses if it is a virtual
- posting, or square brackets if it is a virtual posting that
- must balance. The @code{AMOUNT} can be followed by a per-unit
- posting cost, by specifying @code{@@ AMOUNT}, or a complete
- posting cost with @code{@@@@ AMOUNT}. Lastly, the @code{NOTE} may
- specify an actual and/or effective date for the posting by using
- the syntax @code{[ACTUAL_DATE]} or @code{[=EFFECTIVE_DATE]} or
- @code{[ACTUAL_DATE=EFFECTIVE_DATE]} (@pxref{Virtual postings}).
- @item P
- @findex --download
- @findex P
- @cindex historical prices
- Specifies a historical price for a commodity. These are usually found
- in a pricing history file (see the @option{--download (-Q)} option).
- The syntax is:
- @smallexample
- P DATE SYMBOL PRICE
- @end smallexample
- @item =
- @findex =
- @cindex automated transaction
- @cindex transaction, automated
- An automated transaction. A value expression must appear after the
- equal sign.
- After this initial line there should be a set of one or more postings,
- just as if it were a normal transaction. If the amounts of the postings
- have no commodity, they will be applied as multipliers to whichever real
- posting is matched by the value expression (@pxref{Automated
- Transactions}).
- @item ~
- @findex ~
- @cindex periodic transaction
- @cindex transaction, periodic
- A periodic transaction. A period expression must appear after the tilde.
- After this initial line there should be a set of one or more
- postings, just as if it were a normal transaction.
- @item ; # % | *
- @findex comment
- @cindex comments
- A line beginning with a semicolon, pound, percent, bar or asterisk
- indicates a comment, and is ignored. Comments will not be returned in
- a ``print'' response.
- @item indented ;
- @cindex tags
- If the semicolon is indented and occurs inside a transaction, it is
- parsed as a persistent note for its preceding category. These notes or
- tags can be used to augment the reporting and filtering capabilities of
- Ledger.
- @end table
- @node Command Directives, , Transactions and Comments, Journal Format
- @subsection Command Directives
- @findex --strict
- @findex --pedantic
- @table @code
- @item beginning of line
- Command directives must occur at the beginning of a line. Use of
- @samp{!} and @samp{@@} is deprecated.
- @item account
- @findex account
- @cindex pre-declare account
- Pre-declare valid account names. This only has an effect if
- @option{--strict} or @option{--pedantic} is used (see below). The
- @code{account} directive supports several optional sub-directives, if
- they immediately follow the account directive and if they begin with
- whitespace:
- @smallexample @c input:validate
- account Expenses:Food
- note This account is all about the chicken!
- alias food
- payee ^(KFC|Popeyes)$
- check commodity == "$"
- assert commodity == "$"
- eval print("Hello!")
- default
- @end smallexample
- The @code{note} sub-directive associates a textual note with the
- account. This can be accessed later using the @code{note} value
- expression function in any account context.
- The @code{alias} sub-directive, which can occur multiple times, allows
- the alias to be used in place of the full account name anywhere that
- account names are allowed.
- The @code{payee} sub-directive, which can occur multiple times,
- provides regexes that identify the account if that payee is
- encountered and an account within its transaction ends in the name
- "Unknown". Example:
- @smallexample @c input:validate
- 2012-02-27 KFC
- Expenses:Unknown $10.00 ; Read now as "Expenses:Food"
- Assets:Cash
- @end smallexample
- The @code{check} and @code{assert} directives warn or raise an error
- (respectively) if the given value expression evaluates to false within
- the context of any posting.
- The @code{eval} directive evaluates the value expression in the
- context of the account at the time of definition. At the moment this
- has little value.
- The @code{default} directive specifies that this account should be
- used as the ``balancing account'' for any future transactions that
- contain only a single posting.
- @item apply account
- @findex apply account
- @c instance_t::master_account_directive
- Sets the root for all accounts following this directive. Ledger
- supports a hierarchical tree of accounts. It may be convenient to
- keep two ``root accounts''. For example you may be tracking your
- personal finances and your business finances. In order to keep them
- separate you could preface all personal accounts with @samp{personal:}
- and all business accounts with @samp{business:}. You can easily split
- out large groups of transactions without manually editing them using
- the account directive. For example:
- @smallexample @c input:validate
- apply account Personal
- 2011/11/15 Supermarket
- Expenses:Groceries $ 50.00
- Assets:Checking
- @end smallexample
- Would result in all postings going into
- @samp{Personal:Expenses:Groceries} and @samp{Personal:Assets:Checking}
- until an @samp{end apply account} directive was found.
- @item alias
- @findex alias
- @cindex account, alias
- @c instance_t::alias_directive
- Define an alias for an account name. If you have a deeply nested tree
- of accounts, it may be convenient to define an alias, for example:
- @smallexample @c input:94A99E8
- alias Dining=Expenses:Entertainment:Dining
- alias Checking=Assets:Credit Union:Joint Checking Account
- 2011/11/28 YummyPalace
- Dining $10.00
- Checking
- @end smallexample
- The aliases are only in effect for transactions read in after the alias
- is defined and are affected by @code{account} directives that precede
- them.
- @smallexample @c command:94A99E8
- $ ledger bal --no-total ^Exp
- @end smallexample
- @smallexample @c output:94A99E8
- $10.00 Expenses:Entertainment:Dining
- @end smallexample
- With the option @option{--recursive-aliases}, aliases can refer to other
- aliases, the following example produces exactly the same transactions
- and account names as the preceding one:
- @smallexample @c input:83E1FB3
- alias Entertainment=Expenses:Entertainment
- alias Dining=Entertainment:Dining
- alias Checking=Assets:Credit Union:Joint Checking Account
- 2011/11/30 ChopChop
- Dining $10.00
- Checking
- @end smallexample
- @smallexample @c command:83E1FB3
- $ ledger balance --no-total --recursive-aliases ^Exp
- @end smallexample
- @smallexample @c output:83E1FB3
- $10.00 Expenses:Entertainment:Dining
- @end smallexample
- The option @option{--no-aliases} completely disables alias expansion.
- All accounts are read verbatim as they are in the ledger file.
- @item assert
- @findex assert
- @cindex assertions
- @c instance_t::assert_directive
- An assertion can throw an error if a condition is not met during
- Ledger's run.
- @smallexample
- assert <VALUE EXPRESSION BOOLEAN RESULT>
- @end smallexample
- @item bucket
- @anchor{bucket}
- @findex bucket
- @cindex bucket
- @c instance_t::default_account_directive
- Defines the default account to use for balancing transactions.
- Normally, each transaction has at least two postings, which must
- balance to zero. Ledger allows you to leave one posting with no
- amount and automatically balance the transaction in the
- posting. The @code{bucket} allows you to fill in all postings and
- automatically generate an additional posting to the bucket account
- balancing the transaction. If any transaction is unbalanced, it
- will automatically be balanced against the @code{bucket} account.
- The following example sets @samp{Assets:Checking} as the bucket:
- @smallexample @c input:validate
- bucket Assets:Checking
- 2011/01/25 Tom's Used Cars
- Expenses:Auto $ 5,500.00
- 2011/01/27 Book Store
- Expenses:Books $20.00
- 2011/12/01 Sale
- Assets:Checking:Business $ 30.00
- @end smallexample
- @item capture
- @c instance_t::account_mapping_directive
- @findex capture
- @findex print
- @findex register
- Directs Ledger to replace any account matching a regex with the given
- account. For example:
- @smallexample @c input:validate
- capture Expenses:Deductible:Medical Medical
- @end smallexample
- Would cause any posting with @samp{Medical} in its name to be replaced
- with @samp{Expenses:Deductible:Medical}.
- Ledger will display the mapped payees in @command{print} and
- @command{register} reports.
- @item check
- @findex check
- @cindex assertions
- @c instance_t::check_directive in textual.cc
- A check issues a warning if a condition is not met during Ledger's
- run.
- @smallexample
- check <VALUE EXPRESSION BOOLEAN RESULT>
- @end smallexample
- @item comment
- @findex comment
- @cindex comments
- @c instance_t::comment_directive in textual.cc
- Start a block comment, closed by @code{end comment}.
- @item commodity
- @findex commodity
- @cindex pre-declare commodity
- Pre-declare commodity names. This only has an effect if
- @option{--strict} or @option{--pedantic} is used (see below).
- @smallexample @c input:validate
- commodity $
- commodity CAD
- @end smallexample
- The @code{commodity} directive supports several optional
- sub-directives, if they immediately follow the commodity directive
- and---if they are on successive lines---begin with whitespace:
- @smallexample @c input:validate
- commodity $
- note American Dollars
- format $1,000.00
- nomarket
- default
- @end smallexample
- The @code{note} sub-directive associates a textual note with the
- commodity. At present this has no value other than documentation.
- The @code{format} sub-directive gives you a way to tell Ledger how to
- format this commodity. In the future, using this directive will disable
- Ledger's observation of other ways that commodity is used, and will
- provide the ``canonical'' representation.
- The @code{nomarket} sub-directive states that the commodity's price
- should never be auto-downloaded.
- The @code{default} sub-directive marks this as the ``default'' commodity.
- @item define
- @findex define
- @c instance_t::define_directive in textual.cc
- Allows you to define value expressions for future use. For example:
- @smallexample @c input:validate
- define var_name=$100
- 2011/12/01 Test
- Expenses (var_name*4)
- Assets
- @end smallexample
- The posting will have a cost of $400.
- @item end
- @findex end
- @c instance_t::end_directive in textual.cc
- Closes block commands like @code{tag} or @code{comment}.
- @item expr
- @findex expr
- @c instance_t::expr_directive in textual.cc
- @item fixed
- @findex fixed
- @cindex fixated prices
- @c instance_t::fixed_directive in textual.cc
- A fixed block is used to set fixated prices (@pxref{Fixated prices and
- costs}) for a series of transactions. It's purely a typing saver, for
- use when entering many transactions with fixated prices.
- Thus, the following:
- @smallexample @c input:validate
- fixed CAD $0.90
- 2012-04-10 Lunch in Canada
- Assets:Wallet -15.50 CAD
- Expenses:Food 15.50 CAD
- 2012-04-11 Second day Dinner in Canada
- Assets:Wallet -25.75 CAD
- Expenses:Food 25.75 CAD
- endfixed CAD
- @end smallexample
- is equivalent to this:
- @smallexample @c input:validate
- 2012-04-10 Lunch in Canada
- Assets:Wallet -15.50 CAD @{=$0.90@}
- Expenses:Food 15.50 CAD @{=$0.90@}
- 2012-04-11 Second day Dinner in Canada
- Assets:Wallet -25.75 CAD @{=$0.90@}
- Expenses:Food 25.75 CAD @{=$0.90@}
- @end smallexample
- Note that ending a @code{fixed} is done differently than other
- directives, as @code{fixed} is closed with an @code{endfixed} (i.e.,
- there is @emph{no space} between @code{end} and @code{fixed}).
- For the moment, users may wish to study
- @uref{http://bugs.ledger-cli.org/show_bug.cgi?id=789, Bug Report 789}
- before using the @code{fixed} directive in production.
- @item include
- @findex include
- @c instance_t::include_directive in textual.cc
- Include the stated file as if it were part of the current file.
- @item payee
- @findex payee
- @c instance_t::payee_alias_mapping_directive in textual.cc
- @c instance_t::payee_uuid_mapping_directive in textual.cc
- @findex print
- @findex register
- The @code{payee} directive supports two optional sub-directives, if they
- immediately follow the payee directive and---if it is on a successive
- line---begins with whitespace:
- @smallexample @c input:validate
- payee KFC
- alias KENTUCKY FRIED CHICKEN
- uuid 2a2e21d434356f886c84371eebac6e44f1337fda
- @end smallexample
- The @code{alias} sub-directive provides a regex which, if it matches
- a parsed payee, the declared payee name is substituted:
- @smallexample @c input:validate
- 2012-02-27 KENTUCKY FRIED CHICKEN ; will be read as being 'KFC'
- @end smallexample
- The @code{uuid} sub-directive specifies that a transaction with exactly
- the uuid given should have the declared payee name substituted:
- @smallexample @c input:validate
- 2014-05-13 UNHELPFUL PAYEE ; will be read as being 'KFC'
- ; UUID: 2a2e21d434356f886c84371eebac6e44f1337fda
- @end smallexample
- Ledger will display the mapped payees in @command{print} and
- @command{register} reports.
- @item apply tag
- @findex apply tag
- @c instance_t::tag_directive in textual.cc
- Allows you to designate a block of transactions and assign the same
- tag to all. Tags can have values and may be nested.
- @smallexample @c input:validate
- apply tag hastag
- apply tag nestedtag: true
- 2011/01/25 Tom's Used Cars
- Expenses:Auto $ 5,500.00
- ; :nobudget:
- Assets:Checking
- 2011/01/27 Book Store
- Expenses:Books $20.00
- Liabilities:MasterCard
- end apply tag
- 2011/12/01 Sale
- Assets:Checking:Business $ 30.00
- Income:Sales
- end apply tag
- @end smallexample
- @noindent
- is the equivalent of:
- @smallexample @c input:validate
- 2011/01/25 Tom's Used Cars
- ; :hastag:
- ; nestedtag: true
- Expenses:Auto $ 5,500.00
- ; :nobudget:
- Assets:Checking
- 2011/01/27 Book Store
- ; :hastag:
- ; nestedtag: true
- Expenses:Books $20.00
- Liabilities:MasterCard
- 2011/12/01 Sale
- ; :hastag:
- Assets:Checking:Business $ 30.00
- Income:Sales
- @end smallexample
- @c TODO: the following paragraph seems to be false, the automated tests
- @c fail, if anything appears after end apply tag.
- @c Note that anything following @code{end apply tag} is ignored. Placing
- @c the name of the tag that is being closed is a simple way to keep
- @c track.
- @item tag
- @findex tag
- @cindex pre-declare tag
- Pre-declares tag names. This only has an effect if @option{--strict} or
- @option{--pedantic} is used (see below).
- @smallexample @c input:validate
- tag Receipt
- tag CSV
- @end smallexample
- The @code{tag} directive supports two optional sub-directives, if they
- immediately follow the tag directive and---if on a successive
- line---begin with whitespace:
- @smallexample @c input:validate
- tag Receipt
- check value =~ /pattern/
- assert value != "foobar"
- @end smallexample
- The @code{check} and @code{assert} sub-directives warn or error
- (respectively) if the given value expression evaluates to false within
- the context of any use of the related tag. In such a context,
- ``value'' is bound to the value of the tag (which may be something else
- but a string if typed metadata is used!). Such checks or assertions are
- not called if no value is given.
- @item test
- @findex test
- @cindex comments
- @c instance_t::comment_directive in textual.cc
- This is a synonym for @code{comment} and must be closed by an
- @code{end} tag.
- @item year
- @findex year
- @anchor{year}
- @c instance_t::year_directive in textual.cc
- Denotes the year used for all subsequent transactions that give a date
- without a year. The year should appear immediately after the
- directive, for example: @code{year 2004}. This is useful at the
- beginning of a file, to specify the year for that file. If all
- transactions specify a year, however, this command has no effect.
- @end table
- The following single letter commands may be at the beginning of a line
- alone, for backwards compatibility with older Ledger versions.
- @table @code
- @item A
- @findex A
- @findex bucket
- @xref{bucket}.
- @item Y
- @findex Y
- @findex year
- @xref{year}.
- @item N SYMBOL
- @findex N
- Indicates that pricing information is to be ignored for a given
- symbol, nor will quotes ever be downloaded for that symbol. Useful
- with a home currency, such as the dollar @samp{$}. It is recommended
- that these pricing options be set in the price database file, which
- defaults to @file{~/.pricedb}. The syntax for this command is:
- @smallexample @c input:validate
- N SYMBOL
- @end smallexample
- @item D AMOUNT
- @findex xact
- @findex D
- Specifies the default commodity to use, by specifying an amount in the
- expected format. The @command{xact} command will use this commodity as
- the default when none other can be determined. This command may be used
- multiple times, to set the default flags for different commodities;
- whichever is seen last is used as the default commodity. For example,
- to set US dollars as the default commodity, while also setting the
- thousands flag and decimal flag for that commodity, use:
- @smallexample @c input:validate
- D $1,000.00
- @end smallexample
- @item C AMOUNT1 = AMOUNT2
- @findex C
- Specifies a commodity conversion, where the first amount is given to
- be equivalent to the second amount. The first amount should use the
- decimal precision desired during reporting:
- @smallexample @c input:validate
- C 1.00 Kb = 1024 bytes
- @end smallexample
- @item I, i, O, o, b, h
- @findex I
- @findex i
- @findex O
- @findex o
- @findex b
- @findex h
- These four relate to timeclock support, which permits Ledger to read
- timelog files. See timeclock's documentation for more info on the
- syntax of its timelog files.
- @end table
- @node Converting from other formats, Archiving Previous Years, Journal Format, Keeping a Journal
- @section Converting from other formats
- @cindex csv importing
- There are numerous tools to help convert various formats to a Ledger
- file. Most banks will generate a comma separated values file that can
- easily be parsed into Ledger format using one of those tools. Some of
- the most popular tools are:
- @itemize
- @item @code{ledger convert download.csv}
- @item @code{hledger -f checking.csv print}
- @item @uref{https://github.com/quentinsf/icsv2ledger, @code{icsv2ledger}}
- @item @uref{https://github.com/tazzben/csvToLedger, @code{csvToLedger}}
- @item @uref{https://launchpad.net/csv2ledger, @code{CSV2Ledger}}
- @end itemize
- @noindent
- Directly pulling information from banks is outside the scope of
- Ledger's function.
- @node Archiving Previous Years, , Converting from other formats, Keeping a Journal
- @section Archiving Previous Years
- @findex equity
- @findex print
- After a while, your journal can get to be pretty large. While this
- will not slow down Ledger---it's designed to process journals very
- quickly---things can start to feel ``messy''; and it's a universal
- complaint that when finances feel messy, people avoid them.
- Thus, archiving the data from previous years into their own files can
- offer a sense of completion, and freedom from the past. But how to
- best accomplish this with the ledger program? There are two commands
- that make it very simple: @command{print}, and @command{equity}.
- Let's take an example file, with data ranging from year 2000 until
- 2004. We want to archive years 2000 and 2001 to their own file,
- leaving just 2003 and 2004 in the current file. So, use
- @command{print} to output all the earlier transactions to a file
- called @file{ledger-old.dat}:
- @smallexample
- $ ledger -f ledger.dat -b 2000 -e 2001 print > ledger-old.dat
- @end smallexample
- To delete older data from the current ledger file, use @command{print}
- again, this time specifying year 2002 as the starting date:
- @smallexample
- $ ledger -f ledger.dat -b 2002 print > x
- $ mv x ledger.dat
- @end smallexample
- However, now the current file contains @emph{only} postings from 2002
- onward, which will not yield accurate present-day balances, because the
- net income from previous years is no longer being tallied. To
- compensate for this, we must append an equity report for the old ledger
- at the beginning of the new one:
- @smallexample
- $ ledger -f ledger-old.dat equity > equity.dat
- $ cat equity.dat ledger.dat > x
- $ mv x ledger.dat
- $ rm equity.dat
- @end smallexample
- Now the balances reported from @file{ledger.dat} are identical to what
- they were before the data was split.
- How often should you split your ledger? You never need to, if you
- don't want to. Even eighty years of data will not slow down ledger
- much, and that's just using present day hardware! Or, you can keep
- the previous and current year in one file, and each year before that
- in its own file. It's really up to you, and how you want to organize
- your finances. For those who also keep an accurate paper trail, it
- might be useful to archive the older years to their own files, then
- burn those files to a CD to keep with the paper records---along with
- any electronic statements received during the year. In the arena of
- organization, just keep in mind this maxim: Do whatever keeps you
- doing it.
- @node Transactions, Building Reports, Keeping a Journal, Top
- @chapter Transactions
- @menu
- * Basic format::
- * Eliding amounts::
- * Auxiliary dates::
- * Codes::
- * Transaction state::
- * Transaction notes::
- * Metadata::
- * Virtual postings::
- * Expression amounts::
- * Balance verification::
- * Posting cost::
- * Explicit posting costs::
- * Posting cost expressions::
- * Total posting costs::
- * Virtual posting costs::
- * Commodity prices::
- * Prices versus costs::
- * Fixated prices and costs::
- * Lot dates::
- * Lot notes::
- * Lot value expressions::
- * Automated Transactions::
- @end menu
- @node Basic format, Eliding amounts, Transactions, Transactions
- @section Basic format
- The most basic form of transaction is:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash $-20.00
- @end smallexample
- This transaction has a date, a payee or description, a target account
- (the first posting), and a source account (the second posting). Each
- posting specifies what action is taken related to that account.
- A transaction can have any number of postings:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash $-10.00
- Liabilities:Credit $-10.00
- @end smallexample
- @node Eliding amounts, Auxiliary dates, Basic format, Transactions
- @section Eliding amounts
- The first thing you can do to make things easier is elide amounts.
- That is, if exactly one posting has no amount specified, Ledger will
- infer the inverse of the other postings' amounts:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash $-10.00
- Liabilities:Credit ; same as specifying $-10
- @end smallexample
- @noindent
- If the other postings use multiple commodities, Ledger will copy the
- empty posting N times and fill in the negated values of the various
- commodities:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Expenses:Tips $2.00
- Assets:Cash EUR -10.00
- Assets:Cash GBP -10.00
- Liabilities:Credit
- @end smallexample
- @noindent
- This transaction is identical to writing:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Expenses:Tips $2.00
- Assets:Cash EUR -10.00
- Assets:Cash GBP -10.00
- Liabilities:Credit $-22.00
- Liabilities:Credit EUR 10.00
- Liabilities:Credit GBP 10.00
- @end smallexample
- @node Auxiliary dates, Codes, Eliding amounts, Transactions
- @section Auxiliary dates
- @findex --aux-date
- You can associate a second date with a transaction by following the
- primary date with an equals sign:
- @smallexample @c input:validate
- 2012-03-10=2012-03-08 KFC
- Expenses:Food $20.00
- Assets:Cash $-20.00
- @end smallexample
- What this auxiliary date means is entirely up to you. The only use
- Ledger has for it is that if you specify @option{--aux-date}, then all
- reports and calculations (including pricing) will use the auxiliary
- date as if it were the primary date.
- @node Codes, Transaction state, Auxiliary dates, Transactions
- @section Codes
- A transaction can have a textual ``code''. This has no meaning and is
- only displayed by the print command. Checking accounts often use
- codes like DEP, XFER, etc., as well as check numbers. This is to give
- you a place to put those codes:
- @smallexample @c input:validate
- 2012-03-10 (#100) KFC
- Expenses:Food $20.00
- Assets:Checking
- @end smallexample
- @node Transaction state, Transaction notes, Codes, Transactions
- @section Transaction state
- @findex --cleared
- @findex --uncleared
- @findex --pending
- A transaction can have a ``state'': cleared, pending, or uncleared. The
- default is uncleared. To mark a transaction cleared, put an asterisk
- @samp{*} before the payee, after the date or code:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- @noindent
- To mark it pending, use a @samp{!}:
- @smallexample @c input:validate
- 2012-03-10 ! KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- What these mean is entirely up to you. The @option{--cleared} option
- limits reports to only cleared items, while @option{--uncleared}
- shows both uncleared and pending items, and @option{--pending} shows
- only pending items.
- I use cleared to mean that I've reconciled the transaction with my
- bank statement, and pending to mean that I'm in the middle of
- a reconciliation.
- When you clear a transaction, that's really just shorthand for
- clearing all of its postings. That is:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- @noindent
- Is the same as writing:
- @smallexample @c input:validate
- 2012-03-10 KFC
- * Expenses:Food $20.00
- * Assets:Cash
- @end smallexample
- @noindent
- You can mark individual postings as cleared or pending, in case one
- ``side'' of the transaction has cleared, but the other hasn't yet:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Liabilities:Credit $100.00
- * Assets:Checking
- @end smallexample
- @node Transaction notes, Metadata, Transaction state, Transactions
- @section Transaction notes
- After the payee, and after at least one tab or two spaces (or a space
- and a tab, which Ledger calls a ``hard separator''), you may
- introduce a note about the transaction using the @samp{;} character:
- @smallexample @c input:validate
- 2012-03-10 * KFC ; yum, chicken...
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- @noindent
- Notes can also appear on the next line, so long as that line begins
- with whitespace:
- @smallexample @c input:validate
- 2012-03-10 * KFC ; yum, chicken...
- ; and more notes...
- Expenses:Food $20.00
- Assets:Cash
- 2012-03-10 * KFC
- ; just these notes...
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- A transaction's note is shared by all its postings. This becomes
- significant when querying for metadata (see below). To specify that
- a note belongs only to one posting, place it after a hard separator
- after the amount, or on its own line preceded by whitespace:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00 ; posting #1 note
- Assets:Cash
- ; posting #2 note, extra indentation is optional
- @end smallexample
- @node Metadata, Virtual postings, Transaction notes, Transactions
- @section Metadata
- @c TODO add cindex
- @c TODO https://groups.google.com/d/msg/ledger-cli/2csLPcHJ3ak/a17jOClzLTUJ
- @c > Is there a way to produce a register report that lists all the transaction
- @c > that contain a certain tag, and sort them based on the value of the tag?
- @c ledger reg --sort "tag('foo')" %foo
- @c ledger reg --group-by "tag('Employer)" Remboursement:Employer and tag Employer
- @c > Is it possible to get subtotals for each tag value?
- @c ledger --group-by "tag('foo')" bal
- @c TODO https://groups.google.com/d/msg/ledger-cli/K9NBhNlVnYc/TDYDAWhOA5EJ
- One of Ledger's more powerful features is the ability to associate
- typed metadata with postings and transactions (by which I mean all of
- a transaction's postings). This metadata can be queried, displayed,
- and used in calculations.
- The are two forms of metadata: plain tags, and tag/value pairs.
- @menu
- * Metadata tags::
- * Metadata values::
- * Typed metadata::
- @end menu
- @node Metadata tags, Metadata values, Metadata, Metadata
- @subsection Metadata tags
- To tag an item, put any word not containing whitespace between two
- colons inside a comment:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- ; :TAG:
- @end smallexample
- You can gang up multiple tags by sharing colons:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- ; :TAG1:TAG2:TAG3:
- @end smallexample
- @menu
- * Payee metadata tag::
- @end menu
- @node Payee metadata tag, , Metadata tags, Metadata tags
- @subsubsection Payee metadata tag
- @cindex Payee metadata tag
- @findex register
- @findex payees
- @findex --by-payee
- ``Payee'' is a special metadata field. If set on a posting, it will be
- used as the payee name for that posting. This affects the
- @command{register} report, the @command{payees} report, and the
- @option{--by-payee} option.
- This is useful when for example you deposit 4 checks at a time to the
- bank. On the bank statement, there is just one amount @samp{$400}, but
- you can specify from whom each check came from, as shown by example
- below:
- @smallexample @c input:9B43E57
- 2010-06-17 Sample
- Assets:Bank $400.00
- Income:Check1 $-100.00 ; Payee: Person One
- Income:Check2 $-100.00 ; Payee: Person Two
- Income:Check3 $-100.00 ; Payee: Person Three
- Income:Check4 $-100.00 ; Payee: Person Four
- @end smallexample
- When reporting with
- @smallexample @c command:9B43E57
- $ ledger reg
- @end smallexample
- it appears as:
- @smallexample @c output:9B43E57
- 10-Jun-17 Sample Assets:Bank $400.00 $400.00
- Person One Income:Check1 $-100.00 $300.00
- Person Two Income:Check2 $-100.00 $200.00
- Person Three Income:Check3 $-100.00 $100.00
- Person Four Income:Check4 $-100.00 0
- @end smallexample
- This shows that they are all in the same transaction (which is why the
- date is not repeated), but they have different payees now.
- @node Metadata values, Typed metadata, Metadata tags, Metadata
- @subsection Metadata values
- To associate a value with a tag, use the syntax ``Key: Value'', where
- the value can be any string of characters. Whitespace is needed after
- the colon, and cannot appear in the Key:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- ; MyTag: This is just a bogus value for MyTag
- @end smallexample
- @node Typed metadata, , Metadata values, Metadata
- @subsection Typed metadata
- If a metadata tag ends in ::, its value will be parsed as a value
- expression and stored internally as a value rather than as a string.
- For example, although I can specify a date textually like so:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- ; AuxDate: 2012/02/30
- @end smallexample
- @noindent
- This date is just a string, and won't be parsed as a date unless its
- value is used in a date-context (at which time the string is parsed
- into a date automatically every time it is needed as a date). If on
- the other hand I write this:
- @smallexample
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- ; AuxDate:: [2012/02/30]
- @end smallexample
- @noindent
- Then it is parsed as a date only once, and during parsing of the
- journal file, which would let me know right away that it is an invalid
- date.
- @node Virtual postings, Expression amounts, Metadata, Transactions
- @section Virtual postings
- @findex --real
- Ordinarily, the amounts of all postings in a transaction must balance
- to zero. This is non-negotiable. It's what double-entry accounting
- is all about! But there are some tricks up Ledger's sleeve...
- You can use virtual accounts to transfer amounts to an account on the
- sly, bypassing the balancing requirement. The trick is that these
- postings are not considered ``real'', and can be removed from all
- reports using @option{--real}.
- To specify a virtual account, surround the account name with
- parentheses:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- (Budget:Food) $-20.00
- @end smallexample
- If you want, you can state that virtual postings @emph{should} balance
- against one or more other virtual postings by using brackets (which
- look ``harder'') rather than parentheses:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food $20.00
- Assets:Cash
- [Budget:Food] $-20.00
- [Equity:Budgets] $20.00
- @end smallexample
- @node Expression amounts, Balance verification, Virtual postings, Transactions
- @section Expression amounts
- An amount is usually a numerical figure with an (optional) commodity,
- but it can also be any value expression. To indicate this, surround
- the amount expression with parentheses:
- @smallexample @c input:validate
- 2012-03-10 * KFC
- Expenses:Food ($10.00 + $20.00) ; Ledger adds it up for you
- Assets:Cash
- @end smallexample
- @node Balance verification, Posting cost, Expression amounts, Transactions
- @section Balance verification
- @findex --permissive
- @menu
- * Balance assertions::
- * Balance assignments::
- * Resetting a balance::
- * Balancing transactions::
- @end menu
- If at the end of a posting's amount (and after the cost too, if there
- is one) there is an equals sign, then Ledger will verify that the
- total value for that account as of that posting matches the amount
- specified. See @option{--permissive} option to relax the balance assertions checks.
- There are two forms of this features: balance assertions, and balance
- assignments.
- @node Balance assertions, Balance assignments, Balance verification, Balance verification
- @subsection Balance assertions
- A balance assertion has this general form:
- @smallexample
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash $-20.00 = $500.00
- @end smallexample
- This simply asserts that after subtracting $20.00 from Assets:Cash,
- that the resulting total matches $500.00. If not, it is an error.
- @node Balance assignments, Resetting a balance, Balance assertions, Balance verification
- @subsection Balance assignments
- A balance assignment has this form:
- @smallexample
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash = $500.00
- @end smallexample
- This sets the amount of the second posting to whatever it would need to
- be for the total in @samp{Assets:Cash} to be $500.00 after the posting.
- If the resulting amount is not $-20.00 in this case, it is an error.
- @node Resetting a balance, Balancing transactions, Balance assignments, Balance verification
- @subsection Resetting a balance
- Say your book-keeping has gotten a bit out of date, and your Ledger
- balance no longer matches your bank balance. You can create an
- adjustment transaction using balance assignments:
- @smallexample @c input:validate
- 2012-03-10 Adjustment
- Assets:Cash = $500.00
- Equity:Adjustments
- @end smallexample
- Since the second posting is also null, it's value will become the
- inverse of whatever amount is generated for the first posting.
- This is the only time in ledger when more than one posting's amount
- may be empty---and then only because it's not truly empty, it is
- indirectly provided by the balance assignment's value.
- @node Balancing transactions, , Resetting a balance, Balance verification
- @subsection Balancing transactions
- @findex --empty
- As a consequence of all the above, consider the following transaction:
- @smallexample
- 2012-03-10 My Broker
- [Assets:Brokerage] = 10 AAPL
- @end smallexample
- What this says is: set the amount of the posting to whatever value is
- needed so that @samp{Assets:Brokerage} contains 10 AAPL. Then, because
- this posting must balance, ensure that its value is zero. This can only
- be true if Assets:Brokerage does indeed contain 10 AAPL at that point in
- the input file.
- A balanced virtual transaction is used simply to indicate to Ledger that
- this is not a ``real'' transaction. It won't appear in any reports
- anyway (unless you use a register report with @option{--empty}).
- @node Posting cost, Explicit posting costs, Balance verification, Transactions
- @section Posting cost
- When you transfer a commodity from one account to another, sometimes
- it gets transformed during the transaction. This happens when you
- spend money on gas, for example, which transforms dollars into gallons
- of gasoline, or dollars into stocks in a company.
- In those cases, Ledger will remember the ``cost'' of that transaction
- for you, and can use it during reporting in various ways. Here's an
- example of a stock purchase:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL
- Assets:Brokerage:Cash $-500.00
- @end smallexample
- This is different from transferring 10 AAPL shares from one account to
- another, in this case you are @emph{exchanging} one commodity for
- another. The resulting posting's cost is $50.00 per share.
- @node Explicit posting costs, Posting cost expressions, Posting cost, Transactions
- @section Explicit posting costs
- You can make any posting's cost explicit using the @samp{@@} symbol
- after the amount or amount expression:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL @@ $50.00
- Assets:Brokerage:Cash $-500.00
- @end smallexample
- When you do this, since Ledger can now figure out the balancing amount
- from the first posting's cost, you can elide the other amount:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL @@ $50.00
- Assets:Brokerage:Cash
- @end smallexample
- @menu
- * Primary and secondary commodities::
- @end menu
- @node Primary and secondary commodities, , Explicit posting costs, Explicit posting costs
- @subsection Primary and secondary commodities
- @findex --market
- @findex --exchange @var{COMMODITY}
- It is a general convention within Ledger that the ``top'' postings in
- a transaction contain the target accounts, while the final posting
- contains the source account. Whenever a commodity is exchanged like
- this, the commodity moved to the target account is considered
- ``secondary'', while the commodity used for purchasing and tracked in
- the cost is ``primary''.
- Said another way, whenever Ledger sees a posting cost of the form
- "AMOUNT @@ AMOUNT", the commodity used in the second amount is marked
- ``primary''.
- The only meaning a primary commodity has is that the @option{--market
- (-V)} flag will never convert a primary commodity into any other
- commodity. @option{--exchange @var{COMMODITY} (-X)} still will,
- however.
- @node Posting cost expressions, Total posting costs, Explicit posting costs, Transactions
- @section Posting cost expressions
- Just as you can have amount expressions, you can have posting
- expressions:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL @@ ($500.00 / 10)
- Assets:Brokerage:Cash
- @end smallexample
- You can even have both:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage (5 AAPL * 2) @@ ($500.00 / 10)
- Assets:Brokerage:Cash
- @end smallexample
- @node Total posting costs, Virtual posting costs, Posting cost expressions, Transactions
- @section Total posting costs
- The cost figure following the @samp{@@} character specifies the
- @emph{per-unit} price for the commodity being transferred. If you'd
- like to specify the total cost instead, use @samp{@@@@}:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL @@@@ $500.00
- Assets:Brokerage:Cash
- @end smallexample
- Ledger reads this as if you had written:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL @@ ($500.00 / 10)
- Assets:Brokerage:Cash
- @end smallexample
- @node Virtual posting costs, Commodity prices, Total posting costs, Transactions
- @section Virtual posting costs
- Normally whenever a commodity exchange like this happens, the price of
- the exchange (such as $50 per share of AAPL, above) is recorded in
- Ledger's internal price history database. To prevent this from
- happening in the case of an exceptional transaction, surround the
- @samp{@@} or @samp{@@@@} with parentheses:
- @smallexample @c input:validate
- 2012-03-10 My Brother
- Assets:Brokerage 1000 AAPL (@@) $1
- Income:Gifts Received
- @end smallexample
- @node Commodity prices, Prices versus costs, Virtual posting costs, Transactions
- @section Commodity prices
- @findex --lot-prices
- When a transaction occurs that exchanges one commodity for another,
- Ledger records that commodity price not only within its internal price
- database, but also attached to the commodity itself. Usually this fact
- remains invisible to the user, unless you turn on @option{--lot-prices}
- to show these hidden price figures.
- For example, consider the stock sale given above:
- @smallexample @c input:validate
- 2012-03-10 My Broker
- Assets:Brokerage 10 AAPL @@ $50.00
- Assets:Brokerage:Cash
- @end smallexample
- The commodity transferred into @samp{Assets:Brokerage} is not actually 10
- AAPL, but rather 10 AAPL @{$50.00@}. The figure in braces after the
- amount is called the ``lot price''. It's Ledger's way of remembering
- that this commodity was transferred through an exchange, and that
- $50.00 was the price of that exchange.
- This becomes significant if you later sell that commodity again. For
- example, you might write this:
- @smallexample @c input:validate
- 2012-04-10 My Broker
- Assets:Brokerage:Cash
- Assets:Brokerage -10 AAPL @@ $75.00
- @end smallexample
- And that would be perfectly fine, but how do you track the capital
- gains on the sale? It could be done with a virtual posting:
- @smallexample @c input:validate
- 2012-04-10 My Broker
- Assets:Brokerage:Cash
- Assets:Brokerage -10 AAPL @@ $75.00
- (Income:Capital Gains) $-250.00
- @end smallexample
- But this gets messy since capital gains income is very real, and not
- quite appropriate for a virtual posting.
- Instead, if you reference that same hidden price annotation, Ledger
- will figure out that the price of the shares you're selling, and the
- cost you're selling them at, don't balance:
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $750.00
- Assets:Brokerage -10 AAPL @{$50.00@} @@ $75.00
- @end smallexample
- This transaction will fail because the $250.00 price difference
- between the price you bought those shares at, and the cost you're
- selling them for, does not match. The lot price also identifies which
- shares you purchased on that prior date.
- @menu
- * Total commodity prices::
- @end menu
- @node Total commodity prices, , Commodity prices, Commodity prices
- @subsection Total commodity prices
- As a shorthand, you can specify the total price instead of the
- per-share price in doubled braces. This goes well with total costs,
- but is not required to be used with them:
- @smallexample @c input:validate
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $750.00
- Assets:Brokerage -10 AAPL @{@{$500.00@}@} @@@@ $750.00
- Income:Capital Gains $-250.00
- @end smallexample
- It should be noted that this is a convenience only for cases where you
- buy and sell whole lots. The @{@{$500.00@}@} is @emph{not} an attribute
- of the commodity, whereas @{$50.00@} is. In fact, when you write
- @{@{$500.00@}@}, Ledger just divides that value by 10 and sees
- @{$50.00@}. So if you use the print command to look at this
- transaction, you'll see the single braces form in the output. The
- double braces price form is a shorthand only.
- Plus, it comes with dangers. This works fine:
- @smallexample @c input:validate
- 2012-04-10 My Broker
- Assets:Brokerage 10 AAPL @@ $50.00
- Assets:Brokerage:Cash $-500.00
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{$50.00@} @@ $375.00
- Income:Capital Gains $-125.00
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{$50.00@} @@ $375.00
- Income:Capital Gains $-125.00
- @end smallexample
- @noindent
- But this does not do what you might expect:
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage 10 AAPL @@ $50.00
- Assets:Brokerage:Cash $750.00
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{@{$500.00@}@} @@ $375.00
- Income:Capital Gains $-125.00
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{@{$500.00@}@} @@ $375.00
- Income:Capital Gains $-125.00
- @end smallexample
- And in cases where the amounts do not divide into whole figures and
- must be rounded, the capital gains figure could be off by a cent. Use
- with caution.
- @node Prices versus costs, Fixated prices and costs, Commodity prices, Transactions
- @section Prices versus costs
- Because lot pricing provides enough information to infer the cost, the
- following two transactions are equivalent:
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage 10 AAPL @@ $50.00
- Assets:Brokerage:Cash $750.00
- 2012-04-10 My Broker
- Assets:Brokerage 10 AAPL @{$50.00@}
- Assets:Brokerage:Cash $750.00
- @end smallexample
- However, note that what you see in some reports may differ, for
- example in the print report. Functionally, however, there is no
- difference, and neither the register nor the balance report are
- sensitive to this difference.
- @node Fixated prices and costs, Lot dates, Prices versus costs, Transactions
- @section Fixated prices and costs
- If you buy a stock last year, and ask for its value today, Ledger will
- consult its price database to see what the most recent price for that
- stock is. You can short-circuit this lookup by ``fixing'' the price
- at the time of a transaction. This is done using @samp{@{=AMOUNT@}}:
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage 10 AAPL @{=$50.00@}
- Assets:Brokerage:Cash $750.00
- @end smallexample
- These 10 AAPL will now always be reported as being worth $50, no
- matter what else happens to the stock in the meantime.
- Fixated prices are a special case of using lot valuation expressions
- (see below) to fix the value of a commodity lot.
- Since price annotations and costs are largely interchangeable and
- a matter of preference, there is an equivalent syntax for specified
- fixated prices by way of the cost:
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage 10 AAPL @@ =$50.00
- Assets:Brokerage:Cash $750.00
- @end smallexample
- This is the same as the previous transaction, with the same caveats
- found in @ref{Prices versus costs}.
- @node Lot dates, Lot notes, Fixated prices and costs, Transactions
- @section Lot dates
- @findex --lot-dates
- In addition to lot prices, you can specify lot dates and reveal them
- with @option{--lot-dates}. Other than that, however, they have no
- special meaning to Ledger. They are specified after the amount in
- square brackets (the same way that dates are parsed in value
- expressions):
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{$50.00@} [2012-04-10] @@ $375.00
- Income:Capital Gains $-125.00
- @end smallexample
- @node Lot notes, Lot value expressions, Lot dates, Transactions
- @section Lot notes
- @findex --lot-notes
- @findex --lots
- You can also associate arbitrary notes for your own record keeping in
- parentheses, and reveal them with @option{--lot-notes}. One caveat is
- that the note cannot begin with an @samp{@@} character, as that would
- indicate a virtual cost:
- @smallexample
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{$50.00@} [2012-04-10] (Oh my!) @@ $375.00
- Income:Capital Gains $-125.00
- @end smallexample
- You can specify any combination of lot prices, dates or notes, in any
- order. They are all optional.
- To show all lot information in a report, use @option{--lots}.
- @node Lot value expressions, Automated Transactions, Lot notes, Transactions
- @section Lot value expressions
- Normally when you ask Ledger to display the values of commodities held,
- it uses a value expression called ``market'' to determine the most
- recent value from its price database---even downloading prices from the
- Internet, if @option{--download (-Q)} was specified and a suitable
- @file{getquote} script is found on your system.
- However, you can override this valuation logic by providing
- a commodity valuation expression in doubled parentheses. This
- expression must result in one of two values: either an amount to
- always be used as the per-share price for that commodity; or
- a function taking three arguments, which is called to determine that
- price.
- If you use the functional form, you can either specify a function
- name, or a lambda expression. Here's a function that yields the price
- as $10 in whatever commodity is being requested:
- @smallexample @c input:validate
- define ten_dollars(s, date, t) = market($10, date, t)
- @end smallexample
- I can now use that in a lot value expression as follows:
- @smallexample @c input:validate
- 2012-04-10 My Broker
- Assets:Brokerage:Cash $375.00
- Assets:Brokerage -5 AAPL @{$50.00@} ((ten_dollars)) @@@@ $375.00
- Income:Capital Gains $-125.00
- @end smallexample
- Alternatively, I could do the same thing without pre-defining
- a function by using a lambda expression taking three arguments:
- @smallexample
- 2012-04-10 My Broker
- A:B:Cash $375.00
- A:B -5 AAPL @{$50.00@} ((s, d, t -> market($10, date, t))) @@@@ $375.00
- Income:Capital Gains $-125.00
- @end smallexample
- The arguments passed to these functions have the following meaning:
- @itemize
- @item source
- The source commodity string, or an amount object. If it is a string,
- the return value must be an amount representing the price of the
- commodity identified by that string (example: @samp{$}). If it is an
- amount, return the value of that amount as a new amount (usually
- calculated as commodity price times source amount).
- @item date
- The date to use for determining the value. If null, it means no date
- was specified, which can mean whatever you want it to mean.
- @item target
- If not null, a string representing the desired target commodity that the
- commodity price, or repriced amount, should be valued in. Note that
- this string can be a comma-separated list, and that some or all of the
- commodities in that list may be suffixed with an exclamation mark, to
- indicate what is being desired.
- @end itemize
- In most cases, it is simplest to either use explicit amounts in your
- valuation expressions, or just pass the arguments down to @samp{market}
- after modifying them to suit your needs.
- @node Automated Transactions, , Lot value expressions, Transactions
- @section Automated Transactions
- An automated transaction is a special kind of transaction which adds
- its postings to other transactions any time one of that other
- transactions' postings matches its predicate. The predicate uses the
- same query syntax as the Ledger command-line.
- Consider this posting:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- If I write this automated transaction before it in the file:
- @smallexample @c input:validate
- = expr true
- Foo $50.00
- Bar $-50.00
- @end smallexample
- Then the first transaction will be modified during parsing as if I'd
- written this:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Foo $50.00
- Bar $-50.00
- Assets:Cash $-20.00
- Foo $50.00
- Bar $-50.00
- @end smallexample
- Despite this fancy logic, automated transactions themselves follow
- most of the same rules as regular transactions: their postings must
- balance (unless you use a virtual posting), you can have metadata,
- etc.
- One thing you cannot do, however, is elide amounts in an automated
- transaction.
- @menu
- * Amount multipliers::
- * Accessing the matching posting's amount::
- * Referring to the matching posting's account::
- * Applying metadata to every matched posting::
- * Applying metadata to the generated posting::
- * State flags::
- * Effective Dates::
- * Periodic Transactions::
- * Concrete Example of Automated Transactions::
- @end menu
- @node Amount multipliers, Accessing the matching posting's amount, Automated Transactions, Automated Transactions
- @subsection Amount multipliers
- As a special case, if an automated transaction's posting's amount
- (phew) has no commodity, it is taken as a multiplier upon the matching
- posting's cost. For example:
- @smallexample @c input:validate
- = expr true
- Foo 50.00
- Bar -50.00
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- Then the latter transaction turns into this during parsing:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- Foo $1000.00
- Bar $-1000.00
- Assets:Cash $-20.00
- Foo $1000.00
- Bar $-1000.00
- @end smallexample
- @node Accessing the matching posting's amount, Referring to the matching posting's account, Amount multipliers, Automated Transactions
- @subsection Accessing the matching posting's amount
- If you use an amount expression for an automated transaction's
- posting, that expression has access to all the details of the matched
- posting. For example, you can refer to that posting's amount using
- the ``amount'' value expression variable:
- @smallexample @c input:validate
- = expr true
- (Foo) (amount * 2) ; same as just "2" in this case
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- This becomes:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- (Foo) $40.00
- Assets:Cash $-20.00
- (Foo) $-40.00
- @end smallexample
- @node Referring to the matching posting's account, Applying metadata to every matched posting, Accessing the matching posting's amount, Automated Transactions
- @subsection Referring to the matching posting's account
- Sometimes you want to refer to the account that was matched
- in some way within the automated transaction itself. This is
- done by using the string @samp{$account}, anywhere within the
- account part of the automated posting:
- @smallexample @c input:validate
- = food
- (Budget:$account) 10
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- Becomes:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- (Budget:Expenses:Food) $200.00
- Assets:Cash $-20.00
- @end smallexample
- @node Applying metadata to every matched posting, Applying metadata to the generated posting, Referring to the matching posting's account, Automated Transactions
- @subsection Applying metadata to every matched posting
- If the automated transaction has a transaction note, that note is
- copied (along with any metadata) to every posting that matches the
- predicate:
- @smallexample @c input:validate
- = food
- ; Foo: Bar
- (Budget:$account) 10
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- Becomes:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- ; Foo: Bar
- (Budget:Expenses:Food) $200.00
- Assets:Cash $-20.00
- @end smallexample
- @node Applying metadata to the generated posting, State flags, Applying metadata to every matched posting, Automated Transactions
- @subsection Applying metadata to the generated posting
- If the automated transaction's posting has a note, that note is
- carried to the generated posting within the matched transaction:
- @smallexample @c input:validate
- = food
- (Budget:$account) 10
- ; Foo: Bar
- 2012-03-10 KFC
- Expenses:Food $20.00
- Assets:Cash
- @end smallexample
- Becomes:
- @smallexample @c input:validate
- 2012-03-10 KFC
- Expenses:Food $20.00
- (Budget:Expenses:Food) $200.00
- ; Foo: Bar
- Assets:Cash $-20.00
- @end smallexample
- This is slightly different from the rules for regular transaction
- notes, in that an automated transaction's note does not apply to every
- posting within the automated transaction itself, but rather to every
- posting it matches.
- @node State flags, Effective Dates, Applying metadata to the generated posting, Automated Transactions
- @subsection State flags
- Although you cannot mark an automated transaction as a whole as
- cleared or pending, you can mark its postings with a @samp{*} or
- @samp{!} before the account name, and that state flag gets carried to
- the generated posting.
- @node Effective Dates, Periodic Transactions, State flags, Automated Transactions
- @subsection Effective Dates
- @cindex effective dates
- @findex --effective
- In the real world, transactions do not take place instantaneously.
- Purchases can take several days to post to a bank account. And you may
- pay ahead for something for which you want to distribute costs. With
- Ledger you can control every aspect of the timing of a transaction.
- Say you're in business. If you bill a customer, you can enter
- something like
- @cindex effective date of invoice
- @smallexample @c input:validate
- 2008/01/01=2008/01/14 Client invoice ; estimated date you'll be paid
- Assets:Accounts Receivable $100.00
- Income: Client name
- @end smallexample
- Then, when you receive the payment, you change it to
- @smallexample @c input:validate
- 2008/01/01=2008/01/15 Client invoice ; actual date money received
- Assets:Accounts Receivable $100.00
- Income: Client name
- @end smallexample
- @noindent
- and add something like
- @smallexample @c input:validate
- 2008/01/15 Client payment
- Assets:Checking $100.00
- Assets:Accounts Receivable
- @end smallexample
- Now
- @smallexample @c command:validate
- $ ledger --begin 2008/01/01 --end 2008/01/14 bal Income
- @end smallexample
- @noindent
- gives you your accrued income in the first two weeks of the year, and
- @smallexample @c command:validate
- $ ledger --effective --begin 2008/01/01 --end 2008/01/14 bal Income
- @end smallexample
- @noindent
- gives you your cash basis income in the same two weeks.
- Another use is distributing costs out in time. As an example, suppose
- you just prepaid into a local vegetable co-op that sustains you
- through the winter. It costs $225 to join the program, so you write
- a check. You don't want your October grocery budget to be blown
- because you bought food ahead, however. What you really want is for
- the money to be evenly distributed over the next six months so that
- your monthly budgets gradually take a hit for the vegetables you'll
- pick up from the co-op, even though you've already paid for them.
- @smallexample @c input:6453542
- 2008/10/16 * (2090) Bountiful Blessings Farm
- Expenses:Food:Groceries $ 37.50 ; [=2008/10/01]
- Expenses:Food:Groceries $ 37.50 ; [=2008/11/01]
- Expenses:Food:Groceries $ 37.50 ; [=2008/12/01]
- Expenses:Food:Groceries $ 37.50 ; [=2009/01/01]
- Expenses:Food:Groceries $ 37.50 ; [=2009/02/01]
- Expenses:Food:Groceries $ 37.50 ; [=2009/03/01]
- Assets:Checking
- @end smallexample
- This entry accomplishes this. Every month you'll see an
- automatic $37.50 deficit like you should, while your checking account
- really knows that it debited $225 this month.
- And using the @option{--effective} option, the initial date will be
- overridden by the effective dates.
- @smallexample @c command:6453542
- $ ledger --effective register Groceries
- @end smallexample
- @smallexample @c output:6453542
- 08-Oct-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 37.50
- 08-Nov-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 75.00
- 08-Dec-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 112.50
- 09-Jan-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 150.00
- 09-Feb-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 187.50
- 09-Mar-01 Bountiful Blessings.. Expense:Food:Groceries $ 37.50 $ 225.00
- @end smallexample
- @node Periodic Transactions, Concrete Example of Automated Transactions, Effective Dates, Automated Transactions
- @subsection Periodic Transactions
- @findex --budget
- A periodic transaction starts with a tilde @samp{~} followed by a period
- expression (see @ref{Period Expressions}). Periodic transactions are used for budgeting and
- forecasting only, they have no effect without the @option{--budget}
- option specified. For examples and details, @pxref{Budgeting and
- Forecasting}.
- @node Concrete Example of Automated Transactions, , Periodic Transactions, Automated Transactions
- @subsection Concrete Example of Automated Transactions
- As a Bahá'í, I need to compute Huqúqu'lláh whenever I acquire assets.
- It is similar to tithing for Jews and Christians, or to Zakát for
- Muslims. The exact details of computing Huqúqu'lláh are somewhat
- complex, but if you have further interest, please consult the Web.
- Ledger makes this otherwise difficult law very easy. Just set up an
- automated posting at the top of your ledger file:
- @smallexample @c input:C371854
- ; This automated transaction will compute Huqúqu'lláh based on this
- ; journal's postings. Any accounts that match will affect the
- ; Liabilities:Huququ'llah account by 19% of the value of that posting.
- = /^(?:Income:|Expenses:(?:Business|Rent$|Furnishings|Taxes|Insurance))/
- (Liabilities:Huququ'llah) 0.19
- @end smallexample
- This automated posting works by looking at each posting in the
- ledger file. If any match the given value expression, 19% of the
- posting's value is applied to the @samp{Liabilities:Huququ'llah}
- account. So, if $1000 is earned from @samp{Income:Salary}, $190 is
- added to @samp{Liabilities:Huqúqu'lláh}; if $1000 is spent on Rent,
- $190 is subtracted.
- @smallexample @c input:C371854
- 2003/01/01 (99) Salary
- Income:Salary -$1000
- Assets:Checking
- 2003/01/01 (100) Rent
- Expenses:Rent $500
- Assets:Checking
- @end smallexample
- The ultimate balance of Huqúqu'lláh reflects how
- much is owed in order to fulfill one's obligation to Huqúqu'lláh.
- When ready to pay, just write a check to cover the amount shown in
- @samp{Liabilities:Huququ'llah}. That transaction would look like:
- @smallexample @c input:validate
- 2003/01/01 (101) Baha'i Huqúqu'lláh Trust
- Liabilities:Huququ'llah $1,000.00
- Assets:Checking
- @end smallexample
- That's it. To see how much Huqúq is currently owed based on your
- ledger transactions, use:
- @smallexample @c command:C371854
- $ ledger balance Liabilities:Huquq
- @end smallexample
- @smallexample @c output:C371854
- $-95 Liabilities:Huququ'llah
- @end smallexample
- This works fine, but omits one aspect of the law: that Huqúq is only
- due once the liability exceeds the value of 19 mithqáls of gold (which
- is roughly 2.22 ounces). So what we want is for the liability to
- appear in the balance report only when it exceeds the present day
- value of 2.22 ounces of gold. This can be accomplished using the
- command:
- @c TODO: fix this, it doesn't work any longer
- @smallexample
- $ ledger -Q -t "/Liab.*Huquq/?(a/P@{2.22 AU@}<=@{-1.0@}&a):a" bal liab
- @end smallexample
- With this command, the current price for gold is downloaded, and the
- Huqúqu'lláh is reported only if its value exceeds that of 2.22 ounces
- of gold. If you wish the liability to be reflected in the parent
- subtotal either way, use this instead:
- @c TODO: fix this, it doesn't work any longer
- @smallexample
- $ ledger -Q -T "/Liab.*Huquq/?(O/P@{2.22 AU@}<=@{-1.0@}&O):O" bal liab
- @end smallexample
- In some cases, you may wish to refer to the account of whichever posting
- matched your automated transaction's value expression. To do this, use
- the special account name @samp{$account}:
- @smallexample @c input:validate
- = /^Some:Long:Account:Name/
- [$account] -0.10
- [Savings] 0.10
- @end smallexample
- This example causes 10% of the matching account's total to be deferred
- to the @samp{Savings} account---as a balanced virtual posting, which
- may be excluded from reports by using @option{--real}.
- @node Building Reports, Reporting Commands, Transactions, Top
- @chapter Building Reports
- @menu
- * Introduction::
- * Balance Reports::
- * Typical queries::
- * Advanced Reports::
- @end menu
- @node Introduction, Balance Reports, Building Reports, Building Reports
- @section Introduction
- The power of Ledger comes from the incredible flexibility in its
- reporting commands, combined with formatting commands. Some options
- control what is included in the calculations, and formatting controls
- how it is displayed. The combinations are infinite. This chapter will
- show you the basics of combining various options and commands. In the
- next chapters you will find details about the specific commands and
- options.
- @node Balance Reports, Typical queries, Introduction, Building Reports
- @section Balance Reports
- @menu
- * Controlling the Accounts and Payees::
- * Controlling Formatting::
- @end menu
- @node Controlling the Accounts and Payees, Controlling Formatting, Balance Reports, Balance Reports
- @subsection Controlling the Accounts and Payees
- The balance report is the most commonly used report. The simplest
- invocation is:
- @smallexample @c command:1D00D56
- $ ledger balance -f drewr3.dat
- @end smallexample
- @noindent
- which will print the balances of every account in your journal.
- @smallexample @c output:1D00D56
- $ -3,804.00 Assets
- $ 1,396.00 Checking
- $ 30.00 Business
- $ -5,200.00 Savings
- $ -1,000.00 Equity:Opening Balances
- $ 6,654.00 Expenses
- $ 5,500.00 Auto
- $ 20.00 Books
- $ 300.00 Escrow
- $ 334.00 Food:Groceries
- $ 500.00 Interest:Mortgage
- $ -2,030.00 Income
- $ -2,000.00 Salary
- $ -30.00 Sales
- $ -63.60 Liabilities
- $ -20.00 MasterCard
- $ 200.00 Mortgage:Principal
- $ -243.60 Tithe
- --------------------
- $ -243.60
- @end smallexample
- Most times, this is more than you want. Limiting the results to
- specific accounts is as easy as entering the names of the accounts
- after the command:
- @smallexample @c command:06B2AD4
- $ ledger balance -f drewr3.dat Auto MasterCard
- @end smallexample
- @smallexample @c output:06B2AD4
- $ 5,500.00 Expenses:Auto
- $ -20.00 Liabilities:MasterCard
- --------------------
- $ 5,480.00
- @end smallexample
- @noindent
- Note the implicit logical or between @samp{Auto} and
- @samp{Mastercard}.
- If you want the entire contents of a branch of your account tree, use
- the highest common name in the branch:
- @smallexample @c command:B0468E1
- $ ledger balance -f drewr3.dat Income
- @end smallexample
- @smallexample @c output:B0468E1
- $ -2,030.00 Income
- $ -2,000.00 Salary
- $ -30.00 Sales
- --------------------
- $ -2,030.00
- @end smallexample
- You can use general regular expressions in nearly any place Ledger
- needs a string:
- @smallexample @c command:EAE389F
- $ ledger balance -f drewr3.dat ^Bo
- @end smallexample
- @smallexample @c output:EAE389F
- @end smallexample
- This first example looks for any account starting with @samp{Bo}, of
- which there are none.
- @smallexample @c command:E2AF6AD
- $ ledger balance -f drewr3.dat Bo
- @end smallexample
- @smallexample @c output:E2AF6AD
- $ 20.00 Expenses:Books
- @end smallexample
- This second example looks for any account containing @samp{Bo}, which is
- @samp{Expenses:Books}.
- @cindex limit by payees
- @findex --limit @var{EXPR}
- If you want to know exactly how much you have spent in a particular
- account on a particular payee, the following are equivalent:
- @smallexample @c command:validate
- $ ledger balance Auto:Fuel and Chevron
- @end smallexample
- @smallexample @c command:validate
- $ ledger balance --limit 'account=~/Fuel/' and 'payee=~/Chev/'
- @end smallexample
- @noindent
- will show you the amount expended on gasoline at Chevron. The second
- example is the first example of the very powerful expression language
- available to shape reports. The first example may be easier to
- remember, but learning to use the second will open up far more
- possibilities.
- If you want to exclude specific accounts from the report, you can
- exclude multiple accounts with parentheses:
- @smallexample @c command:validate
- $ ledger bal Expenses and not (Expenses:Drinks or Expenses:Candy or Expenses:Gifts)
- @end smallexample
- @node Controlling Formatting, , Controlling the Accounts and Payees, Balance Reports
- @subsection Controlling Formatting
- These examples all use the default formatting for the balance
- report. Customizing the formatting can easily allowing to see only what
- you want, or interface Ledger with other programs.
- @node Typical queries, Advanced Reports, Balance Reports, Building Reports
- @section Typical queries
- A query such as the following shows all expenses since last
- October, sorted by total:
- @smallexample @c command:validate
- $ ledger -b "last oct" -S T bal ^expenses
- @end smallexample
- From left to right the options mean: Show transactions since last
- October; sort by the absolute value of the total; and report the balance
- for all accounts that begin with @samp{expenses}.
- @menu
- * Reporting monthly expenses::
- @end menu
- @node Reporting monthly expenses, , Typical queries, Typical queries
- @subsection Reporting monthly expenses
- @findex --monthly
- @findex --display @var{EXPR}
- @findex --period-sort @var{VEXPR}
- @findex --related
- @findex --subtotal
- The following query makes it easy to see monthly expenses, with each
- month's expenses sorted by the amount:
- @smallexample @c command:validate
- $ ledger -M --period-sort "(amount)" reg ^expenses
- @end smallexample
- Now, you might wonder where the money came from to pay for these things.
- To see that report, add @option{--related (-r)}, which shows the
- ``related account'' postings:
- @smallexample @c command:validate
- $ ledger -M --period-sort "(amount)" -r reg ^expenses
- @end smallexample
- But maybe this prints too much information. You might just want to
- see how much you're spending with your MasterCard. That kind of query
- requires the use of a display predicate, since the postings
- calculated must match @samp{^expenses}, while the postings
- displayed must match @samp{mastercard}. The command would be:
- @smallexample @c command:validate
- $ ledger -M -r --display 'account=~/mastercard/' reg ^expenses
- @end smallexample
- This query says: Report monthly subtotals; report the ``related
- account'' postings; display only related postings whose
- account matches @samp{mastercard}, and base the calculation on
- postings matching @samp{^expenses}.
- This works just as well for reporting the overall total, too:
- @smallexample @c command:validate
- $ ledger -s -r --display "account=~/mastercard/" reg ^expenses
- @end smallexample
- The @option{--subtotal (-s)} option subtotals all postings, just as
- @option{--monthly (-M)} subtotaled by the month. The running total in
- both cases is off, however, since a display expression is being used.
- @node Advanced Reports, , Typical queries, Building Reports
- @section Advanced Reports
- @menu
- * Asset Allocation::
- * Visualizing with Gnuplot::
- @end menu
- @node Asset Allocation, Visualizing with Gnuplot, Advanced Reports, Advanced Reports
- @subsection Asset Allocation
- A very popular method of managing portfolios is to control the
- percent allocation of assets by certain categories. The mix of
- categories and the weights applied to them vary by investing
- philosophy, but most follow a similar pattern. Tracking asset
- allocation in ledger is not difficult but does require some additional
- effort to describe how the various assets you own contribute to the
- asset classes you want to track.
- In our simple example we assume you want to apportion your assets into
- the general categories of domestic and international equities (stocks)
- and a combined category of bonds and cash. For illustrative purposes,
- we will use several publicly available mutual funds from Vanguard.
- The three funds we will track are the Vanguard 500 IDX FD Signal
- (VIFSX), the Vanguard Target Retirement 2030 (VTHRX), and the Vanguard
- Short Term Federal Fund (VSGBX). Each of these funds allocates assets
- to different categories of the investment universe and in different
- proportions. When you buy a share of VTHRX, that share is partially
- invested in equities, and partially invested in bonds and cash. Below
- is the asset allocation for each of the instruments listed above:
- @multitable @columnfractions .2 .2 .3 .3
- @item @tab Domestic @tab Global @tab
- @item Symbol @tab Equity @tab Equity @tab bonds/cash
- @item VIFSX @tab 100% @tab @tab
- @item VTHRX @tab 24.0% @tab 56.3% @tab 19.7%
- @item VSGBX @tab @tab @tab 100%
- @end multitable
- These numbers are available from the prospectus of any publicly
- available mutual fund. Of course a single stock issue is 100% equity
- and a single bond issue is 100% bonds.
- We track purchases of specific investments using the symbol of that
- investment as its commodity. How do we tell Ledger that a share of
- VTHRX is 24% Domestic equity? Enter automatic transactions and
- virtual accounts.
- At the top of our ledger we enter automatic transactions that describe
- these proportions to Ledger. In the same entries we set up virtual
- accounts that let us separate these abstract calculations from our
- actual balances.
- For the three instruments listed above, those automatic transactions
- would look like:
- @smallexample @c input:582C8C2
- = expr ( commodity == 'VIFSX' )
- (Allocation:Equities:Domestic) 1.000
- = expr ( commodity == 'VTHRX' )
- (Allocation:Equities:Global) 0.240
- (Allocation:Equities:Domestic) 0.563
- (Allocation:Bonds/Cash) 0.197
- = expr ( commodity == 'VBMFX')
- (Allocation:Bonds/Cash) 1.000
- 2015-01-01 Buy VIFSX
- Assets:Broker 100 VIFSX
- Assets:Cash $-10000
- 2015-01-01 Buy VTHRX
- Assets:Broker 10 VTHRX
- Assets:Cash $-10000
- 2015-01-01 Buy VBMFX
- Assets:Broker 1 VBMFX
- Assets:Cash $-10000
- @end smallexample
- How do these work? First the @samp{=} sign at the beginning of the
- line tells ledger this is an automatic transaction to be applied when
- the condition following the @samp{=} is true. After the @samp{=} sign
- is a value expression (@pxref{Value Expressions}) that returns true
- any time a posting contains the commodity of interest.
- The following line gives the proportions (not percentages) of each unit
- of commodity that belongs to each asset class. Whenever Ledger sees a
- buy or sell of a particular commodity it will credit or debit these
- virtual accounts with that proportion of the number of shares moved.
- Now that Ledger understands how to distribute the commodities amongst
- the various asset classes how do we get a report that tells us our
- current allocation? Using the balance command and some tricky
- formatting!
- @smallexample @c command:582C8C2
- ledger bal Allocation --current --format "\
- %-17((depth_spacer)+(partial_account))\
- %10(percent(market(display_total), market(parent.total)))\
- %16(market(display_total))\n%/"
- @end smallexample
- Which yields:
- @smallexample @c output:582C8C2
- Allocation 100.00% $30000
- Bonds/Cash 39.90% $11970
- Equities 60.10% $18030
- Domestic 86.69% $15630
- Global 13.31% $2400
- @end smallexample
- Let's look at the Ledger invocation a bit closer. The command above is
- split into lines for clarity. The first line is very vanilla Ledger
- asking for the current balances of the account in the ``Allocation''
- tree, using a special formatter.
- @cindex depth_spacer
- @cindex display_total
- @cindex parent.total
- The magic is in the formatter. The second line simply tells Ledger to
- print the partial account name indented by its depth in the tree. The
- third line is where we calculate and display the percentages. The
- @code{display_total} command gives the values of the total calculated
- for the account in this line. The @code{parent.total} command gives
- the total for the next level up in the tree. @code{percent} formats
- their ratio as a percentage. The fourth line tells ledger to display
- the current market value of the line. The last two characters
- @samp{%/} tell Ledger what to do for the last line, in this case,
- nothing.
- @node Visualizing with Gnuplot, , Asset Allocation, Advanced Reports
- @subsection Visualizing with Gnuplot
- @cindex plotting
- @cindex Gnuplot
- @findex --amount-data
- @findex --total-data
- @findex --limit @var{EXPR}
- @findex --display @var{EXPR}
- If you have the ``Gnuplot'' program installed, you can graph any of the
- above register reports. The script to do this is included in the ledger
- distribution, and is named @file{contrib/report}. Install @file{report}
- anywhere along your @env{PATH}, and then use @file{report} instead of
- @file{ledger} when doing a register report. The only thing to keep in
- mind is that you must specify @option{--amount-data (-j)} or
- @option{--total-data (-J)} to indicate whether ``Gnuplot'' should plot
- the amount, or the running total. For example, this command plots total
- monthly expenses made on your MasterCard.
- @smallexample
- $ report -j -M -r --display "account =~ /mastercard/" reg ^expenses
- @end smallexample
- The @file{report} script is a very simple Bourne shell script, that
- passes a set of scripted commands to ``Gnuplot''. Feel free to modify
- the script to your liking, since you may prefer histograms to line
- plots, for example.
- Here are some useful plots:
- @smallexample
- report -j -M reg ^expenses # monthly expenses
- report -J reg checking # checking account balance
- report -J reg ^income ^expenses # cash flow report
- # net worth report, ignoring non-$ postings
- report -J -l "Ua>=@{\$0.01@}" reg ^assets ^liab
- # net worth report starting last February. the use of a display
- # predicate (-d) is needed, otherwise the balance will start at
- # zero, and thus the y-axis will not reflect the true balance
- report -J -l "Ua>=@{\$0.01@}" -d "d>=[last feb]" reg ^assets ^liab
- @end smallexample
- The last report uses both a calculation predicate @option{--limit
- @var{EXPR} (-l)} and a display predicate @option{--display @var{EXPR}
- (-d)}. The calculation predicate limits the report to postings whose
- amount is greater than or equal to $1 (which can only happen if the
- posting amount is in dollars). The display predicate limits the
- transactions @emph{displayed} to just those since last February, even
- though those transactions from before will be computed as part of the
- balance.
- @node Reporting Commands, Command-Line Syntax, Building Reports, Top
- @chapter Reporting Commands
- @menu
- * Primary Financial Reports:: Reports in other formats:: Reports about
- * Reports in other Formats::
- * Reports about your Journals::
- @end menu
- @node Primary Financial Reports, Reports in other Formats, Reporting Commands, Reporting Commands
- @section Primary Financial Reports
- @menu
- * The @command{balance} command::
- * The @command{equity} command::
- * The @command{register} command::
- * The @command{print} command::
- @end menu
- @node The @command{balance} command, The @command{equity} command, Primary Financial Reports, Primary Financial Reports
- @subsection The @command{balance} command
- @findex balance
- The @command{balance} command reports the current balance of all
- accounts. It accepts a list of optional regexes, which confine the
- balance report to the matching accounts. If an account contains
- multiple types of commodities, each commodity's total is reported
- separately.
- @node The @command{equity} command, The @command{register} command, The @command{balance} command, Primary Financial Reports
- @subsection The @command{equity} command
- @findex equity
- The @command{equity} command prints out account balances as if they
- were transactions. This makes it easy to establish the starting
- balances for an account, such as when @ref{Archiving Previous Years}.
- @node The @command{register} command, The @command{print} command, The @command{equity} command, Primary Financial Reports
- @subsection The @command{register} command
- @findex register
- @findex --amount-data
- @findex --total-data
- The @command{register} command displays all the postings occurring in
- a single account, line by line. The account regex must be specified as
- the only argument to this command. If any regexes occur after the
- required account name, the register will contain only those postings
- that match, which makes it very useful for hunting down a particular
- posting.
- The output from @command{register} is very close to what a typical
- checkbook, or single-account ledger, would look like. It also shows a
- running balance. The final running balance of any register should
- always be the same as the current balance of that account.
- If you have ``Gnuplot'' installed, you may plot the amount or running
- total of any register by using the script @file{report}, which is
- included in the Ledger distribution. The only requirement is that you
- add either @option{--amount-data (-j)} or @option{--total-data (-J)} to
- your @command{register} command, in order to plot either the amount or
- total column, respectively.
- @node The @command{print} command, , The @command{register} command, Primary Financial Reports
- @subsection The @command{print} command
- @findex print
- The @command{print} command prints out ledger transactions in a textual
- format that can be parsed by Ledger. They will be properly formatted,
- and output in the most economic form possible. The @command{print}
- command also takes a list of optional regexes, which will cause only
- those postings which match in some way to be printed.
- The @command{print} command can be a handy way to clean up a ledger
- file whose formatting has gotten out of hand.
- @node Reports in other Formats, Reports about your Journals, Primary Financial Reports, Reporting Commands
- @section Reports in other Formats
- @menu
- * Comma Separated Values files::
- * The @command{lisp} command::
- * Emacs @command{org} Mode::
- * Org mode with Babel::
- * The @command{pricemap} command::
- * The @command{xml} command::
- * @command{prices} and @command{pricedb} commands::
- @end menu
- @node Comma Separated Values files, The @command{lisp} command, Reports in other Formats, Reports in other Formats
- @subsection Comma Separated Values files
- @menu
- * The @command{csv} command::
- * The @command{convert} command::
- @end menu
- @node The @command{csv} command, The @command{convert} command, Comma Separated Values files, Comma Separated Values files
- @subsubsection The @command{csv} command
- @findex csv
- The @command{csv} command prints the desired ledger
- transactions in a csv format suitable for importing into other programs.
- You can specify the transactions to print using all the normal
- limiting and searching functions.
- @node The @command{convert} command, , The @command{csv} command, Comma Separated Values files
- @subsubsection The @command{convert} command
- @cindex csv importing
- @cindex comma separated variable file reading
- @findex convert
- @findex --input-date-format @var{DATE_FORMAT}
- The @command{convert} command parses a comma separated value (csv) file
- and prints Ledger transactions. Many banks offer csv file downloads.
- Unfortunately, the file formats, aside from the commas, are all
- different. The ledger @command{convert} command tries to help as much
- as it can.
- Your bank's csv files will have fields in different orders from other
- banks, so there must be a way to tell Ledger what to expect. Insert
- a line at the beginning of the csv file that describes the fields to
- Ledger.
- For example, this is a portion of a csv file downloaded from a credit
- union in the United States:
- @smallexample
- Account Name: VALUFIRST CHECKING
- Account Number: 71
- Date Range: 11/13/2011 - 12/13/2011
- Transaction Number,Date,Description,Memo,Amount Debit,Amount Credit,Balance,Check Number,Fees
- 767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
- 767406,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-1.03,,00001648.84,,
- 683342,12/13/2011,"Visa Checking","NetFlix Date 12/12/11 000326585896 5968",-21.85,,00001649.87,,
- 639668,12/13/2011,"Withdrawal","ID: 1741472662 CO: XXAA.COM PAYMNT",-236.65,,00001671.72,,
- 1113648,12/12/2011,"Withdrawal","Tuscan IT #00037657",-29.73,,00001908.37,,
- @end smallexample
- Unfortunately, as it stands Ledger cannot read it, but you can. Ledger
- expects the first line to contain a description of the fields on each
- line of the file. The fields ledger can recognize contain these
- case-insensitive strings @code{date}, @code{posted}, @code{code},
- @code{payee} or @code{desc} or @code{description}, @code{amount},
- @code{cost}, @code{total}, and @code{note}.
- Delete the account description lines at the top, and replace the first
- line in the data above with:
- @smallexample
- ,date,payee,note,amount,,,code,
- @end smallexample
- Then execute ledger like this:
- @smallexample
- $ ledger convert download.csv --input-date-format "%m/%d/%Y"
- @end smallexample
- Where the @option{--input-date-format @var{DATE_FORMAT}} option tells
- ledger how to interpret the dates.
- Importing csv files is a lot of work, but is very amenable to
- scripting.
- If there are columns in the bank data you would like to keep in your
- ledger data, besides the primary fields described above, you can name
- them in the field descriptor list and Ledger will include them in the
- transaction as meta data if it doesn't recognize the field name. For
- example, if you want to capture the bank transaction number and it
- occurs in the first column of the data use:
- @smallexample
- transid,date,payee,note,amount,,,code,
- @end smallexample
- Ledger will include @samp{; transid: 767718} in the first transaction
- from the file above.
- @findex --invert
- @findex --auto-match
- @findex --account @var{STR}
- @findex --rich-data
- The @command{convert} command accepts four options. They are
- @option{--invert} which inverts the amount field, @option{--auto-match}
- which automatically matches an account from the Ledger journal for every
- CSV line, @option{--account @var{STR}} which you can use to specify the
- account to balance against, and @option{--rich-data} which stores
- additional tag/value pairs.
- Using the two first lines of the above csv file,
- @smallexample @c file:01B0350
- ,date,payee,note,amount,,,code,
- 767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
- 767406,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-1.03,,00001648.84,,
- @end smallexample
- and launching the below command,
- @smallexample @c command:01B0350,with_file:download.csv
- $ ledger convert download.csv --input-date-format "%m/%d/%Y" \
- --invert --account Assets:MyBank --rich-data \
- --file sample.dat --now=2012/01/13
- @end smallexample
- you will get the result:
- @smallexample @c output:01B0350
- 2011/12/13 * Withdrawal ;ACE HARDWARE 16335 S HOUGHTON RD
- ; CSV: 767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
- ; Imported: 2012/01/13
- ; UUID: dfdc3c3d5c54c6967dd39d5b4e4fd1ea76e87233
- Expenses:Unknown 8.8
- Assets:MyBank
- 2011/12/13 * Withdrawal ;ACE HARDWARE 16335 S HOUGHTON RD
- ; CSV: 767406,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-1.03,,00001648.84,,
- ; Imported: 2012/01/13
- ; UUID: 63086448b1f29f7fd6efb11ea40660185a213f9d
- Expenses:Unknown 1.03
- Assets:MyBank
- @end smallexample
- The three added metadata are: @samp{CSV} as the original line from csv
- file, @samp{Imported} as the date when the csv file was imported into
- Ledger, and @samp{UUID} as a checksum of original csv line.
- If an entry with the same @samp{UUID} tag is already included in the
- normal ledger file (specified via @option{--file @var{FILE} (-f)} or via
- the environment variable @env{LEDGER_FILE}) this entry will not be
- printed again.
- In the output above, the account is @samp{Expenses:Unknown} for CSV
- lines. You can use the @option{--auto-match} option to automatically
- match an account from your Ledger journal.
- You can also use @command{convert} with @code{payee} and @code{account}
- directives. First, you can use the @code{payee} and @code{alias}
- directive to rewrite the @code{payee} field based on some rules. Then
- you can use the account and its @code{payee} directive to specify the
- account. I use it like this, for example:
- @smallexample @c input:validate
- payee Aldi
- alias ^ALDI SUED SAGT DANKE
- account Aufwand:Einkauf:Lebensmittel
- payee ^(Aldi|Alnatura|Kaufland|REWE)$
- @end smallexample
- Note that it may be necessary for the output of @samp{ledger convert}
- to be passed through @code{ledger print} a second time if you want to
- match on the new payee field. During the @code{ledger convert} run,
- only the original payee name as specified in the csv data seems to be
- used.
- @node The @command{lisp} command, Emacs @command{org} Mode, Comma Separated Values files, Reports in other Formats
- @subsection The @command{lisp} command
- @findex lisp
- @findex emacs
- The @command{lisp} command prints results in a form that can be read
- directly by Emacs Lisp. The format of the @code{sexp} is:
- @smallexample
- ((BEG-POS CLEARED DATE CODE PAYEE
- (ACCOUNT AMOUNT)...) ; list of postings
- ...) ; list of transactions
- @end smallexample
- @noindent
- @command{emacs} can also be used as a synonym for @command{lisp}.
- @node Emacs @command{org} Mode, Org mode with Babel, The @command{lisp} command, Reports in other Formats
- @subsection Emacs @command{org} Mode
- @findex org
- The @command{org} command produces a journal file suitable for use in
- the Emacs Org mode. More details on using Org mode can be found at
- @url{http://www.orgmode.org}.
- Org mode has a sub-system known as Babel which allows for literate
- programming. This allows you to mix text and code within the same
- document and automatically execute code which may generate results
- which will then appear in the text.
- One of the languages supported by Babel is Ledger, so that you can have
- ledger commands embedded in a text file and have the output of ledger
- commands also appear in the text file. The output can be updated
- whenever any new ledger entries are added.
- For instance, the following Org mode text document snippet illustrates
- a very naive but still useful application of the Babel system:
- @smallexample
- * A simple test of ledger in an org file
- The following are some entries and I have requested that ledger be run
- to generate a balance on the accounts. I could have asked for
- a register or, in fact, anything at all the ledger can do through
- command-line options.
- #+begin_src ledger :cmdline bal :results value
- 2010/01/01 * Starting balance
- assets:bank:savings £1300.00
- income:starting balances
- 2010/07/22 * Got paid
- assets:bank:chequing £1000.00
- income:salary
- 2010/07/23 Rent
- expenses:rent £500.00
- assets:bank:chequing
- #+end_src
- #+results:
- : £1800.00 assets:bank
- : £500.00 chequing
- : £1300.00 savings
- : £500.00 expenses:rent
- : £-2300.00 income
- : £-1000.00 salary
- : £-1300.00 starting balances
- @end smallexample
- Typing @kbd{C-c C-c} anywhere in the ``ledger source code block'' will
- invoke ledger on the contents of that block and generate a ``results''
- block. The results block can appear anywhere in the file but, by
- default, will appear immediately below the source code block.
- You can combine multiple source code blocks before executing ledger and
- do all kinds of other wonderful things with Babel (and Org mode).
- @node Org mode with Babel, The @command{pricemap} command, Emacs @command{org} Mode, Reports in other Formats
- @subsection Org mode with Babel
- Using Babel, it is possible to record financial transactions
- conveniently in an org file and subsequently generate the financial
- reports required.
- As of Org mode 7.01, Ledger support is provided. Check the Babel
- documentation on Worg for instructions on how to achieve this but
- I currently do this directly as follows:
- @smallexample
- (org-babel-do-load-languages
- 'org-babel-load-languages
- '((ledger . t) ;this is the important one for this tutorial
- ))
- @end smallexample
- Once Ledger support in Babel has been enabled, we can proceed to
- include Ledger entries within an org file. There are three ways (at
- least) in which these can be included:
- @enumerate
- @item
- place all Ledger entries within one single source block and execute this
- block with different arguments to generate the appropriate reports,
- @item
- place Ledger entries in more than one source block and use the
- @code{noweb} literary programming approach, supported by Babel, to
- combine these into one block elsewhere in the file for processing by
- Ledger,
- @item
- place Ledger entries in different source blocks and use @code{tangle} to
- generate a Ledger file which you can subsequently process using Ledger
- directly.
- @end enumerate
- The first two are described in more detail in this short tutorial.
- @menu
- * Embedded Ledger example with single source block::
- * Multiple Ledger source blocks with @code{noweb}::
- * Income Entries::
- * Expenses::
- * Financial Summaries::
- * An overall balance summary::
- * Generating a monthly register::
- * Summary::
- @end menu
- @node Embedded Ledger example with single source block, Multiple Ledger source blocks with @code{noweb}, Org mode with Babel, Org mode with Babel
- @subsubsection Embedded Ledger example with single source block
- The easiest, albeit possibly least useful, way in which to use Ledger
- within an org file is to use a single source block to record all Ledger
- entries. The following is an example source block:
- @smallexample
- #+name: allinone
- #+begin_src ledger
- 2010/01/01 * Starting balance
- assets:bank:savings £1300.00
- income:starting balances
- 2010/07/22 * Got paid
- assets:bank:chequing £1000.00
- income:salary
- 2010/07/23 Rent
- expenses:rent £500.00
- assets:bank:chequing
- 2010/07/24 Food
- expenses:food £150.00
- assets:bank:chequing
- 2010/07/31 * Interest on bank savings
- assets:bank:savings £3.53
- income:interest
- 2010/07/31 * Transfer savings
- assets:bank:savings £250.00
- assets:bank:chequing
- 2010/08/01 got paid again
- assets:bank:chequing £1000.00
- income:salary
- #+end_src
- @end smallexample
- In this example, we have combined both expenses and income into one set
- of Ledger entries. We can now generate register and balance reports (as
- well as many other types of reports) using Babel to invoke Ledger with
- specific arguments. The arguments are passed to Ledger using the
- @code{:cmdline} header argument. In the code block above, there is no
- such argument so the system takes the default. For Ledger code blocks,
- the default @code{:cmdline} argument is @code{bal} and the result of
- evaluating this code block (@kbd{C-c C-c}) would be:
- @smallexample
- #+results: allinone()
- : £2653.53 assets:bank
- : £1100.00 chequing
- : £1553.53 savings
- : £650.00 expenses
- : £150.00 food
- : £500.00 rent
- : £-3303.53 income
- : £-3.53 interest
- : £-2000.00 salary
- : £-1300.00 starting balances
- @end smallexample
- If, instead, you wished to generate a register of all the transactions,
- you would change the @code{#+begin_src} line for the code block to
- include the required command-line option:
- @smallexample
- #+begin_src ledger :cmdline reg
- @end smallexample
- Evaluating the code block again would generate a different report.
- Having to change the actual directive on the code block and re-evaluate
- makes it difficult to have more than one view of your transactions and
- financial state. Eventually, Babel will support passing arguments to
- @code{#+call} evaluations of code blocks but this support is missing
- currently. Instead, we can use the concepts of literary programming, as
- implemented by the @code{noweb} features of Babel, to help us.
- @node Multiple Ledger source blocks with @code{noweb}, Income Entries, Embedded Ledger example with single source block, Org mode with Babel
- @subsubsection Multiple Ledger source blocks with @code{noweb}
- The @code{noweb} feature of Babel allows us to expand references to
- other code blocks within a code block. For Ledger, this can be used to
- group transactions according to type, say, and then bring various sets
- of transactions together to generate reports.
- Using the same transactions used above, we could consider splitting
- these into expenses and income, as follows:
- @node Income Entries, Expenses, Multiple Ledger source blocks with @code{noweb}, Org mode with Babel
- @subsubsection Income Entries
- The first set of entries relates to income, either monthly pay or
- interest, all typically going into one of my bank accounts. Here, I have
- placed several entries, but we could have had each entry in a separate
- @code{src} block. Note that all code blocks you wish to refer to later
- must have the @code{:noweb yes} header argument specified.
- @smallexample
- #+name: income
- #+begin_src ledger :noweb yes
- 2010/01/01 * Starting balance
- assets:bank:savings £1300.00
- income:starting balances
- 2010/07/22 * Got paid
- assets:bank:chequing £1000.00
- income:salary
- 2010/07/31 * Interest on bank savings
- assets:bank:savings £3.53
- income:interest
- 2010/07/31 * Transfer savings
- assets:bank:savings £250.00
- assets:bank:chequing
- 2010/08/01 got paid again
- assets:bank:chequing £1000.00
- income:salary
- #+end_src
- @end smallexample
- @node Expenses, Financial Summaries, Income Entries, Org mode with Babel
- @subsubsection Expenses
- The following entries relate to personal expenses, such as rent and
- food. Again, these have all been placed in a single @code{src} block but
- could have been done individually.
- @smallexample
- #+name: expenses
- #+begin_src ledger :noweb yes
- 2010/07/23 Rent
- expenses:rent £500.00
- assets:bank:chequing
- 2010/07/24 Food
- expenses:food £150.00
- assets:bank:chequing
- #+end_src
- @end smallexample
- @node Financial Summaries, An overall balance summary, Expenses, Org mode with Babel
- @subsubsection Financial Summaries
- Given the ledger entries defined above in the income and expenses code
- blocks, we can now refer to these using the noweb expansion directives,
- @code{<<name>>}. We can now define different code blocks to generate
- specific reports for those transactions. Below are two examples, one to
- generate a balance report and one to generate a register report of all
- transactions.
- @node An overall balance summary, Generating a monthly register, Financial Summaries, Org mode with Babel
- @subsubsection An overall balance summary
- @findex --subtotal
- The overall balance of your account and expenditure with a breakdown
- according to category is specified by passing the @code{:cmdline bal}
- argument to Ledger. This code block can now be evaluated (@kbd{C-c C-c})
- and the results generated by incorporating the transactions referred to
- by the @code{<<income>>} and @code{<<expenses>>} lines.
- @smallexample
- #+name: balance
- #+begin_src ledger :cmdline bal :noweb yes
- <<income>>
- <<expenses>>
- #+end_src
- #+results: balance
- : £2653.53 assets:bank
- : £1100.00 chequing
- : £1553.53 savings
- : £650.00 expenses
- : £150.00 food
- : £500.00 rent
- : £-3303.53 income
- : £-3.53 interest
- : £-2000.00 salary
- : £-1300.00 starting balances
- @end smallexample
- If you want a less detailed breakdown of where your money is, you can
- specify the @option{--collapse (-n)} flag (i.e. @samp{:cmdline -n bal})
- to tell Ledger to exclude sub-accounts in the report.
- @smallexample
- #+begin_src ledger :cmdline -n bal :noweb yes
- <<income>>
- <<expenses>>
- #+end_src
- #+results:
- : £2653.53 assets
- : £650.00 expenses
- : £-3303.53 income
- @end smallexample
- @node Generating a monthly register, Summary, An overall balance summary, Org mode with Babel
- @subsubsection Generating a monthly register
- @findex register
- @findex --monthly
- You can also generate a monthly register (the @command{reg} command) by
- executing the following @code{src} block. This presents a summary of
- transactions for each monthly period (the @option{--monthly (-M)}
- argument) with a running total in the final column (which should be 0 at
- the end if all the entries are correct).
- @smallexample
- #+name: monthlyregister
- #+begin_src ledger :cmdline -M reg :noweb yes
- <<income>>
- <<expenses>>
- #+end_src
- #+results: monthlyregister
- :2010/01/01 - 2010/01/31 assets:bank:savings £1300.00 £1300.00
- : in:starting balances £-1300.00 0
- :2010/07/01 - 2010/07/31 assets:bank:chequing £100.00 £100.00
- : assets:bank:savings £253.53 £353.53
- : expenses:food £150.00 £503.53
- : expenses:rent £500.00 £1003.53
- : income:interest £-3.53 £1000.00
- : income:salary £-1000.00 0
- :2010/08/01 - 2010/08/01 assets:bank:chequing £1000.00 £1000.00
- : income:salary £-1000.00 0
- @end smallexample
- We could also generate a monthly report on our assets showing how these
- are increasing (or decreasing!). In this case, the final column will be
- the running total of the assets in our ledger.
- @smallexample
- #+name: monthlyassetsregister
- #+begin_src ledger :cmdline -M reg assets :noweb yes
- <<income>>
- <<expenses>>
- #+end_src
- #+results: monthlyassetsregister
- : 2010/01/01 - 2010/01/31 assets:bank:savings £1300.00 £1300.00
- : 2010/07/01 - 2010/07/31 assets:bank:chequing £100.00 £1400.00
- : assets:bank:savings £253.53 £1653.53
- : 2010/08/01 - 2010/08/01 assets:bank:chequing £1000.00 £2653.53
- @end smallexample
- @node Summary, , Generating a monthly register, Org mode with Babel
- @subsubsection Summary
- This short tutorial shows how Ledger entries can be embedded in an org
- file and manipulated using Babel. However, only simple Ledger features
- have been illustrated; please refer to the Ledger documentation for
- examples of more complex operations on a ledger.
- @node The @command{pricemap} command, The @command{xml} command, Org mode with Babel, Reports in other Formats
- @subsection The @command{pricemap} command
- @findex pricemap
- If you have the @file{graphviz} graph visualization package installed,
- ledger can generate a graph of the relationship between your various
- commodities. The output file is in the ``dot'' format.
- This is probably not very interesting, unless you have many different
- commodities valued in terms of each other. For example, multiple
- currencies and multiple investments valued in those currencies.
- @node The @command{xml} command, @command{prices} and @command{pricedb} commands, The @command{pricemap} command, Reports in other Formats
- @subsection The @command{xml} command
- @findex xml
- By default, Ledger uses a human-readable data format, and displays its
- reports in a manner meant to be read on screen. For the purpose of
- writing tools which use Ledger, however, it is possible to read and
- display data using XML. This section documents that format.
- The general format used for Ledger data is:
- @smallexample
- <?xml version="1.0"?>
- <ledger>
- <xact>...</xact>
- <xact>...</xact>
- <xact>...</xact>...
- </ledger>
- @end smallexample
- The data stream is enclosed in a @code{ledger} tag, which contains a
- series of one or more transactions. Each @code{xact} describes one
- transaction and contains a series of one or more postings:
- @smallexample
- <xact>
- <en:date>2004/03/01</en:date>
- <en:cleared/>
- <en:code>100</en:code>
- <en:payee>John Wiegley</en:payee>
- <en:postings>
- <posting>...</posting>
- <posting>...</posting>
- <posting>...</posting>...
- </en:postings>
- </xact>
- @end smallexample
- The date format for @code{en:date} is always @code{YYYY/MM/DD}. The
- @code{en:cleared} tag is optional, and indicates whether the posting has
- been cleared or not. There is also an @code{en:pending} tag, for
- marking pending postings. The @code{en:code} and @code{en:payee} tags
- both contain whatever text the user wishes.
- After the initial transaction data, there must follow a set of postings
- marked with @code{en:postings}. Typically these postings will all
- balance each other, but if not they will be automatically balanced into
- an account named @samp{Unknown}.
- Within the @code{en:postings} tag is a series of one or more
- @code{posting}'s, which have the following form:
- @smallexample
- <posting>
- <tr:account>Expenses:Computer:Hardware</tr:account>
- <tr:amount>
- <value type="amount">
- <amount>
- <commodity flags="PT">$</commodity>
- <quantity>90.00</quantity>
- </amount>
- </value>
- </tr:amount>
- </posting>
- @end smallexample
- This is a basic posting. It may also begin with
- @code{tr:virtual} and/or @code{tr:generated} tags, to indicate virtual
- and auto-generated postings. Then follows the @code{tr:account}
- tag, which contains the full name of the account the posting is
- related to. Colons separate parent from child in an account name.
- Lastly follows the amount of the posting, indicated by
- @code{tr:amount}. Within this tag is a @code{value} tag, of which
- there are four different kinds, each with its own format:
- @enumerate
- @item Boolean,
- @item integer,
- @item amount,
- @item balance.
- @end enumerate
- The format of a Boolean value is @code{true} or @code{false}
- surrounded by a @code{boolean} tag, for example:
- @smallexample
- <boolean>true</boolean>
- @end smallexample
- The format of an integer value is the numerical value surrounded by an
- @code{integer} tag, for example:
- @smallexample
- <integer>12036</integer>
- @end smallexample
- The format of an amount contains two members, the commodity and the
- quantity. The commodity can have a set of flags that indicate how to
- display it. The meaning of the flags (all of which are optional) are:
- @table @code
- @item P
- The commodity is prefixed to the value.
- @item S
- The commodity is separated from the value by a space.
- @item T
- Thousands markers are used to display the amount.
- @item E
- The format of the amount is European, with period used as a thousands
- marker, and comma used as the decimal point.
- @end table
- The actual quantity for an amount is an integer of arbitrary size.
- Ledger uses the GNU multiple precision arithmetic library to handle
- such values. The XML format assumes the reader to be equally capable.
- Here is an example amount:
- @smallexample
- <value type="amount">
- <amount>
- <commodity flags="PT">$</commodity>
- <quantity>90.00</quantity>
- </amount>
- </value>
- @end smallexample
- Lastly, a balance value contains a series of amounts, each with a
- different commodity. Unlike the name, such a value does need to
- balance. It is called a balance because it sums several amounts. For
- example:
- @smallexample
- <value type="balance">
- <balance>
- <amount>
- <commodity flags="PT">$</commodity>
- <quantity>90.00</quantity>
- </amount>
- <amount>
- <commodity flags="TE">DM</commodity>
- <quantity>200.00</quantity>
- </amount>
- </balance>
- </value>
- @end smallexample
- That is the extent of the XML data format used by Ledger. It will
- output such data if the @command{xml} command is used, and can read
- the same data.
- @node @command{prices} and @command{pricedb} commands, , The @command{xml} command, Reports in other Formats
- @subsection @command{prices} and @command{pricedb} commands
- @findex prices
- @findex pricedb
- @findex --average
- The @command{prices} command displays the price history for matching
- commodities. The @option{--average (-A)} option is useful with this
- report, to display the running average price, or @option{--deviation
- (-D)} to show each price's deviation from that average.
- There is also a @command{pricedb} command which outputs the same
- information as @command{prices}, but does so in a format that can be
- parsed by Ledger. This is useful for generating and tidying up
- pricedb database files.
- @node Reports about your Journals, , Reports in other Formats, Reporting Commands
- @section Reports about your Journals
- @findex --count
- @menu
- * @command{accounts}::
- * @command{payees}::
- * @command{commodities}::
- * @command{tags}::
- * @command{xact}::
- * @command{stats}::
- * @command{select}::
- @end menu
- @node @command{accounts}, @command{payees}, Reports about your Journals, Reports about your Journals
- @subsection @command{accounts}
- @findex accounts
- The @command{accounts} command reports all of the accounts in the
- journal. Following the command with a regular expression will limit the
- output to accounts matching the regex. The output is sorted by name.
- Using the @option{--count} option will tell you how many entries use
- each account.
- @node @command{payees}, @command{commodities}, @command{accounts}, Reports about your Journals
- @subsection @command{payees}
- @findex payees
- The @command{payees} command reports all of the unique payees in the
- journal. Using the @option{--count} option will tell you how many
- entries use each payee. To filter the payees displayed you must use the
- prefix @@:
- @smallexample @c command:validate
- $ ledger payees @@Nic
- @end smallexample
- @smallexample
- Nicolas
- Nicolas BOILABUS
- Oudtshoorn Municipality
- Vaca Veronica
- @end smallexample
- @node @command{commodities}, @command{tags}, @command{payees}, Reports about your Journals
- @subsection @command{commodities}
- @findex commodities
- Report all commodities present in the journals under consideration. The
- output is sorted by name. Using the @option{--count} option will tell
- you how many entries use each commodity.
- @node @command{tags}, @command{xact}, @command{commodities}, Reports about your Journals
- @subsection @command{tags}
- @findex tags
- @findex --values
- The @command{tags} command reports all of the tags in the journal. The
- output is sorted by name. Using the @option{--count} option will tell
- you how many entries use each tag. Using the @option{--values} option
- will report the values used by each tag.
- @node @command{xact}, @command{stats}, @command{tags}, Reports about your Journals
- @subsection @command{xact}
- @findex draft
- @findex entry
- @findex xact
- The @command{xact} command simplifies the creation of new transactions.
- It works on the principle that 80% of all postings are variants of
- earlier postings. Here's how it works:
- Say you currently have this posting in your ledger file:
- @smallexample @c input:03ACB97
- 2004/03/15 * Viva Italiano
- Expenses:Food $12.45
- Expenses:Tips $2.55
- Liabilities:MasterCard $-15.00
- @end smallexample
- Now it's @samp{2004/4/9}, and you've just eaten at @samp{Viva Italiano}
- again. The exact amounts are different, but the overall form is the
- same. With the @command{xact} command you can type:
- @smallexample @c command:03ACB97
- $ ledger xact 2004/4/9 viva food 11 tips 2.50
- @end smallexample
- This produces the following output:
- @smallexample @c output:03ACB97
- 2004/04/09 Viva Italiano
- Expenses:Food $11.00
- Expenses:Tips $2.50
- Liabilities:MasterCard
- @end smallexample
- It works by finding a past posting matching the regular expression
- @samp{viva}, and assuming that any accounts or amounts specified will be
- similar to that earlier posting. If Ledger does not succeed in
- generating a new transaction, an error is printed and the exit code is
- set to @samp{1}.
- Here are a few more examples of the @command{xact} command, assuming
- the above journal transaction:
- @smallexample
- $ ledger xact 4/9 viva 11.50
- $ ledger xact 4/9 viva 11.50 checking # (from `checking')
- $ ledger xact 4/9 viva food 11.50 tips 8
- $ ledger xact 4/9 viva food 11.50 tips 8 cash
- $ ledger xact 4/9 viva food $11.50 tips $8 cash
- $ ledger xact 4/9 viva dining "DM 11.50"
- @end smallexample
- @command{draft} and @command{entry} are both synonyms of
- @command{xact}. @command{entry} is provided for backwards compatibility
- with Ledger 2.X.
- @node @command{stats}, @command{select}, @command{xact}, Reports about your Journals
- @subsection @command{stats}
- @findex stats
- @findex stat
- @value{FIXME:UNDOCUMENTED}
- @node @command{select}, , @command{stats}, Reports about your Journals
- @subsection @command{select}
- @findex select
- @value{FIXME:UNDOCUMENTED}
- @node Command-Line Syntax, Budgeting and Forecasting, Reporting Commands, Top
- @chapter Command-Line Syntax
- @menu
- * Basic Usage::
- * Command-Line Quick Reference::
- * Detailed Option Description::
- * Period Expressions::
- @end menu
- @node Basic Usage, Command-Line Quick Reference, Command-Line Syntax, Command-Line Syntax
- @section Basic Usage
- This chapter describes Ledger's features and options. You may wish to
- survey this to get an overview before diving into the @ref{Ledger
- Tutorial} and more detailed examples that follow.
- Ledger has a very simple command-line interface, named---enticingly
- enough---@file{ledger}. It supports a few reporting commands, and
- a large number of options for refining the output from those commands.
- The basic syntax of any ledger command is:
- @smallexample
- $ ledger [OPTIONS...] COMMAND [ARGS...]
- @end smallexample
- After the command word there may appear any number of arguments. For
- most commands, these arguments are regular expressions that cause the
- output to relate only to postings matching those regular expressions.
- For the @command{xact} command, the arguments have a special meaning,
- described below.
- The regular expressions arguments always match the account name that
- a posting refers to. To match on the payee of the transaction
- instead, precede the regular expression with @samp{payee} or
- @samp{@@}. For example, the following balance command reports account
- totals for rent, food and movies, but only those whose payee matches
- Freddie:
- @smallexample @c command:validate
- $ ledger bal rent food movies payee freddie
- @end smallexample
- @noindent
- or
- @smallexample @c command:validate
- $ ledger bal rent food movies @@freddie
- @end smallexample
- There are many, many command options available with the @file{ledger}
- program, and it takes a while to master them. However, none of them are
- required to use the basic reporting commands.
- @node Command-Line Quick Reference, Detailed Option Description, Basic Usage, Command-Line Syntax
- @section Command-Line Quick Reference
- @menu
- * Basic Reporting Commands::
- * Basic Options::
- * Report Filtering::
- * Error Checking and Calculation Options::
- * Output Customization::
- * Grouping Options::
- * Commodity Reporting::
- @end menu
- @node Basic Reporting Commands, Basic Options, Command-Line Quick Reference, Command-Line Quick Reference
- @subsection Basic Reporting Commands
- @ftable @command
- @item balance
- @itemx bal
- Show account balances.
- @item register
- @itemx reg
- Show all transactions with running total.
- @item csv
- @cindex csv exporting
- Show transactions in csv format, for exporting to other programs.
- @item print
- Print transactions in a format readable by ledger.
- @item xml
- Produce XML output of the register command.
- @item lisp
- @itemx emacs
- Produce s-expression output, suitable for Emacs.
- @item equity
- Print account balances as transactions.
- @item prices
- Print price history for matching commodities.
- @item pricedb
- Print price history for matching commodities in a format readable by
- ledger.
- @item xact
- Generate transactions based on previous postings.
- @end ftable
- @node Basic Options, Report Filtering, Basic Reporting Commands, Command-Line Quick Reference
- @subsection Basic Options
- @ftable @option
- @item --help
- @itemx -h
- Display the man page for @file{ledger}.
- @item --version
- Print version information and exit.
- @item --file @var{FILE}
- @itemx -f @var{FILE}
- Read @file{FILE} as a ledger file.
- @item --output @var{FILE}
- @itemx -o @var{FILE}
- Redirect output to @file{FILE}.
- @item --init-file @var{FILE}
- @itemx -i @var{FILE}
- Specify an options file.
- @item --import @var{FILE}
- Import @var{FILE} as Python module.
- @item --account @var{STR}
- @itemx -a @var{STR}
- Specify default account @var{STR} for QIF file postings.
- @end ftable
- @node Report Filtering, Error Checking and Calculation Options, Basic Options, Command-Line Quick Reference
- @subsection Report Filtering
- @ftable @option
- @item --current
- @itemx -c
- Display only transactions on or before the current date.
- @item --begin @var{DATE}
- @itemx -b @var{DATE}
- Limit the processing to transactions on or after @var{DATE}.
- @item --end @var{DATE}
- @itemx -e @var{DATE}
- Limit the processing to transactions before @var{DATE}.
- @item --period @var{PERIOD_EXPRESSION}
- @itemx -p @var{PERIOD_EXPRESSION}
- Limit the processing to transactions in @var{PERIOD_EXPRESSION}.
- @item --period-sort @var{VEXPR}
- Sort postings within each period according to @var{VEXPR}.
- @item --cleared
- @itemx -C
- Display only cleared postings.
- @item --dc
- Display register or balance in debit/credit format.
- @item --uncleared
- @itemx -U
- Display only uncleared postings.
- @item --real
- @itemx -R
- Display only real postings.
- @item --actual
- @itemx -L
- Display only actual postings, not automated ones.
- @item --related
- @itemx -r
- Display related postings.
- @item --budget
- Display how close your postings meet your budget.
- @item --add-budget
- Show unbudgeted postings.
- @item --unbudgeted
- Show only unbudgeted postings.
- @item --forecast-while @var{VEXPR}
- @itemx --forecast @var{VEXPR}
- Project balances into the future.
- @item --limit @var{EXPR}
- @itemx -l @var{EXPR}
- Limit which postings are used in calculations by @var{EXPR}.
- @item --amount @var{EXPR}
- @itemx -t @var{EXPR}
- Change value expression reported in @command{register} report.
- @item --total @var{VEXPR}
- @itemx -T @var{VEXPR}
- Change the value expression used for ``totals'' column in
- @command{register} and @command{balance} reports.
- @end ftable
- @node Error Checking and Calculation Options, Output Customization, Report Filtering, Command-Line Quick Reference
- @subsection Error Checking and Calculation Options
- @ftable @option
- @item --strict
- Accounts, tags or commodities not previously declared will cause
- warnings.
- @item --pedantic
- Accounts, tags or commodities not previously declared will cause errors.
- @item --check-payees
- Enable strict and pedantic checking for payees as well as accounts,
- commodities and tags. This only works in conjunction with
- @option{--strict} or @option{--pedantic}.
- @item --immediate
- Instruct ledger to evaluate calculations immediately rather than lazily.
- @end ftable
- @node Output Customization, Grouping Options, Error Checking and Calculation Options, Command-Line Quick Reference
- @subsection Output Customization
- @ftable @option
- @item --collapse
- @itemx -n
- Collapse transactions with multiple postings.
- @item --subtotal
- @itemx -s
- Report register as a single subtotal.
- @item --by-payee
- @itemx -P
- Report subtotals by payee.
- @item --empty
- @itemx -E
- Include empty accounts in the report.
- @item --weekly
- @itemx -W
- Report posting totals by week.
- @item --quarterly
- Report posting totals by quarter.
- @item --yearly
- @itemx -Y
- Report posting totals by year.
- @item --dow
- Report posting totals by day of week.
- @item --sort @var{VEXPR}
- @itemx -S @var{VEXPR}
- Sort a report using @var{VEXPR}.
- @item --wide
- @itemx -w
- Assume 132 columns instead of 80.
- @item --head @var{INT}
- Report the first @var{INT} postings.
- @item --tail @var{INT}
- Report the last @var{INT} postings.
- @item --pager @var{FILE}
- Direct output to @var{FILE} pager program.
- @item --no-pager
- Direct output to stdout, avoiding pager program.
- @item --average
- @itemx -A
- Report the average posting value.
- @item --deviation
- @itemx -D
- Report each posting's deviation from the average.
- @item --percent
- @itemx -%
- Show subtotals in the balance report as percentages.
- @c @item --totals
- @c Include running total in the @command{xml} report
- @item --pivot @var{TAG}
- Produce a pivot table of the @var{TAG} type specified.
- @item --amount-data
- @itemx -j
- Show only the date and value columns to format the output for plots.
- @item --plot-amount-format @var{FORMAT_STRING}
- Specify the format for the plot output.
- @item --total-data
- @itemx -J
- Show only the date and total columns to format the output for plots.
- @item --plot-total-format @var{FORMAT_STRING}
- Specify the format for the plot output.
- @item --display @var{EXPR}
- @itemx -d @var{EXPR}
- Display only postings that meet the criteria in the @var{EXPR}.
- @item --date-format @var{DATE_FORMAT}
- @itemx -y @var{DATE_FORMAT}
- Change the basic date format used in reports.
- @item --format @var{FORMAT_STRING}
- @itemx --balance-format @var{FORMAT_STRING}
- @itemx --register-format @var{FORMAT_STRING}
- @itemx --prices-format @var{FORMAT_STRING}
- @itemx -F @var{FORMAT_STRING}
- Set the reporting format for various reports.
- @item --anon
- Print the ledger register with anonymized accounts and payees, useful
- for filing bug reports.
- @end ftable
- @node Grouping Options, Commodity Reporting, Output Customization, Command-Line Quick Reference
- @subsection Grouping Options
- @ftable @option
- @item --by-payee
- @itemx -P
- Group postings by common payee names.
- @item --daily
- @itemx -D
- Group postings by day.
- @item --weekly
- @itemx -W
- Group postings by week.
- @item --monthly
- @itemx -M
- Group postings by month.
- @item --quarterly
- Group postings by quarter.
- @item --yearly
- @itemx -Y
- Group postings by year.
- @item --dow
- Group by day of weeks.
- @item --subtotal
- @itemx -s
- Group postings together, similar to the balance report.
- @end ftable
- @node Commodity Reporting, , Grouping Options, Command-Line Quick Reference
- @subsection Commodity Reporting
- @ftable @option
- @item --price-db @var{FILE}
- Use @file{FILE} for retrieving stored commodity prices.
- @item --price-exp @var{INT}
- @itemx --leeway @var{INT}
- @itemx -Z @var{INT}
- Set expected freshness of prices in @var{INT} minutes.
- @item --download
- @itemx -Q
- Download quotes using the script named @file{getquote}.
- @c FIXME: The option doesn't exist currently.
- @c @item --getquote @var{FILE}
- @c Sets the path to a user-defined script to download commodity prices.
- @item --quantity
- @itemx -O
- Report commodity totals without conversion.
- @item --basis
- @itemx -B
- Report cost basis.
- @item --market
- @itemx -V
- Report last known market value.
- @item --gain
- @itemx -G
- Report net gain or loss for commodities that have a price history.
- @end ftable
- @node Detailed Option Description, Period Expressions, Command-Line Quick Reference, Command-Line Syntax
- @section Detailed Option Description
- @menu
- * Global Options::
- * Session Options::
- * Report Options::
- * Basic options::
- * Report filtering::
- * Output customization::
- * Commodity reporting::
- * Environment variables::
- @end menu
- @node Global Options, Session Options, Detailed Option Description, Detailed Option Description
- @subsection Global Options
- Options for Ledger reports affect three separate scopes of operation:
- Global, Session, and Report. In practice there is very little
- difference between these scopes. Ledger 3.0 contains provisions for
- GUIs, which would make use of the different scopes by keeping an
- instance of Ledger running in the background and running multiple
- sessions with multiple reports per session.
- @ftable @option
- @item --args-only
- Ignore all environment and init-file settings and
- use only command-line arguments to control Ledger. Useful for debugging
- or testing small journal files not associated with your main financial
- database.
- @item --debug @var{CODE}
- @value{FIXME:UNDOCUMENTED}
- If ledger has been built with debug options this will provide extra data during
- the run.
- @item --help
- @itemx -h
- Display the man page for @file{ledger}.
- @item --init-file @var{FILE}
- Specify the location of the init file. The default is home directory
- @file{~/.ledgerrc}, or current directory @file{./.ledgerrc} if not found
- in home directory.
- @item --options
- Display the options in effect for this Ledger invocation, along with
- their values and the source of those values, for example:
- @smallexample @c command:A9349E4,with_input:03ACB97
- $ ledger --options bal --cleared
- @end smallexample
- @smallexample @c output:A9349E4
- ===============================================================================
- [Global scope options]
- --args-only --args-only
- [Session scope options]
- --file = A9349E4.dat --file
- [Report scope options]
- --cleared --cleared
- --columns = 80 --columns
- --limit = cleared --cleared
- ===============================================================================
- $15.00 Expenses
- $12.45 Food
- $2.55 Tips
- $-15.00 Liabilities:MasterCard
- --------------------
- 0
- @end smallexample
- @noindent
- For the source column, a value starting with a @samp{-} or @samp{--}
- indicated the source was a command-line argument. If the entry starts
- with a @samp{$}, the source was an environment variable. If the source
- is @code{?normalize} the value was set internally by ledger, in
- a function called @code{normalize_options}.
- @item --script @var{FILE}
- Execute a ledger script.
- @item --trace @var{INT}
- Enable tracing. The @var{INT} specifies the level of trace desired.
- @item --verbose
- @itemx -v
- Print detailed information on the execution of Ledger.
- @item --verify
- Enable additional assertions during run-time. This causes a significant
- slowdown. When combined with @option{--debug @var{CODE}} ledger will
- produce memory trace information.
- @item --verify-memory
- Verify that every constructed object is properly destructed. This is for
- debugging purposes only.
- @item --version
- Print version information and exit.
- @end ftable
- @node Session Options, Report Options, Global Options, Detailed Option Description
- @subsection Session Options
- Options for Ledger reports affect three separate scopes of operation:
- Global, Session, and Report. In practice there is very little
- difference between these scopes. Ledger 3.0 contains provisions for
- GUIs, which would make use of the different scopes by keeping an
- instance of Ledger running in the background and running multiple
- sessions with multiple reports per session.
- @ftable @option
- @item --check-payees
- Enable strict and pedantic checking for payees as well as accounts,
- commodities and tags. This only works in conjunction with
- @option{--strict} or @option{--pedantic}.
- @item --day-break
- Break up @command{register} report of @ref{timelog} entries that span multiple
- days by day.
- @c see test/baseline/opt-day-break.dat
- @c @smallexample @c input:
- @c i 2015/
- @c @end smallexample
- @c @smallexample @c command:
- @c $ ledger reg --day-break
- @c @end smallexample
- @c @smallexample @c output:
- @c @end smallexample
- @item --decimal-comma
- Direct Ledger to parse journals using the European standard comma as
- a decimal separator, not the usual period.
- @item --download
- @itemx -Q
- Direct Ledger to download prices.
- @c using the script defined via the option
- @c @option{--getquote @var{FILE}}.
- @item --explicit
- Direct Ledger to require pre-declarations for entities (such as accounts,
- commodities and tags) rather than taking entities from cleared
- transactions as defined. This option is useful in combination with
- @option{--strict} or @option{--pedantic}.
- @item --file @var{FILE}
- @itemx -f @var{FILE}
- Specify the input @file{FILE} for this invocation.
- @c FIXME: The option doesn't exist currently.
- @c @item --getquote @var{FILE}
- @c @cindex getquote
- @c @cindex download prices
- @c Tell ledger where to find the user defined script to download prices
- @c information.
- @item --input-date-format @var{DATE_FORMAT}
- Specify the input date format for journal entries. For example,
- @smallexample
- $ ledger convert Export.csv --input-date-format "%m/%d/%Y"
- @end smallexample
- Would convert the @file{Export.csv} file to ledger format, assuming
- the dates in the CSV file are like 12/23/2009 (@pxref{Date and Time
- Format Codes}).
- @item --master-account @var{STR}
- Prepend all account names with the argument.
- @smallexample @c command:A76BB56
- $ ledger -f drewr3.dat bal --no-total --master-account HUMBUG
- @end smallexample
- @smallexample @c output:A76BB56
- 0 HUMBUG
- $ -3,804.00 Assets
- $ 1,396.00 Checking
- $ 30.00 Business
- $ -5,200.00 Savings
- $ -1,000.00 Equity:Opening Balances
- $ 6,654.00 Expenses
- $ 5,500.00 Auto
- $ 20.00 Books
- $ 300.00 Escrow
- $ 334.00 Food:Groceries
- $ 500.00 Interest:Mortgage
- $ -2,030.00 Income
- $ -2,000.00 Salary
- $ -30.00 Sales
- $ 180.00 Liabilities
- $ -20.00 MasterCard
- $ 200.00 Mortgage:Principal
- @end smallexample
- @item --no-aliases
- Ledger does not expand any aliases if this option is specified.
- @item --pedantic
- Accounts, tags or commodities not previously declared will cause errors.
- @item --permissive
- Quiet balance assertions.
- @item --price-db @var{FILE}
- Specify the location of the price entry data file.
- @item --price-exp @var{INT}
- @itemx --leeway @var{INT}
- @itemx -Z @var{INT}
- Set the expected freshness of price quotes, in @var{INT} minutes. That
- is, if the last known quote for any commodity is older than this value,
- and if @option{--download} is being used, then the Internet will be
- consulted again for a newer price. Otherwise, the old price is still
- considered to be fresh enough.
- @item --strict
- Ledger normally silently accepts any account or commodity in a posting,
- even if you have misspelled a commonly used one. The option
- @option{--strict} changes that behavior. While running with
- @option{--strict}, Ledger interprets all cleared transactions as
- correct, and if it encounters a new account or commodity (same as
- a misspelled commodity or account) it will issue a warning giving you
- the file and line number of the problem.
- @item --recursive-aliases
- Normally, ledger only expands aliases once. With this option, ledger
- tries to expand the result of alias expansion recursively, until no more
- expansions apply.
- @item --time-colon
- The @option{--time-colon} option will display the value for a seconds
- based commodity as real hours and minutes.
- For example 8100 seconds by default will be displayed as 2.25 whereas
- with the @option{--time-colon} option they will be displayed as 2:15.
- @item --value-expr @var{VEXPR}
- Set a global value expression annotation.
- @c needs example
- @end ftable
- @node Report Options, Basic options, Session Options, Detailed Option Description
- @subsection Report Options
- Options for Ledger reports affect three separate scopes of operation:
- Global, Session, and Report. In practice there is very little
- difference between these scopes. Ledger 3.0 contains provisions for
- GUIs, which would make use of the different scopes by keeping an
- instance of Ledger running in the background and running multiple
- sessions with multiple reports per session.
- @ftable @option
- @item --abbrev-len @var{INT}
- Set the minimum length an account can be abbreviated to if it doesn't
- fit inside the @code{account-width}. If @var{INT} is zero, then the
- account name will be truncated on the right. If @var{INT} is greater
- than @code{account-width} then the account will be truncated on the
- left, with no shortening of the account names in order to fit into the
- desired width.
- @item --account @var{STR}
- Prepend @var{STR} to all accounts reported. That is, the option
- @samp{--account Personal} would tack @samp{Personal:} to the beginning
- of every account reported in a balance report or register report.
- @item --account-width @var{INT}
- Set the width of the account column in the @command{register} report
- to @var{INT} characters.
- @item --actual
- @itemx -L
- Report only real transactions, ignoring all automated or virtual
- transactions.
- @item --add-budget
- Show only unbudgeted postings.
- @item --amount @var{EXPR}
- @itemx -t @var{EXPR}
- Apply the given value expression to the posting amount (@pxref{Value
- Expressions}). Using @option{--amount @var{EXPR}} you can apply an
- arbitrary transformation to the postings.
- @item --amount-data
- @itemx -j
- On a register report print only the date and amount of postings.
- Useful for graphing and spreadsheet applications.
- @item --amount-width @var{INT}
- Set the width in characters of the amount column in the
- @command{register} report.
- @item --anon
- Anonymize registry output, mostly for sending in bug reports.
- @item --auto-match
- When generating a ledger transaction from a CSV file using the
- @command{convert} command, automatically match an account from the
- Ledger journal.
- @item --aux-date
- @itemx --effective
- Show auxiliary dates for all calculations (@pxref{Effective Dates}).
- @item --average
- @itemx -A
- Print average values over the number of transactions instead of
- running totals.
- @item --balance-format @var{FORMAT_STRING}
- Specify the format to use for the @command{balance} report (@pxref{Format
- Strings}). The default is:
- @smallexample
- "%(justify(scrub(display_total), 20, -1, true, color))"
- " %(!options.flat ? depth_spacer : \"\")"
- "%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
- "%$1\n%/"
- "--------------------\n"
- @end smallexample
- @item --base
- Reduce convertible commodities down the bottom of the conversion, e.g.
- display time in seconds. This also applies to custom commodity
- conversions (@pxref{Commodity equivalences}).
- @item --basis
- @itemx -B
- @itemx --cost
- Report the cost basis on all posting.
- @item --begin @var{DATE}
- Specify the start @var{DATE} of all calculations. Transactions before
- that date will be ignored.
- @item --bold-if @var{VEXPR}
- Print the entire line in bold if the given value expression is true
- (@pxref{Value Expressions}).
- @smallexample @c command:validate
- $ ledger reg Expenses --begin Dec --bold-if "amount>100"
- @end smallexample
- @noindent
- list all transactions since the beginning of December and print in
- bold any posting greater than $100.
- @item --budget
- Only display budgeted items. In a register report this
- displays transactions in the budget, in a balance report this displays
- accounts in the budget (@pxref{Budgeting and Forecasting}).
- @item --budget-format @var{FORMAT_STRING}
- Specify the format to use for the @command{budget} report (@pxref{Format
- Strings}). The default is:
- @smallexample
- "%(justify(scrub(display_total), 20, -1, true, color))"
- " %(!options.flat ? depth_spacer : \"\")"
- "%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
- "%$1\n%/"
- "--------------------\n"
- @end smallexample
- @item --by-payee
- @itemx -P
- Group the register report by payee.
- @item --cleared
- @itemx -C
- Consider only transactions that have been cleared for display and
- calculation.
- @item --cleared-format @var{FORMAT_STRING}
- @c FIXME thdox: to keep?
- Specify the format to use for the @command{cleared} report (@pxref{Format
- Strings}). The default is:
- @smallexample
- "%(justify(scrub(get_at(total_expr, 0)), 16, 16 + prepend_width, "
- " true, color)) %(justify(scrub(get_at(total_expr, 1)), 18, "
- " 36 + prepend_width, true, color))"
- " %(latest_cleared ? format_date(latest_cleared) : \" \")"
- " %(!options.flat ? depth_spacer : \"\")"
- "%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
- "%$1 %$2 %$3\n%/"
- "%(prepend_width ? \" \" * prepend_width : \"\")"
- "---------------- ---------------- ---------\n"
- @end smallexample
- @item --collapse
- @itemx -n
- By default ledger prints all accounts in an account tree. With
- @option{--collapse} it prints only the top level account specified.
- @item --collapse-if-zero
- Collapse the account display only if it has a zero balance.
- @item --color
- @itemx --ansi
- Use color if the terminal supports it.
- @item --columns @var{INT}
- Specify the width of the @command{register} report in characters.
- @item --count
- Direct ledger to report the number of items when appended to the
- @command{commodities}, @command{accounts} or @command{payees} command.
- @item --csv-format @var{FORMAT_STRING}
- Specify the format to use for the @command{csv} report (@pxref{Format
- Strings}). The default is:
- @smallexample
- "%(quoted(date)),"
- "%(quoted(code)),"
- "%(quoted(payee)),"
- "%(quoted(display_account)),"
- "%(quoted(commodity(scrub(display_amount)))),"
- "%(quoted(quantity(scrub(display_amount)))),"
- "%(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),"
- "%(quoted(join(note | xact.note)))\n"
- @end smallexample
- @item --current
- Shorthand for @samp{--limit "date <= today"}.
- @item --daily
- @itemx -D
- Shorthand for @samp{--period "daily"}.
- @item --date @var{EXPR}
- Transform the date of the transaction using @var{EXPR}.
- @item --date-format @var{DATE_FORMAT}
- @itemx -y @var{DATE_FORMAT}
- Specify the format ledger should use to read and print dates
- (@pxref{Date and Time Format Codes}).
- @item --date-width @var{INT}
- Specify the width, in characters, of the date column in the
- @command{register} report.
- @item --datetime-format @var{DATETIME_FORMAT}
- Specify the format ledger should use to print datetimes.
- @item --dc
- Display register or balance in debit/credit format If you use
- @option{--dc} with either the @command{register} (reg) or
- @command{balance} (bal) commands, you will now get extra columns.
- The register goes from this:
- @smallexample
- 12-Mar-10 Employer Assets:Cash $100 $100
- Income:Employer $-100 0
- 12-Mar-10 KFC Expenses:Food $20 $20
- Assets:Cash $-20 0
- 12-Mar-10 KFC - Rebate Assets:Cash $5 $5
- Expenses:Food $-5 0
- 12-Mar-10 KFC - Food & Reb.. Expenses:Food $20 $20
- Expenses:Food $-5 $15
- Assets:Cash $-15 0
- @end smallexample
- @noindent
- To this:
- @smallexample
- 12-Mar-10 Employer Assets:Cash $100 0 $100
- In:Employer 0 $100 0
- 12-Mar-10 KFC Expens:Food $20 0 $20
- Assets:Cash 0 $20 0
- 12-Mar-10 KFC - Rebate Assets:Cash $5 0 $5
- Expens:Food 0 $5 0
- 12-Mar-10 KFC - Food &.. Expens:Food $20 0 $20
- Expens:Food 0 $5 $15
- Assets:Cash 0 $15 0
- @end smallexample
- @noindent
- Where the first column is debits, the second is credits, and the third
- is the running total. Only the running total may contain negative
- values.
- For the balance report without @option{--dc}:
- @smallexample
- $70 Assets:Cash
- $30 Expenses:Food
- $-100 Income:Employer
- --------------------
- 0
- @end smallexample
- @noindent
- And with @option{--dc} it becomes this:
- @smallexample
- $105 $35 $70 Assets:Cash
- $40 $10 $30 Expenses:Food
- 0 $100 $-100 Income:Employer
- --------------------------------------------
- $145 $145 0
- @end smallexample
- @item --depth @var{INT}
- Limit the depth of the account tree. In a balance report, for example,
- a @samp{--depth 2} statement will print balances only for accounts with
- two levels, i.e. @samp{Expenses:Entertainment} but not
- @samp{Expenses:Entertainment:Dining}. This is a display predicate, which
- means it only affects display, not the total calculations.
- @item --deviation
- Report each posting’s deviation from the average. It is only meaningful
- in the register and prices reports.
- @item --display @var{EXPR}
- Display only lines that satisfy the expression @var{EXPR}.
- @item --display-amount @var{EXPR}
- Apply a transformation to the @emph{displayed} amount. This happens
- after calculations occur.
- @item --display-total @var{EXPR}
- Apply a transformation to the @emph{displayed} total. This happens after
- calculations occur.
- @item --dow
- @itemx --days-of-week
- Group transactions by the day of the week.
- @smallexample @c command:validate
- $ ledger reg Expenses --dow --collapse
- @end smallexample
- @noindent
- Will print all Expenses totaled for each day of the week.
- @item --empty
- @itemx -E
- Include empty accounts in the report and in average calculations.
- @item --end @var{DATE}
- Specify the end @var{DATE} for a transaction to be considered in the
- report. All transactions on or after this date are ignored.
- @item --equity
- Related to the @command{equity} command (@pxref{The @command{equity}
- command}). Gives current account balances in the form of a register
- report.
- @item --exact
- Report beginning and ending of periods by the date of the first and last
- posting occurring in that period.
- @item --exchange @var{COMMODITY}
- @itemx -X @var{COMMODITY}
- Display values in terms of the given @var{COMMODITY}. The latest
- available price is used. The syntax
- @option{-X @var{COMMODITY1}:@var{COMMODITY2}} displays values in @var{COMMODITY1}
- in terms of @var{COMMODITY2} using the latest available price, but
- will not automatically covert any other commodities to
- @var{COMMODITY2}. Multiple @option{-X} arguments may be used on a
- single command-line (as in
- @option{-X COMMODITY1:COMMODITY2 -X COMMODITY3:COMMODITY2}),
- which is particularly useful for situations where many prices are
- available for reporting in terms of @var{COMMODITY2}, but only a few
- should be displayed that way.
- @item --flat
- Force the full names of accounts to be used in the balance report. The
- balance report will not use an indented tree.
- @item --force-color
- Output TTY color codes even if the TTY doesn't support them. Useful
- for TTYs that don't advertise their capabilities correctly.
- @item --force-pager
- Force Ledger to paginate its output.
- @item --forecast-while @var{VEXPR}
- @itemx --forecast @var{VEXPR}
- Continue forecasting while @var{VEXPR} is true.
- @item --forecast-years @var{INT}
- Forecast at most @var{INT} years into the future.
- @item --format @var{FORMAT_STRING}
- @itemx -F @var{FORMAT_STRING}
- Use the given format string to print output.
- @item --gain
- @itemx -G
- @itemx --change
- Report on gains using the latest available prices.
- @item --generated
- Include auto-generated postings (such as those from automated
- transactions) in the report, in cases where you normally wouldn't want
- them.
- @item --group-by @var{EXPR}
- Group transactions together in the @command{register} report.
- @var{EXPR} can be anything, although most common would be @code{payee}
- or @code{commodity}. The @code{tags()} function is also useful here.
- @item --group-title-format @var{FORMAT_STRING}
- Set the format for the headers that separates the report sections of
- a grouped report. Only has an effect with a @option{--group-by
- @var{EXPR}} register report.
- @smallexample @c command:validate
- $ ledger reg Expenses --group-by "payee" --group-title-format "------------------------ %-20(value) ---------------------\n"
- @end smallexample
- @smallexample
- ------------------------ 7-Eleven ---------------------
- 2011/08/13 7-Eleven Expenses:Auto:Misc $ 5.80 $ 5.80
- ------------------------ AAA Dues ---------------------
- 2011/06/02 AAA Dues Expenses:Auto:Misc $ 215.00 $ 215.00
- ------------------------ ABC Towing and Wrecking ---------------------
- 2011/03/17 ABC Towing and Wrec.. Expenses:Auto:Hobbies $ 48.20 $ 48.20
- ...
- @end smallexample
- @item --head @var{INT}
- @itemx --first @var{INT}
- Print the first @var{INT} entries. Opposite of @option{--tail
- @var{INT}}.
- @item --historical
- @itemx -H
- Value commodities at the time of their acquisition.
- @item --immediate
- Evaluate calculations immediately rather than lazily.
- @item --inject
- Use @code{Expected} amounts in calculations. In case you know
- what amount a transaction should be, but the actual transaction has the
- wrong value you can use metadata to specify the expected amount:
- @smallexample @c input:validate
- 2012-03-12 Paycheck
- Income $-990; Expected:: $-1000.00
- Checking
- @end smallexample
- Then using the command @code{ledger reg --inject=Expected Income} would
- treat the transaction as if the ``Expected Value'' was actual.
- @item --invert
- Change the sign of all reported values.
- @item --limit @var{EXPR}
- @itemx -l @var{EXPR}
- Only transactions that satisfy @var{EXPR} are considered in
- calculations and for display.
- @item --lot-dates
- Report the date on which each commodity in a balance report was
- purchased.
- @item --lot-notes
- @itemx --lot-tags
- Report the tag attached to each commodity in a balance report.
- @item --lot-prices
- Report the price at which each commodity in a balance report was
- purchased.
- @item --lots
- Report the date and price at which each commodity was purchased in
- a balance report.
- @item --lots-actual
- Preserve the uniqueness of commodities so they aren't merged during
- reporting without printing the lot annotations.
- @item --market
- @itemx -V
- Use the latest market value for all commodities.
- @item --meta @var{TAG}
- In the register report, prepend the transaction with the value of the
- given @var{TAG}.
- @item --meta-width @var{INT}
- Specify the width of the Meta column used for the @option{--meta
- @var{TAG}} options.
- @item --monthly
- @itemx -M
- Synonym for @samp{--period "monthly"}.
- @item --no-aliases
- Aliases are completely ignored.
- @item --no-color
- Suppress any color TTY output.
- @item --no-pager
- Direct output to stdout, avoiding pager program.
- @item --no-revalued
- Stop Ledger from showing @code{<Revalued>} postings. This option is useful
- in combination with the @option{--exchange} or @option{--market} option.
- @item --no-rounding
- Don't output @samp{<Adjustment>} postings. Note that this will cause the
- running total to often not add up! Its main use is for
- @option{--amount-data (-j)} and @option{--total-data (-J)} reports.
- @item --no-titles
- Suppress the output of group titles.
- @item --no-total
- Suppress printing the final total line in a balance report.
- @item --now @var{DATE}
- Define the current date in case you want to calculate in the past or
- future using @option{--current}.
- @item --only @var{FIXME}
- This is a postings predicate that applies after certain transforms have
- been executed, such as periodic gathering.
- @item --output @var{FILE}
- Redirect the output of ledger to the file defined in @file{FILE}.
- @item --pager @var{FILE}
- Direct output to @var{FILE} pager program.
- @item --payee @var{VEXPR}
- Sets a value expression for formatting the payee. In the
- @command{register} report this prevents the second entry from having
- a date and payee for each transaction.
- @item --payee-width @var{INT}
- Set the number of columns dedicated to the payee in the register
- report to @var{INT}.
- @item --pending
- Use only postings that are marked pending.
- @item --percent
- @itemx -%
- Calculate the percentage value of each account in balance reports.
- Only works for accounts that have a single commodity.
- @item --period @var{PERIOD_EXPRESSION}
- Define a period expression that sets the time period during which
- transactions are to be accounted. For a @command{register} report only
- the transactions that satisfy the period expression with be displayed.
- For a @command{balance} report only those transactions will be accounted
- in the final balances.
- @item --pivot @var{TAG}
- Produce a balance pivot report @emph{around} the given @var{TAG}. For
- example, if you have multiple cars and track each fuel purchase in
- @samp{Expenses:Auto:Fuel} and tag each fuel purchase with a tag
- identifying which car the purchase was for @samp{; Car: Prius}, then the
- command:
- @smallexample @c command:validate
- $ ledger bal Fuel --pivot "Car" --period "this year"
- @end smallexample
- @smallexample
- $ 3491.26 Car
- $ 1084.22 M3:Expenses:Auto:Fuel
- $ 149.65 MG V11:Expenses:Auto:Fuel
- $ 621.89 Prius:Expenses:Auto:Fuel
- $ 1635.50 Sienna:Expenses:Auto:Fuel
- $ 42.69 Expenses:Auto:Fuel
- --------------------
- $ 3533.95
- @end smallexample
- @xref{Metadata values}.
- @item --plot-amount-format @var{FORMAT_STRING}
- Define the output format for an amount data plot. @xref{Visualizing
- with Gnuplot}.
- @item --plot-total-format @var{FORMAT_STRING}
- Define the output format for a total data plot. @xref{Visualizing with
- Gnuplot}.
- @item --prepend-format @var{FORMAT_STRING}
- Prepend @var{STR} to every line of the output.
- @item --prepend-width @var{INT}
- Reserve @var{INT} spaces at the beginning of each line of the output.
- @item --price
- @itemx -I
- Use the price of the commodity purchase for performing calculations.
- @item --pricedb-format @var{FORMAT_STRING}
- Set the format expected for the historical price file.
- @item --prices-format @var{FORMAT_STRING}
- Set the format for the @command{prices} report.
- @item --primary-date
- @itemx --actual-dates
- Show primary dates for all calculations (@pxref{Effective Dates}).
- @item --quantity
- @itemx -O
- Report commodity totals (this is the default).
- @item --quarterly
- Synonym for @samp{--period "quarterly"}.
- @item --raw
- In the @command{print} report, show transactions using the exact same
- syntax as specified by the user in their data file. Don't do any
- massaging or interpreting. This can be useful for minor cleanups, like
- just aligning amounts.
- @item --real
- @itemx -R
- Account using only real transactions ignoring virtual and automatic
- transactions.
- @item --register-format @var{FORMAT_STRING}
- Define the output format for the @command{register} report.
- @item --related
- In a @command{register} report show the related account. This is the
- other @emph{side} of the transaction.
- @item --related-all
- Show all postings in a transaction, similar to @option{--related} but
- show both @emph{sides} of each transaction.
- @item --revalued
- Report discrepancy in values for manual reports by inserting @code{<Revalued>}
- postings. This is implied when using the @option{--exchange} or
- @option{--market} option.
- @item --revalued-only
- Show only @code{<Revalued>} postings.
- @item --revalued-total @var{FIXME}
- Display the sum of the revalued postings as the running total, which serves
- to show unrealized capital in a gain/losses report.
- @item --rich-data
- @itemx --detail
- When generating a ledger transaction from a CSV file using the
- @command{convert} command, add CSV, Imported, and UUID metadata.
- @item --seed @var{INT}
- Set the random seed to @var{INT} for the @code{generate} command.
- Used as part of development testing.
- @item --sort @var{VEXPR}
- @itemx -S @var{VEXPR}
- Sort the @command{register} report based on the value expression given
- to sort.
- @item --sort-all @var{FIXME}
- @value{FIXME:UNDOCUMENTED}
- @item --sort-xacts @var{VEXPR}
- @itemx --period-sort @var{VEXPR}
- Sort the postings within transactions using the given value expression.
- @item --start-of-week @var{INT}
- Tell ledger to use a particular day of the week to start its ``weekly''
- summary. @samp{--start-of-week=1} specifies Monday as the start of the
- week.
- @item --subtotal
- @itemx -s
- Cause all transactions in a @command{register} report to be collapsed
- into a single, subtotaled transaction.
- @item --tail @var{INT}
- @itemx --last @var{INT}
- Report only the last @var{INT} entries. Only useful in
- a @command{register} report.
- @item --time-report
- Add two columns to the balance report to show the earliest checkin and
- checkout times for timelog entries.
- @item --total @var{VEXPR}
- @itemx -T @var{VEXPR}
- Define a value expression used to calculate the total in reports.
- @item --total-data
- @itemx -J
- Show only dates and totals to format the output for plots.
- @item --total-width @var{INT}
- Set the width of the total field in the register report.
- @item --truncate @var{CODE}
- Indicates how truncation should happen when the contents of columns
- exceed their width. Valid arguments are @samp{leading}, @samp{middle},
- and @samp{trailing}. The default is smarter than any of these three,
- as it considers sub-names within the account name (that style is
- called ``abbreviate'').
- @item --unbudgeted
- Show only unbudgeted postings.
- @item --uncleared
- @itemx -U
- Use only uncleared transactions in calculations and reports.
- @item --unrealized
- Show generated unrealized gain and loss accounts in the balance
- report.
- @item --unrealized-gains @var{STR}
- Allow the user to specify what account name should be used for
- unrealized gains. Defaults to @samp{"Equity:Unrealized Gains"}.
- Often set in one's @file{~/.ledgerrc} file to change the default.
- @item --unrealized-losses @var{STR}
- Allow the user to specify what account name should be used for
- unrealized losses. Defaults to @samp{"Equity:Unrealized Losses"}.
- Often set in one's @file{~/.ledgerrc} file to change the default.
- @item --unround
- Perform all calculations without rounding and display results to full
- precision.
- @item --values
- Shows the values used by each tag when used in combination with the
- @command{tags} command.
- @item --weekly
- @itemx -W
- Synonym for @samp{--period "weekly"}.
- @item --wide
- Let the register report use 132 columns instead of 80 (the default).
- Identical to @samp{--columns "132"}.
- @item --yearly
- @itemx -Y
- Synonym for @samp{--period "yearly"}.
- @end ftable
- @node Basic options, Report filtering, Report Options, Detailed Option Description
- @subsection Basic options
- These are the most basic command options. Most likely, the user will
- want to set them using environment variables (see @ref{Environment
- variables}), instead of using actual command-line options:
- @ftable @option
- @item --help
- @itemx -h
- Display the man page for @file{ledger}.
- @item --version
- Print the current version of ledger and exits. This is useful for
- sending bug reports, to let the author know which version of ledger you
- are using.
- @item --file @var{FILE}
- @itemx -f @var{FILE}
- Read @file{FILE} as a ledger file. @var{FILE} can be @samp{-} which is
- a synonym for @samp{/dev/stdin}. This command may be used multiple
- times. Typically, the environment variable @env{LEDGER_FILE} is set,
- rather than using this command-line option.
- @item --output @var{FILE}
- @itemx -o @var{FILE}
- Redirect output from any command to @file{FILE}. By default, all output
- goes to standard output.
- @item --init-file @var{FILE}
- @itemx -i @var{FILE}
- Causes @file{FILE} to be read by ledger before any other ledger file.
- This file may not contain any postings, but it may contain option
- settings. To specify options in the init file, use the same syntax as
- on the command-line, but put each option on its own line. Here is an
- example init file:
- @smallexample @c input:validate
- --price-db ~/finance/.pricedb
- --wide
- ; ~/.ledgerrc ends here
- @end smallexample
- Option settings on the command-line or in the environment always take
- precedence over settings in the init file.
- @item --account @var{STR}
- @itemx -a @var{STR}
- Specify the default account which QIF file postings are assumed to
- relate to.
- @end ftable
- @node Report filtering, Output customization, Basic options, Detailed Option Description
- @subsection Report filtering
- These options change which postings affect the outcome of a
- report, in ways other than just using regular expressions:
- @ftable @option
- @item --current
- @itemx -c
- Display only transactions occurring on or before the current date.
- @item --begin @var{DATE}
- @itemx -b @var{DATE}
- Constrain the report to transactions on or after @var{DATE}. Only
- transactions after that date will be calculated, which means that the
- running total in the balance report will always start at zero with the
- first matching transaction. (Note: This is different from using
- @option{--display @var{EXPR}} to constrain what is displayed).
- @item --end @var{DATE}
- @itemx -e @var{DATE}
- Constrain the report so that transactions on or after @var{DATE} are
- not considered.
- @item --period @var{PERIOD_EXPRESSION}
- @itemx -p @var{PERIOD_EXPRESSION}
- Set the reporting period to @var{STR}. This will subtotal all matching
- transactions within each period separately, making it easy to see
- weekly, monthly, quarterly, etc., posting totals. A period string can
- even specify the beginning and end of the report range, using simple
- terms like @samp{last June} or @samp{next month}. For more details on
- period expressions, see @ref{Period Expressions}.
- @item --period-sort @var{VEXPR}
- Sort the postings within each reporting period using the value
- expression @var{EXPR}. This is most often useful when reporting
- monthly expenses, in order to view the highest expense categories at
- the top of each month:
- @c TODO: the parameter to --period-sort was -At, which doesn't seem to work any longer
- @smallexample @c command:validate
- $ ledger -M --period-sort total reg ^Expenses
- @end smallexample
- @item --cleared
- @itemx -C
- Display only postings whose transaction has been marked ``cleared''
- (by placing an asterisk to the right of the date).
- @item --uncleared
- @itemx -U
- Display only postings whose transaction has not been marked ``cleared''
- (i.e., if there is no asterisk to the right of the date).
- @item --real
- @itemx -R
- Display only real postings, not virtual. (A virtual posting is
- indicated by surrounding the account name with parentheses or brackets;
- see @ref{Virtual postings} for more information).
- @item --actual
- @itemx -L
- Display only actual postings, and not those created by automated
- transactions.
- @item --related
- @itemx -r
- Display postings that are related to whichever postings would
- otherwise have matched the filtering criteria. In the register
- report, this shows where money went to, or the account it came from.
- In the balance report, it shows all the accounts affected by
- transactions having a related posting. For example, if a file had
- this transaction:
- @smallexample @c input:94C5675
- 2004/03/20 Safeway
- Expenses:Food $65.00
- Expenses:Cash $20.00
- Assets:Checking $-85.00
- @end smallexample
- And the register command was:
- @smallexample @c command:94C5675
- $ ledger -f example.dat -r register food
- @end smallexample
- The following would be printed, showing the postings related to the
- posting that matched:
- @smallexample @c output:94C5675
- 04-Mar-20 Safeway Expenses:Cash $20.00 $20.00
- Assets:Checking $-85.00 $-65.00
- @end smallexample
- @item --budget
- Useful for displaying how close your postings meet your budget.
- @option{--add-budget} also shows unbudgeted postings, while
- @option{--unbudgeted} shows only those. @option{--forecast @var{VEXPR}}
- is a related option that projects your budget into the future, showing
- how it will affect future balances. @xref{Budgeting and Forecasting}.
- @item --limit @var{EXPR}
- @itemx -l @var{EXPR}
- Limit which postings take part in the calculations of a report.
- @item --amount @var{EXPR}
- @itemx -t @var{EXPR}
- Change the value expression used to calculate the ``value'' column in
- the @command{register} report, the amount used to calculate account
- totals in the @command{balance} report, and the values printed in the
- @command{equity} report. @xref{Value Expressions}.
- @item --total @var{VEXPR}
- @itemx -T @var{VEXPR}
- Set the value expression used for the ``totals'' column in the
- @command{register} and @command{balance} reports.
- @end ftable
- @c @node Search Terms, Output Customization, Report Filtering, Detailed Options Description
- @c @subsection Search Terms
- @c Valid Ledger invocations look like:
- @c @smallexample
- @c ledger [OPTIONS] <COMMAND> <SEARCH-TERMS>
- @c @end smallexample
- @c Where @code{COMMAND} is any command verb (@pxref{Reporting
- @c Commands}), @code{OPTIONS} can occur anywhere, and
- @c @code{SEARCH-TERM} is one or more of the following:
- @c @smallexample
- @c word search for any account containing 'word'
- @c TERM and TERM boolean AND between terms
- @c TERM or TERM boolean OR between terms
- @c not TERM invert the meaning of the term
- @c payee word search for any payee containing 'word'
- @c @@word shorthand for 'payee word'
- @c desc word alternate for 'payee word'
- @c note word search for any note containing 'word'
- @c &word shorthand for 'note word'
- @c tag word search for any metadata tag containing 'word'
- @c tag word=value search for any metadata tag containing 'word'
- @c whose value contains 'value'
- @c %word shorthand for 'tag word'
- @c %word=value shorthand for 'tag word=value'
- @c meta word alternate for 'tag word'
- @c meta word=value alternate for 'tag word=value'
- @c expr 'EXPR' apply the given value expression as a predicate
- @c '=EXPR' shorthand for 'expr EXPR'
- @c \( TERMS \) group terms; useful if using and/or/not
- @c @end smallexample
- @c So, to list all transaction that charged to ``food'' but not
- @c ``dining'' for any payee other than ``chang'' the following three
- @c commands would be equivalent:
- @c @smallexample
- @c ledger reg food not dining @@chang
- @c ledger reg food and not dining and not payee chang
- @c ledger reg food not dining expr 'payee =~ /chang/'
- @c @end smallexample
- @node Output customization, Commodity reporting, Report filtering, Detailed Option Description
- @subsection Output customization
- These options affect only the output, but not which postings are
- used to create it:
- @ftable @option
- @item --collapse
- @itemx -n
- Cause transactions in a @command{register} report with multiple
- postings to be collapsed into a single, subtotaled transaction.
- @item --subtotal
- @itemx -s
- Cause all transactions in a @command{register} report to be collapsed
- into a single, subtotaled transaction.
- @item --by-payee
- @itemx -P
- Report subtotals by payee.
- @item --empty
- @itemx -E
- Include even empty accounts in the @command{balance} report.
- @item --weekly
- @itemx -W
- Report posting totals by the week. The week begins on whichever day of
- the week begins the month containing that posting. To set a specific
- begin date, use a period string, such as @samp{weekly from DATE}.
- @item --monthly
- @itemx -M
- Report posting totals by month.
- @item --yearly
- @itemx -Y
- Report posting totals by year. For more complex periods, use
- @option{--period}.
- @c TODO end this sentence
- @item --period @var{PERIOD_EXPRESSION}
- Option described above.
- @item --dow
- Report posting totals for each day of the week. This is an easy way
- to see if weekend spending is more than on weekdays.
- @item --sort @var{VEXPR}
- @itemx -S @var{VEXPR}
- Sort a report by comparing the values determined using the value
- expression @var{VEXPR}. For example, using @samp{-S "-abs(total)"} in
- the @command{balance} report will sort account balances from greatest to
- least, using the absolute value of the total. For more on how to use
- value expressions, see @ref{Value Expressions}.
- @item --pivot @var{TAG}
- Produce a pivot table around the @var{TAG} provided. This requires
- meta data using valued tags.
- @item --wide
- @itemx -w
- Cause the default @command{register} report to assume 132 columns
- instead of 80.
- @item --head @var{INT}
- Cause only the first @var{INT} transactions to be printed. This is
- different from using the command-line utility @file{head}, which would
- limit to the first @var{INT} postings. @option{--tail @var{INT}} outputs
- only the last @var{INT} transactions. Both options may be used
- simultaneously. If a negative amount is given, it will invert the
- meaning of the flag (instead of the first five transactions being
- printed, for example, it would print all but the first five).
- @item --pager @var{FILE}
- Tell Ledger to pass its output to the given @var{FILE} pager program;
- very useful when the output is especially long. This behavior can be
- made the default by setting the @env{LEDGER_PAGER} environment variable.
- @item --no-pager
- Tell Ledger to @emph{not} pass its output to a pager program; useful
- when a pager is set by default.
- @item --average
- @itemx -A
- Report the average posting value.
- @item --deviation
- @itemx -D
- Report each posting's deviation from the average. It is only meaningful
- in the @command{register} and @command{prices} reports.
- @item --percent
- @itemx -%
- Show account subtotals in the @command{balance} report as percentages of
- the parent account.
- @c @option{--totals} include running total information in the
- @c @command{xml} report.
- @item --amount-data
- @itemx -j
- Change the @command{register} report so that it prints nothing but the
- date and the value column, and the latter without commodities. This is
- only meaningful if the report uses a single commodity. This data can
- then be fed to other programs, which could plot the date, analyze it,
- etc.
- @item --total-data
- @itemx -J
- Change the @command{register} report so that it prints nothing but the
- date and total columns, without commodities.
- @item --display @var{EXPR}
- @itemx -d @var{EXPR}
- Limit which postings or accounts are actually displayed in a report.
- They might still be calculated, and be part of the running total of a
- register report, for example, but they will not be displayed. This is
- useful for seeing last month's checking postings, against a running
- balance which includes all posting values:
- @smallexample @c command:validate
- $ ledger -d "d>=[last month]" reg checking
- @end smallexample
- The output from this command is very different from the following,
- whose running total includes only postings from the last month
- onward:
- @smallexample @c command:validate
- $ ledger -p "last month" reg checking
- @end smallexample
- Which is more useful depends on what you're looking to know: the total
- amount for the reporting range (using @option{--period
- @var{PERIOD_EXPRESSION} (-p)}), or simply a display restricted to the
- reporting range (using @option{--display @var{EXPR} (-d)}).
- @item --date-format @var{DATE_FORMAT}
- @itemx -y @var{DATE_FORMAT}
- Change the basic date format used by reports. The default uses a date
- like @samp{2004/08/01}, which represents the default date format of
- @code{%Y/%m/%d}. To change the way dates are printed in general, the
- easiest way is to put @option{--date-format @var{DATE_FORMAT}} in the
- Ledger initialization file @file{~/.ledgerrc} (or the file referred to
- by @env{LEDGER_INIT}).
- @item --format @var{FORMAT_STRING}
- @itemx -F @var{FORMAT_STRING}
- Set the reporting format for whatever report ledger is about to make.
- @xref{Format Strings}. There are also specific format commands for
- each report type:
- @item --balance-format @var{FORMAT_STRING}
- Define the output format for the @command{balance} report. The default
- (defined in @file{report.h} is:
- @smallexample
- "%(ansify_if(
- justify(scrub(display_total), 20,
- 20 + int(prepend_width), true, color),
- bold if should_bold))
- %(!options.flat ? depth_spacer : \"\")
- %-(ansify_if(
- ansify_if(partial_account(options.flat), blue if color),
- bold if should_bold))\n%/
- %$1\n%/
- %(prepend_width ? \" \" * int(prepend_width) : \"\")
- --------------------\n"
- @end smallexample
- @item --cleared-format @var{FORMAT_STRING}
- Define the format for the cleared report. The default is:
- @smallexample
- "%(justify(scrub(get_at(display_total, 0)), 16, 16 + int(prepend_width),
- true, color)) %(justify(scrub(get_at(display_total, 1)), 18,
- 36 + int(prepend_width), true, color))
- %(latest_cleared ? format_date(latest_cleared) : \" \")
- %(!options.flat ? depth_spacer : \"\")
- %-(ansify_if(partial_account(options.flat), blue if color))\n%/
- %$1 %$2 %$3\n%/
- %(prepend_width ? \" \" * int(prepend_width) : \"\")
- ---------------- ---------------- ---------\n"
- @end smallexample
- @item --register-format @var{FORMAT_STRING}
- Define the output format for the @command{register} report. The default
- (defined in @file{report.h} is:
- @smallexample
- "%(ansify_if(
- ansify_if(justify(format_date(date), int(date_width)),
- green if color and date > today),
- bold if should_bold))
- %(ansify_if(
- ansify_if(justify(truncated(payee, int(payee_width)), int(payee_width)),
- bold if color and !cleared and actual),
- bold if should_bold))
- %(ansify_if(
- ansify_if(justify(truncated(display_account, int(account_width),
- int(abbrev_len)), int(account_width)),
- blue if color),
- bold if should_bold))
- %(ansify_if(
- justify(scrub(display_amount), int(amount_width),
- 3 + int(meta_width) + int(date_width) + int(payee_width)
- + int(account_width) + int(amount_width) + int(prepend_width),
- true, color),
- bold if should_bold))
- %(ansify_if(
- justify(scrub(display_total), int(total_width),
- 4 + int(meta_width) + int(date_width) + int(payee_width)
- + int(account_width) + int(amount_width) + int(total_width)
- + int(prepend_width), true, color),
- bold if should_bold))\n%/
- %(justify(\" \", int(date_width)))
- %(ansify_if(
- justify(truncated(has_tag(\"Payee\") ? payee : \" \",
- int(payee_width)), int(payee_width)),
- bold if should_bold))
- %$3 %$4 %$5\n"
- @end smallexample
- @item --csv-format @var{FORMAT_STRING}
- Set the format for @command{csv} reports. The default is:
- @smallexample
- "%(quoted(date)),
- %(quoted(code)),
- %(quoted(payee)),
- %(quoted(display_account)),
- %(quoted(commodity(scrub(display_amount)))),
- %(quoted(quantity(scrub(display_amount)))),
- %(quoted(cleared ? \"*\" : (pending ? \"!\" : \"\"))),
- %(quoted(join(note | xact.note)))\n"
- @end smallexample
- @item --plot-amount-format @var{FORMAT_STRING}
- Set the format for amount plots, using the @option{--amount-data (-j)}
- option. The default is:
- @smallexample
- "%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_amount)))\n"
- @end smallexample
- @item --plot-total-format @var{FORMAT_STRING}
- Set the format for total plots, using the @option{--total-data (-J)}
- option. The default is:
- @smallexample
- "%(format_date(date, \"%Y-%m-%d\")) %(quantity(scrub(display_total)))\n"
- @end smallexample
- @item --pricedb-format @var{FORMAT_STRING}
- Set the format expected for the historical price file. The default is:
- @smallexample
- "P %(datetime) %(display_account) %(scrub(display_amount))\n"
- @end smallexample
- @item --prices-format @var{FORMAT_STRING}
- Set the format for the @command{prices} report. The default is:
- @smallexample
- "%(date) %-8(display_account) %(justify(scrub(display_amount), 12,
- 2 + 9 + 8 + 12, true, color))\n"
- @end smallexample
- @end ftable
- @node Commodity reporting, Environment variables, Output customization, Detailed Option Description
- @subsection Commodity reporting
- These options affect how commodity values are displayed:
- @ftable @option
- @item --price-db @var{FILE}
- Set the file that is used for recording downloaded commodity prices.
- It is always read on startup, to determine historical prices. Other
- settings can be placed in this file manually, to prevent downloading
- quotes for a specific commodity, for example. This is done by adding a
- line like the following:
- @smallexample @c input:validate
- ; Don't download quotes for the dollar, or timelog values
- N $
- N h
- @end smallexample
- @noindent
- Note: Ledger NEVER writes output to files. You are responsible for
- updating the price-db file. The best way is to have your price
- download script maintain this file.
- The format of the file can be changed by telling ledger to use the
- @option{--pricedb-format @var{FORMAT_STRING}} you define.
- @item --price-exp @var{INT}
- @itemx --leeway @var{INT}
- @itemx -Z @var{INT}
- Set the expected freshness of price quotes, in @var{INT} minutes. That
- is, if the last known quote for any commodity is older than this value,
- and if @option{--download} is being used, then the Internet will be
- consulted again for a newer price. Otherwise, the old price is still
- considered to be fresh enough.
- @item --download
- @itemx -Q
- Cause quotes to be automagically downloaded, as needed, by running
- a script named @file{getquote} and expecting that script to return
- a value understood by ledger. A sample implementation of
- a @file{getquote} script, implemented in Perl, is provided in the
- distribution. Downloaded quote price are then appended to the price
- database, usually specified using the environment variable
- @env{LEDGER_PRICE_DB}.
- @end ftable
- There are several different ways that ledger can report the totals it
- displays. The most flexible way to adjust them is by using value
- expressions, and the @option{--amount @var{EXPR} (-t)} and
- @option{--total @var{VEXPR} (-T)} options. However, there are also
- several ``default'' reports, which will satisfy most users' basic
- reporting needs:
- @ftable @option
- @item --quantity
- @itemx -O
- Report commodity totals (this is the default).
- @item --basis
- @itemx -B
- Report the cost basis for all postings.
- @item --market
- @itemx -V
- Use the last known value for commodities to calculate final values.
- @item --gain
- @itemx -G
- Report the net gain/loss for all commodities in the report that have
- a price history.
- @end ftable
- Often you will be more interested in the value of your entire holdings,
- in your preferred currency. It might be nice to know you hold 10,000
- shares of PENNY, but you are more interested in whether or not that is
- worth $1000.00 or $10,000.00. However, the current day value of a
- commodity can mean different things to different people, depending on
- the accounts involved, the commodities, the nature of the transactions,
- etc.
- @findex --now @var{DATE}
- @findex --market
- @findex --exchange @var{COMMODITY}
- When you specify @option{--market (-V)}, or @option{--exchange
- @var{COMMODITY} (-X)}, you are requesting that some or all of the
- commodities be valuated as of today (or whatever @option{--now
- @var{DATE}} is set to). But what does such a valuation mean? This
- meaning is governed by the presence of a @var{VALUE} meta-data property,
- whose content is an expression used to compute that value.
- If no @var{VALUE} property is specified, each posting is assumed to have
- a default, as if you'd specified a global, automated transaction as
- follows:
- @smallexample @c input:validate
- = expr true
- ; VALUE:: market(amount, date, exchange)
- @end smallexample
- This definition emulates the present day behavior of @option{--market
- (-V)} and @option{--exchange @var{COMMODITY} (-X)} (in the case of
- @samp{-X}, the requested commodity is passed via the string
- @samp{exchange} above).
- @cindex Euro conversion
- One thing many people have wanted to do is to fixate the valuation of
- old European currencies in terms of the Euro after a certain date:
- @smallexample @c input:validate
- = expr commodity == "DM"
- ; VALUE:: date < [Jun 2008] ? market(amount, date, exchange) : 1.44 EUR
- @end smallexample
- This says: If @option{--now @var{DATE}} is some old date, use market
- prices as they were at that time; but if @option{--now @var{DATE}} is
- past June 2008, use a fixed price for converting Deutsch Mark to Euro.
- Or how about never re-valuating commodities used in Expenses, since
- they cannot have a different future value:
- @smallexample @c input:validate
- = /^Expenses:/
- ; VALUE:: market(amount, post.date, exchange)
- @end smallexample
- This says the future valuation is the same as the valuation at the time
- of posting. @code{post.date} equals the posting's date, while just 'date' is
- the value of @option{--now @var{DATE}} (defaults to today).
- Or how about valuating miles based on a reimbursement rate during a
- specific time period:
- @smallexample @c input:validate
- = expr commodity == "miles" and date >= [2007] and date < [2008]
- ; VALUE:: market($1.05, date, exchange)
- @end smallexample
- In this case, miles driven in 2007 will always be valuated at $1.05
- each. If you use @samp{-X EUR} to expressly request all amounts in
- Euro, Ledger shall convert $1.05 to Euro by whatever means are
- appropriate for dollars.
- Note that you can have a valuation expression specific to a particular
- posting or transaction, by overriding these general defaults using
- specific meta-data:
- @smallexample @c input:validate
- 2010-12-26 Example
- Expenses:Food $20
- ; Just to be silly, always valuate *these* $20 as 30 DM, no matter what
- ; the user asks for with -V or -X
- ; VALUE:: 30 DM
- Assets:Cash
- @end smallexample
- This example demonstrates that your value expression should be as
- symbolic as possible, using terms like 'amount' and 'date', rather than
- specific amounts and dates. Also, you should pass the amount along to
- the function 'market' so it can be further revalued if the user has
- asked for a specific currency.
- Or, if it better suits your accounting, you can be less symbolic,
- which allows you to report most everything in EUR if you use @samp{-X
- EUR}, except for certain accounts or postings which should always be
- valuated in another currency. For example:
- @c TODO is this example missing the actual line to get the effect?
- @c it looks like it only contains a match, but no effect
- @smallexample @c input:validate
- = /^Assets:Brokerage:CAD$/
- ; Always report the value of commodities in this account in
- ; terms of present day dollars, despite what was asked for
- ; on the command-line VALUE:: market(amount, date, @samp{$})
- @end smallexample
- @cindex FIFO/LIFO
- @cindex LIFO/FIFO
- @findex --lots
- @findex --lot-prices
- @findex --exchange @var{COMMODITY}
- @findex --historical
- @findex --basis
- @findex --price
- Ledger presently has no way of handling such things as FIFO and LIFO.
- If you specify an unadorned commodity name, like AAPL, it will balance
- against itself. If @option{--lots} are not being displayed, then it
- will appear to balance against any lot of AAPL.
- @cindex adorned commodity
- @findex --lot-prices
- If you specify an adorned commodity, like AAPL @{$10.00@}, it will also
- balance against itself, and against any AAPL if @option{--lots} is not
- specified. But if you do specify @option{--lot-prices}, for example,
- then it will balance against that specific price for AAPL.
- Normally when you use @option{--exchange @var{COMMODITY} (-X)} to
- request that amounts be reported in a specific commodity, Ledger uses
- these values:
- @itemize
- @item Register Report
- For the @command{register} report, use the value of that commodity on
- the date of the posting being reported, with a @samp{<Revalued>} posting
- added at the end if today's value is different from the value of the
- last posting.
- @item Balance Report
- For the @command{balance} report, use the value of that commodity as of
- today.
- @end itemize
- You can now specify @option{--historical (-H)} to ask that all
- valuations for any amount be done relative to the date that amount was
- encountered.
- You can also now use @option{--exchange @var{COMMODITY} (-X)} (and
- @option{--historical (-H)}) in conjunction with @option{--basis (-B)}
- and @option{--price (-I)}, to see valuation reports of just your basis
- costs or lot prices.
- Finally, sometimes, you may seek to only report one (or some subset) of
- the commodities in terms of another commodity. In this situation, you
- can use the syntax @option{--exchange @var{COMMODITY1}:@var{COMMODITY2}}
- to request that ledger always display @var{COMMODITY1} in terms of
- @var{COMMODITY2}, but you want no other commodities to be automatically
- displayed in terms of @var{COMMODITY2} without additional
- @option{--exchange} options. For example, if you wanted to report EUR
- and BTC in terms of USD, but report all other commodities without
- conversion to USD, you could use: @option{--exchange EUR:USD --exchange
- BTC:USD}.
- @node Environment variables, , Commodity reporting, Detailed Option Description
- @subsection Environment variables
- Every option to ledger may be set using an environment variable if the
- option has a long name. For example setting the environment variable
- @samp{@env{LEDGER_DATE_FORMAT}="%d.%m.%Y"} will have the same effect as specifying
- @samp{@option{--date-format} '%d.%m.%Y'} on the command-line. Options on the
- command-line always take precedence over environment variable settings, however.
- Note that you may also permanently specify option values by placing
- option settings in the file @file{~/.ledgerrc} one option per line, for example:
- @smallexample @c input:validate
- --pager /bin/cat
- @end smallexample
- @node Period Expressions, , Detailed Option Description, Command-Line Syntax
- @section Period Expressions
- @c TODO use @var below
- A period expression indicates a span of time, or a reporting interval,
- or both. The full syntax is:
- @smallexample
- [INTERVAL] [BEGIN] [END]
- @end smallexample
- The optional @var{INTERVAL} part may be any one of:
- @smallexample
- every day
- every week
- every month
- every quarter
- every year
- every N days # N is any integer
- every N weeks
- every N months
- every N quarters
- every N years
- daily
- weekly
- biweekly
- monthly
- bimonthly
- quarterly
- yearly
- @end smallexample
- After the interval, a begin time, end time, both or neither may be
- specified. As for the begin time, it can be either of:
- @smallexample
- from <SPEC>
- since <SPEC>
- @end smallexample
- The end time can be either of:
- @smallexample
- to <SPEC>
- until <SPEC>
- @end smallexample
- Where @var{SPEC} can be any of:
- @smallexample
- 2004
- 2004/10
- 2004/10/1
- 10/1
- october
- oct
- this week # or day, month, quarter, year
- next week
- last week
- @end smallexample
- The beginning and ending can be given at the same time, if it spans a
- single period. In that case, just use @var{SPEC} by itself. In that
- case, the period @samp{oct}, for example, will cover all the days in
- October. The possible forms are:
- @smallexample
- <SPEC>
- in <SPEC>
- @end smallexample
- Here are a few examples of period expressions:
- @smallexample
- monthly
- monthly in 2004
- weekly from oct
- weekly from last month
- from sep to oct
- from 10/1 to 10/5
- monthly until 2005
- from apr
- until nov
- last oct
- weekly last august
- @end smallexample
- @node Budgeting and Forecasting, Time Keeping, Command-Line Syntax, Top
- @chapter Budgeting and Forecasting
- @menu
- * Budgeting::
- * Forecasting::
- @end menu
- @node Budgeting, Forecasting, Budgeting and Forecasting, Budgeting and Forecasting
- @section Budgeting
- @findex --budget
- @findex --add-budget
- @findex --unbudgeted
- @findex --monthly
- Keeping a budget allows you to pay closer attention to your income and
- expenses, by reporting how far your actual financial activity is from
- your expectations.
- To start keeping a budget, put some periodic transactions
- (@pxref{Periodic Transactions}) at the top of your ledger file. A
- periodic transaction is almost identical to a regular transaction, except
- that it begins with a tilde and has a period expression in place of a
- payee. For example:
- @smallexample @c input:validate
- ~ Monthly
- Expenses:Rent $500.00
- Expenses:Food $450.00
- Expenses:Auto:Gas $120.00
- Expenses:Insurance $150.00
- Expenses:Phone $125.00
- Expenses:Utilities $100.00
- Expenses:Movies $50.00
- Expenses $200.00 ; all other expenses
- Assets
- ~ Yearly
- Expenses:Auto:Repair $500.00
- Assets
- @end smallexample
- These two periodic transactions give the usual monthly expenses, as well
- as one typical yearly expense. For help on finding out what your
- average monthly expenses are for any category, use a command like:
- @smallexample @c command:validate
- $ ledger -p "this year" --monthly --average balance ^expenses
- @end smallexample
- The reported totals are the current year's average for each account.
- Once these periodic transactions are defined, creating a budget report is
- as easy as adding @option{--budget} to the command-line. For example,
- a typical monthly expense report would be:
- @smallexample @c command:validate
- $ ledger --monthly register ^expenses
- @end smallexample
- To see the same report balanced against your budget, use:
- @smallexample @c command:validate
- $ ledger --budget --monthly register ^expenses
- @end smallexample
- A budget report includes only those accounts that appear in the budget.
- To see all expenses balanced against the budget, use
- @option{--add-budget}. You can even see only the unbudgeted expenses
- using @option{--unbudgeted}:
- @smallexample @c command:validate
- $ ledger --unbudgeted --monthly register ^expenses
- @end smallexample
- You can also use these flags with the @command{balance} command.
- @node Forecasting, , Budgeting, Budgeting and Forecasting
- @section Forecasting
- @findex --forecast @var{VEXPR}
- Sometimes it's useful to know what your finances will look like in the
- future, such as determining when an account will reach zero. Ledger
- makes this easy to do, using the same periodic transactions as are used
- for budgeting. An example forecast report can be generated with:
- @smallexample @c command:validate
- $ ledger --file drewr3.dat --forecast "T>@{\$-500.00@}" register ^assets ^liabilities
- @end smallexample
- This report continues outputting postings until the running total
- is greater than $-500.00. A final posting is always shown, to
- inform you what the total afterwards would be.
- Forecasting can also be used with the @command{balance} report,
- but by date only, and not against the running total:
- @smallexample @c command:validate
- $ ledger --forecast "d<[2010]" bal ^assets ^liabilities
- @end smallexample
- @node Time Keeping, Value Expressions, Budgeting and Forecasting, Top
- @chapter Time Keeping
- @findex --day-break
- @anchor{timelog}
- Ledger directly supports ``timelog'' entries, which have this form:
- @smallexample @c input:validate
- i 2013/03/28 22:13:00 ACCOUNT[ PAYEE]
- o 2013/03/29 03:39:00
- @end smallexample
- This records a check-in to the given ACCOUNT, and a check-out. You can
- be checked-in to multiple accounts at a time, if you wish, and they can
- span multiple days (use @option{--day-break} to break them up in the
- report). The number of seconds between check-in and check-out is
- accumulated as time to that ACCOUNT. If the checkout uses a capital
- @samp{O}, the transaction is marked ``cleared''. You can use an
- optional PAYEE for whatever meaning you like.
- Now, there are a few ways to generate this information. You can use
- the @file{timeclock.el} package, which is part of Emacs. Or you can
- write a simple script in whichever language you prefer to emit similar
- information. Or you can use Org mode's time-clocking abilities and
- the @file{org2tc} script developed by John Wiegley.
- These timelog entries can appear in a separate file, or directly in
- your main ledger file. The initial @samp{i} and @samp{o} characters
- count as Ledger ``directives'', and are accepted anywhere that
- ordinary transactions are valid.
- @node Value Expressions, Format Strings, Time Keeping, Top
- @chapter Value Expressions
- @findex --limit @var{EXPR}
- @findex --display @var{EXPR}
- Ledger uses value expressions to make calculations for many different
- purposes:
- @enumerate
- @item
- The values displayed in reports.
- @item
- For predicates (where truth is anything non-zero), to determine which
- postings are calculated (option @option{--limit @var{EXPR} (-l)}) or
- displayed (option @option{--display @var{EXPR} (-d)}).
- @item
- For sorting criteria, to yield the sort key.
- @item
- In the matching criteria used by automated postings.
- @end enumerate
- Value expressions support most simple math and logic operators, in
- addition to a set of functions and variables.
- @c A function's argument is whatever follows it. The following is
- @c a display predicate that I use with the @command{balance} command:
- @c @smallexample
- @c ledger -d '/^Liabilities/?T<0:UT>100' balance
- @c @end smallexample
- @c The effect is that account totals are displayed only if: 1) A
- @c Liabilities account has a total less than zero; or 2) the absolute
- @c value of the account's total exceeds 100 units of whatever commodity
- @c contains. If it contains multiple commodities, only one of them must
- @c exceed 100 units.
- Display predicates are also very handy with register reports, to
- constrain which transactions are printed. For example, the following
- command shows only transactions from the beginning of the current month,
- while still calculating the running balance based on all transactions:
- @smallexample @c command:validate
- $ ledger -d "d>[this month]" register checking
- @end smallexample
- The advantage of this command's complexity is that it prints the
- running total in terms of all transactions in the register. The
- following, simpler command is similar, but totals only the displayed
- postings:
- @smallexample @c command:validate
- $ ledger -b "this month" register checking
- @end smallexample
- @menu
- * Variables::
- * Functions::
- * Operators::
- * Complex expressions::
- @end menu
- @node Variables, Functions, Value Expressions, Value Expressions
- @section Variables
- @findex --amount @var{EXPR}
- @findex --total @var{VEXPR}
- Below are the one letter variables available in any value expression.
- For the @command{register} and @command{print} commands, these variables
- relate to individual postings, and sometimes the account affected by a
- posting. For the @command{balance} command, these variables relate to
- accounts, often with a subtle difference in meaning. The use of each
- variable for both is specified.
- @table @code
- @item t
- This maps to whatever the user specified with @option{--amount
- @var{EXPR} (-t)}. In a @command{register} report, @option{--amount
- @var{EXPR} (-t)} changes the value column; in a @command{balance}
- report, it has no meaning by default. If @option{--amount @var{EXPR}
- (-t)} was not specified, the current report style's value expression is
- used.
- @item T
- This maps to whatever the user specified with @option{--total
- @var{VEXPR} (-T)}. In a register report, @option{--total @var{VEXPR}
- (-T)} changes the totals column; in a balance report, this is the value
- given for each account. If @option{--total @var{VEXPR} (-T)} was not
- specified, the current report style's value expression is used.
- @item m
- This is always the present moment/date.
- @end table
- @menu
- * Posting/account details::
- * Calculated totals::
- @end menu
- @node Posting/account details, Calculated totals, Variables, Variables
- @subsection Posting/account details
- @table @code
- @item d
- A posting's date, as the number of seconds past the epoch. This
- is always ``today'' for an account.
- @item a
- The posting's amount; the balance of an account, without
- considering children.
- @item b
- The cost of a posting; the cost of an account, without its
- children.
- @item v
- The market value of a posting or an account, without its children.
- @item g
- The net gain (market value minus cost basis), for a posting or an
- account, without its children. It is the same as @samp{v-b}.
- @item l
- The depth (``level'') of an account. If an account has one parent,
- its depth is one.
- @item n
- The index of a posting, or the count of postings affecting an
- account.
- @item X
- @samp{1} if a posting's transaction has been cleared, @samp{0} otherwise.
- @item R
- @samp{1} if a posting is not virtual, @samp{0} otherwise.
- @item Z
- @samp{1} if a posting is not automated, @samp{0} otherwise.
- @end table
- @node Calculated totals, , Posting/account details, Variables
- @subsection Calculated totals
- @table @code
- @item O
- The total of all postings seen so far, or the total of an account
- and all its children.
- @item N
- The total count of postings affecting an account and all its
- children.
- @end table
- @node Functions, Operators, Variables, Value Expressions
- @section Functions
- The available one letter functions are:
- @table @code
- @item -
- Negates the argument.
- @item U
- The absolute (unsigned) value of the argument.
- @item S
- Strips the commodity from the argument.
- @item P
- The present market value of the argument. The syntax @samp{P(x,d)} is
- supported, which yields the market value at time @samp{d}. If no date
- is given, then the current moment is used.
- @end table
- @node Operators, Complex expressions, Functions, Value Expressions
- @section Operators
- The binary and ternary operators, in order of precedence, are:
- @enumerate
- @item @code{* /}
- @item @code{+ -}
- @item @code{! < > =}
- @item @code{& | ?:}
- @end enumerate
- @menu
- * Unary Operators::
- * Binary Operators::
- @end menu
- @node Unary Operators, Binary Operators, Operators, Operators
- @subsection Unary Operators
- @code{not}
- @code{neg}
- @node Binary Operators, , Unary Operators, Operators
- @subsection Binary Operators
- @code{==}
- @code{<}
- @code{<=}
- @code{>}
- @code{>=}
- @code{and}
- @code{or}
- @code{+}
- @code{-}
- @code{*}
- @code{/}
- @code{QUERY}
- @code{COLON}
- @code{CONS}
- @code{SEQ}
- @code{DEFINE}
- @code{LOOKUP}
- @code{LAMBDA}
- @code{CALL}
- @code{MATCH}
- @node Complex expressions, , Operators, Value Expressions
- @section Complex expressions
- More complicated expressions are possible using:
- @table @code
- @item "amount == COMMODITY AMOUNT"
- The amount can be any kind of amount supported by ledger,
- with or without a commodity. Use this for decimal values.
- @item /REGEX/
- @itemx account =~ /REGEX/
- A regular expression that matches against an account's full name. If
- a posting, this will match against the account affected by the
- posting.
- @item @@/REGEX/
- @itemx expr payee =~ /REGEX/
- A regular expression that matches against a transaction's payee name.
- @item %/REGEX/
- @itemx tag(REGEX)
- A regular expression that matches against a transaction's tags.
- @item expr date =~ /REGEX/
- Useful for specifying a date in plain terms. For example, you could say
- @samp{expr date =~ /2014/}.
- @item expr comment =~ /REGEX/
- A regular expression that matches against a posting's comment
- field. This searches only a posting's field, not the transaction's note
- or comment field. For example, @code{ledger reg "expr" "comment =~
- /landline/"} will match:
- @smallexample @c input:validate
- 2014/1/29 Phone bill
- Assets:Checking $50.00
- Expenses:Phone $-50.00 ; landline bill
- @end smallexample
- but will not match:
- @smallexample @c input:validate
- 2014/1/29 Phone bill ; landline bill
- ; landline bill
- Assets:Checking $50.00
- Expenses:Phone $-50.00
- @end smallexample
- To match the latter, use @samp{ledger reg "expr" "note =~ /landline/"}
- instead.
- @item expr note =~ /REGEX/
- A regular expression that matches against a transaction's note field.
- This searches all comments in the transaction, including comments on
- individual postings. Thus, @samp{ledger reg "expr" "note =~ /landline/"}
- will match both all the three examples below:
- @smallexample @c input:validate
- 2014/1/29 Phone bill
- Assets:Checking $50.00
- Expenses:Phone $-50.00 ; landline bill
- @end smallexample
- @smallexample @c input:validate
- 2014/1/29 Phone bill ; landline bill
- Assets:Checking $50.00
- Expenses:Phone $-50.00
- @end smallexample
- @smallexample @c input:validate
- 2014/1/29 Phone bill
- ; landline bill
- Assets:Checking $50.00
- Expenses:Phone $-50.00
- @end smallexample
- @item (EXPR)
- A sub-expression is nested in parenthesis. This can be useful passing
- more complicated arguments to functions, or for overriding the natural
- precedence order of operators.
- @item expr base =~ /REGEX/
- A regular expression that matches against an account's base name. If
- a posting, this will match against the account affected by the
- posting.
- @item expr code =~ /REGEX/
- A regular expression that matches against the transaction code (the
- text that occurs between parentheses before the payee).
- @end table
- The @command{query} command can be used to see how Ledger interprets
- your query. This can be useful if you are not getting the results you
- expect (@pxref{Pre-Commands}).
- @menu
- * Miscellaneous::
- @end menu
- @node Miscellaneous, , Complex expressions, Complex expressions
- @subsection Miscellaneous
- The following Ledger journal data (saved as @file{expr.dat}) is used to explain the behaviour of the
- functions and variables below:
- @anchor{expr.dat}
- @smallexample @c input:3406FC1
- 2015/01/16 * (C0D3) Payee
- Assets:Cash ¤ -123,45
- ; Payee: PiggyBank
- Expenses:Office Supplies
- @end smallexample
- @defun abs value
- @defunx U value
- Return the absolute value of the given @var{value}, e.g. @var{amount}.
- @smallexample @c command:3406FC1
- $ ledger -f expr.dat --format "%(account) %(abs(amount))\n" reg assets
- @end smallexample
- @smallexample @c output:3406FC1
- Assets:Cash ¤ 123,45
- @end smallexample
- @end defun
- @defun amount_expr
- Return the calculated amount of the posting according to the @option{--amount}
- option.
- @end defun
- @defun ansify_if value color bool
- Render the given @var{expression} as a string, applying the proper ANSI escape
- codes to display it in the given @var{color} if @var{bool} is true. It
- typically checks the value of the option @option{--color}. Since ANSI escape
- codes include non-printable character sequences, such as escape @kbd{^[}
- the following example may not appear as the final result on the command-line.
- @smallexample @c command:4D836EE,with_input:3406FC1
- $ ledger -f expr.dat --format "%(ansify_if(account, blue, options.color))\n" reg
- @end smallexample
- @smallexample @c output:4D836EE
- [34mAssets:Cash[0m
- [34mExpenses:Office Supplies[0m
- @end smallexample
- @end defun
- @defun ceiling value
- Return the next integer of @var{value} toward @math{+}infinity.
- @smallexample @c command:FF9C18C,with_input:3406FC1
- $ ledger -f expr.dat --format "%(account) %(ceiling(amount))\n" reg
- @end smallexample
- @smallexample @c output:FF9C18C
- Assets:Cash ¤ -123,00
- Expenses:Office Supplies ¤ 124,00
- @end smallexample
- @end defun
- @defvar code
- Return the transaction code, the string between the parenthesis after the date.
- @smallexample @c command:46FCFD3,with_input:3406FC1
- $ ledger -f expr.dat --format "%(account) %(code)\n" reg assets
- @end smallexample
- @smallexample @c output:46FCFD3
- Assets:Cash C0D3
- @end smallexample
- @end defvar
- @defvar commodity
- Return the commodity of the posting amount.
- @end defvar
- @smallexample @c command:2CD27D7,with_input:3406FC1
- $ ledger -f expr.dat --format "%(account) %(commodity)\n" reg
- @end smallexample
- @smallexample @c output:2CD27D7
- Assets:Cash ¤
- Expenses:Office Supplies ¤
- @end smallexample
- @defvar date
- Return the date of the posting.
- @end defvar
- @smallexample @c command:67EBA45,with_input:3406FC1
- $ ledger -f expr.dat --format "%(date) %(account)\n" reg assets
- @end smallexample
- @smallexample @c output:67EBA45
- 2015/01/16 Assets:Cash
- @end smallexample
- @defvar display_amount
- @defvarx t
- @value{FIXME:UNDOCUMENTED}
- @end defvar
- @c FIXME
- @defvar display_total
- @defvarx T
- @value{FIXME:UNDOCUMENTED}
- @end defvar
- @defun floor value
- Return the next integer of @var{value} toward @math{-}infinity.
- @smallexample @c command:4FDC7C5,with_input:3406FC1
- $ ledger -f expr.dat --format "%(account) %(floor(amount))\n" reg
- @end smallexample
- @smallexample @c output:4FDC7C5
- Assets:Cash ¤ -124,00
- Expenses:Office Supplies ¤ 123,00
- @end smallexample
- @end defun
- @defun format string
- Evaluate @var{string} as format just like the @option{--format} option.
- @end defun
- @defun format_date date format
- Return the @var{date} as a string using @var{format}. See
- @code{strftime (3)} for format string details.
- @smallexample @c command:9605B13,with_input:3406FC1
- $ ledger -f expr.dat --format "%(format_date(date, '%A, %B %d. %Y'))\n" reg assets
- @end smallexample
- @smallexample @c output:9605B13
- Friday, January 16. 2015
- @end smallexample
- @end defun
- @defun format_datetime datetime format
- Return the @var{datetime} as a string using @var{format}. Refer to
- @code{strftime (3)} for format string details.
- @end defun
- @defun get_at sequence index
- Return the value in @var{sequence} at @var{index}. The first element is @var{index} 0.
- @value{InternalUseOnly}
- @end defun
- @defun is_seq value
- Return true if @var{value} is a sequence. @value{InternalUseOnly}
- @end defun
- @defun join value
- Replace all newlines in @var{value} with @code{\n}.
- @end defun
- @defun justify value first_width latter_width right_justify colorize
- Right or left justify the string representing @var{value}. The width
- of the field in the first line is given by @var{first_width}. For
- subsequent lines the width is given by @var{latter_width}. If
- @var{latter_width=-1}, then @var{first_width} is used for all lines.
- If @var{right_justify=true} then the field is right justified within
- the width of the field. If it is @var{false}, then the field is left
- justified and padded to the full width of the field. If
- @var{colorize} is true, then ledger will honor color settings.
- @smallexample @c command:082FB27,with_input:3406FC1
- $ ledger -f expr.dat --format "»%(justify(account, 30, 30, true))«\n" reg
- @end smallexample
- @smallexample @c output:082FB27
- » Assets:Cash«
- » Expenses:Office Supplies«
- @end smallexample
- @end defun
- @defun market value datetime
- @defunx P
- Return the price of @var{value} at @var{datetime}. Note that @var{datetime}
- must be surrounded by brackets in order to be parsed correctly,
- e.g. @code{[2012/03/23]}.
- @end defun
- @defun nail_down
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @defvar now
- @defvarx d
- @defvarx m
- Return the current datetime.
- @end defvar
- @defvar options
- A variable that allows access to the values of the given command-line options
- using the long option names, e.g. to see whether @option{--daily} or @option{-D}
- was given use @code{option.daily}.
- @smallexample @c command:C1FC7A7,with_input:3406FC1
- $ ledger -f expr.dat -X $ -D --format "%(options.daily) %(options.exchange)\n" reg assets
- @end smallexample
- @smallexample @c output:C1FC7A7
- true $
- @end smallexample
- @end defvar
- @defun percent value_a value_b
- Return the percentage of @var{value_a} in relation to @var{value_b} (used as 100%)
- @smallexample @c command:04959BF,with_input:3406FC1
- $ ledger -f expr.dat --format "%(percent(amount, 200))\n" reg
- @end smallexample
- @smallexample @c output:04959BF
- -61.73%
- 61.73%
- @end smallexample
- @end defun
- @defun print value
- Print @var{value} to stdout. @value{InternalUseOnly}
- @end defun
- @defun quantity value
- Return the quantity of @var{value} for values that have a per-unit cost.
- @end defun
- @defun quoted expression
- Surround @var{expression} with double-quotes.
- @smallexample @c command:EAD8AA7,with_input:3406FC1
- $ ledger -f expr.dat --format "%(quoted(account)) %(quoted(amount))\n" reg
- @end smallexample
- @smallexample @c output:EAD8AA7
- "Assets:Cash" "¤ -123,45"
- "Expenses:Office Supplies" "¤ 123,45"
- @end smallexample
- @end defun
- @defun round
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @defun rounded
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @defun roundto value n
- Return @var{value} rounded to @var{n} digits. Does not affect formatting.
- @smallexample @c command:B4DFB9F,with_input:3406FC1
- $ ledger -f expr.dat --format "%(account) %(roundto(amount, 1))\n" reg
- @end smallexample
- @smallexample @c output:B4DFB9F
- Assets:Cash ¤ -123,40
- Expenses:Office Supplies ¤ 123,50
- @end smallexample
- @end defun
- @defun scrub value
- Clean @var{value} using various transformations such as @code{round}, stripping
- value annotations, and more.
- @end defun
- @defun should_bold
- Return true if expression given to @option{--bold-if} evaluates to true. @value{InternalUseOnly}
- @end defun
- @defun strip value
- @defunx S
- Strip value annotation from @var{value}.
- @end defun
- @defun to_amount value
- Convert @var{value} to an amount. @value{InternalUseOnly}
- @end defun
- @defun to_balance value
- Convert @var{value} to a balance. @value{InternalUseOnly}
- @end defun
- @defun to_boolean value
- Convert @var{value} to a boolean. @value{InternalUseOnly}
- @end defun
- @defun to_date value
- Convert @var{value} to a date. @value{InternalUseOnly}
- @end defun
- @defun to_datetime value
- Convert @var{value} to a datetime. @value{InternalUseOnly}
- @end defun
- @defun to_int value
- @defunx int value
- Return the integer value for @var{value}.
- @smallexample @c command:0B0CBA1,with_input:3406FC1
- $ ledger -f expr.dat --format "%(1 + to_int('1'))\n%(2,5 + int(2,5))\n" reg assets
- @end smallexample
- @smallexample @c output:0B0CBA1
- 2
- 4.5
- @end smallexample
- @end defun
- @defun to_mask value
- Convert @var{value} to a mask. @value{InternalUseOnly}
- @end defun
- @defun to_sequence value
- Convert @var{value} to a sequence. @value{InternalUseOnly}
- @end defun
- @defun to_string value
- @defunx str value
- Convert @var{value} to a character string.
- @end defun
- @defvar today
- Return today's date.
- @end defvar
- @smallexample @c command:F2FDF4B,with_input:3406FC1
- $ ledger -f expr.dat --now 2015/01/01 --format "%(today)\n" reg assets
- @end smallexample
- @smallexample @c output:F2FDF4B
- 2015/01/01
- @end smallexample
- @defun top_amount
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @defun total_expr
- Return the calculated total of the posting according to the @option{--total}
- option.
- @end defun
- @defun trim value
- Trim leading and trailing whitespace from @var{value}.
- @smallexample @c command:377BBAB,with_input:3406FC1
- $ ledger -f expr.dat --format "»%(trim(' Trimmed '))«\n" reg assets
- @end smallexample
- @smallexample @c output:377BBAB
- »Trimmed«
- @end smallexample
- @end defun
- @defun truncatedstring total_len account_len
- Truncate @var{string} to @var{total_len} ensuring that each account is at least
- @var{account_len} long.
- @end defun
- @defun unround
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @defun unrounded
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @defun value_date
- @value{FIXME:UNDOCUMENTED}
- @end defun
- @node Format Strings, Extending with Python, Value Expressions, Top
- @chapter Format Strings
- @menu
- * Format String Basics::
- * Format String Structure::
- * Format Expressions::
- * Balance format::
- * Formatting Functions and Codes::
- @end menu
- @node Format String Basics, Format String Structure, Format Strings, Format Strings
- @section Format String Basics
- @findex --format @var{FORMAT_STRING}
- @findex --balance-format @var{FORMAT_STRING}
- @findex --budget-format @var{FORMAT_STRING}
- @findex --cleared-format @var{FORMAT_STRING}
- @findex --csv-format @var{FORMAT_STRING}
- @findex --plot-amount-format @var{FORMAT_STRING}
- @findex --plot-total-format @var{FORMAT_STRING}
- @findex --pricedb-format @var{FORMAT_STRING}
- @findex --prices-format @var{FORMAT_STRING}
- @findex --register-format @var{FORMAT_STRING}
- Format strings may be used to change the output format of reports. They
- are specified by passing a formatting string to the @option{--format
- @var{FORMAT_STRING} (-F)} option. Within that string, constructs are
- allowed which make it possible to display the various parts of an
- account or posting in custom ways.
- There are several additional flags that allow you to define formats
- for specific reports. These are useful to define in your configuration
- file and will allow you to run ledger reports from the command-line
- without having to enter a new format for each command.
- @itemize
- @item @option{--balance-format @var{FORMAT_STRING}}
- @item @option{--budget-format @var{FORMAT_STRING}}
- @item @option{--cleared-format @var{FORMAT_STRING}}
- @item @option{--csv-format @var{FORMAT_STRING}}
- @item @option{--plot-amount-format @var{FORMAT_STRING}}
- @item @option{--plot-total-format @var{FORMAT_STRING}}
- @item @option{--pricedb-format @var{FORMAT_STRING}}
- @item @option{--prices-format @var{FORMAT_STRING}}
- @item @option{--register-format @var{FORMAT_STRING}}
- @end itemize
- @node Format String Structure, Format Expressions, Format String Basics, Format Strings
- @section Format String Structure
- Within a format string, a substitution is specified using a percent
- @samp{%} character. The basic format of all substitutions is:
- @smallexample
- %[-][MIN WIDTH][.MAX WIDTH](VALEXPR)
- @end smallexample
- If the optional minus sign @samp{-} follows the percent character
- @samp{%}, whatever is substituted will be left justified. The default
- is right justified. If a minimum width is given next, the substituted
- text will be at least that wide, perhaps wider. If a period and
- a maximum width is given, the substituted text will never be wider
- than this, and will be truncated to fit. Here are some examples:
- @table @code
- @item %-20P
- A transaction's payee, left justified and padded to 20 characters wide.
- @item %20P
- The same, right justified, at least 20 chars wide.
- @item %.20P
- The same, no more than 20 chars wide.
- @end table
- The expression following the format constraints can be a single letter,
- or an expression enclosed in parentheses or brackets.
- @node Format Expressions, Balance format, Format String Structure, Format Strings
- @section Format Expressions
- @findex --amount @var{EXPR}
- @findex --total @var{VEXPR}
- For demonstration purposes the journal data from @ref{expr.dat} is used.
- The allowable expressions are:
- @table @code
- @item %
- Inserts a percent sign.
- @smallexample @c command:6F90EFC,with_input:3406FC1
- $ ledger -f expr.dat --format "%%\n" reg assets
- @end smallexample
- @smallexample @c output:6F90EFC
- %
- @end smallexample
- @item t
- Inserts the results of the value expression specified by
- @option{--amount @var{EXPR} (-t)}. If @option{--amount @var{EXPR} (-t)}
- was not specified, the current report style's value expression is used.
- @item T
- Inserts the results of the value expression specified by @option{--total
- @var{VEXPR} (-T)}. If @option{--total @var{VEXPR} (-T)} was not
- specified, the current report style's value expression is used.
- @item (EXPR)
- Inserts the amount resulting from the value expression given in
- parentheses. To insert five times the total value of an account, for
- example, one could say @samp{%12(5*O)}. Note: It's important to put the
- five first in that expression, so that the commodity doesn't get
- stripped from the total.
- @smallexample @c command:494256E,with_input:3406FC1
- $ ledger -f expr.dat --format "%12(5*O)\n" reg assets
- @end smallexample
- @smallexample @c output:494256E
- ¤ -617,25
- @end smallexample
- @item [DATEFMT]
- Inserts the result of formatting a posting's date with a date format
- string, exactly like those supported by @code{strftime (3)}. For
- example: @samp{%[%Y/%m/%d %H:%M:%S]}.
- @item S
- Insert the path name of the file from which the transaction's data was
- read. Only sensible in a @command{register} report.
- @c Note: Unable to test this properly since the output depends on
- @c where the ledger source tree resides in the filesystem.
- @smallexample
- $ ledger -f ~/journal.dat --format "%S\n" reg assets
- @end smallexample
- @smallexample
- /home/jwiegley/journal.dat
- @end smallexample
- @item B
- Inserts the beginning character position of that transaction within the
- file.
- @smallexample @c command:2B669C9,with_input:3406FC1
- $ ledger -f expr.dat --format "%B\n" reg assets
- @end smallexample
- @smallexample @c output:2B669C9
- 26
- @end smallexample
- @item b
- Inserts the beginning line of that transaction within the file.
- @smallexample @c command:F6E356F,with_input:3406FC1
- $ ledger -f expr.dat --format "%b\n" reg assets
- @end smallexample
- @smallexample @c output:F6E356F
- 2
- @end smallexample
- @item E
- Inserts the ending character position of that transaction within the
- file.
- @smallexample @c command:0E55246,with_input:3406FC1
- $ ledger -f expr.dat --format "%E\n" reg assets
- @end smallexample
- @smallexample @c output:0E55246
- 90
- @end smallexample
- @item e
- Inserts the ending line of that transaction within the file.
- @smallexample @c command:A26F4C0,with_input:3406FC1
- $ ledger -f expr.dat --format "%e\n" reg assets
- @end smallexample
- @smallexample @c output:A26F4C0
- 3
- @end smallexample
- @item D
- Returns the date according to the default format.
- @item d
- Returns the date according to the default format. If the transaction
- has an effective date, it prints @code{ACTUAL_DATE=EFFECTIVE_DATE}.
- @item X
- If a posting has been cleared, this returns a 1, otherwise returns 0.
- @item Y
- This is the same as @samp{%X}, except that it only displays a state
- character if all of the member postings have the same state.
- @item C
- Inserts the transaction code. This is the value specified between
- parentheses on the first line of the transaction.
- @smallexample @c command:C1CAAF3,with_input:3406FC1
- $ ledger -f expr.dat --format "%C\n" reg assets
- @end smallexample
- @c Note: The output needs a space character at the end
- @c for this test to pass
- @smallexample @c output:C1CAAF3
- (C0D3)
- @end smallexample
- @item P
- Inserts the payee related to a posting.
- @smallexample @c command:F41A9BB,with_input:3406FC1
- $ ledger -f expr.dat --format "%P\n" reg assets
- @end smallexample
- @smallexample @c output:F41A9BB
- PiggyBank
- @end smallexample
- @c @item a
- @c Inserts the optimal short name for an account. This is normally
- @c used in balance reports. It prints a parent account's name if that
- @c name has not been printed yet, otherwise it just prints the
- @c account's name.
- @item A
- Inserts the full name of an account.
- @smallexample @c command:29A70DD,with_input:3406FC1
- $ ledger -f expr.dat --format "%A\n" reg
- @end smallexample
- @smallexample @c output:29A70DD
- Assets:Cash
- Expenses:Office Supplies
- @end smallexample
- @c @item W
- @c This is the same as @code{%A}, except that it first displays the
- @c posting's state @emph{if the transaction's posting states are not
- @c all the same}, followed by the full account name. This is offered
- @c as a printing optimization, so that combined with @code{%Y}, only
- @c the minimum amount of state detail is printed.
- @c @item o
- @c Inserts the ``optimized'' form of a posting's amount. This is used
- @c by the print report. In some cases, this inserts nothing; in
- @c others, it inserts the posting amount and its cost. It's use is
- @c not recommended unless you are modifying the print report.
- @item N
- Inserts the note associated with a posting, if one exists.
- @smallexample @c command:E6DC93A,with_input:3406FC1
- $ ledger -f expr.dat --format "%N\n" reg assets
- @end smallexample
- @smallexample @c output:E6DC93A
- Payee: PiggyBank
- @end smallexample
- @item /
- The @samp{%/} construct is special. It separates a format string
- between what is printed for the first posting of a transaction, and
- what is printed for all subsequent postings. If not used, the
- same format string is used for all postings.
- @smallexample @c command:E80897D,with_input:3406FC1
- $ ledger -f expr.dat --format "%P\n%/%A\n" reg
- @end smallexample
- @smallexample @c output:E80897D
- PiggyBank
- Expenses:Office Supplies
- @end smallexample
- @end table
- @node Balance format, Formatting Functions and Codes, Format Expressions, Format Strings
- @section Balance format
- @findex --balance-format @var{FORMAT_STRING}
- @findex --format @var{FORMAT_STRING}
- As an example of how flexible the @option{--format @var{FORMAT_STRING}}
- strings can be, the default balance format looks like this (the various
- functions are described later):
- @smallexample
- "%(justify(scrub(display_total), 20, -1, true, color))"
- " %(!options.flat ? depth_spacer : \"\")"
- "%-(ansify_if(partial_account(options.flat), blue if color))\n%/"
- "%$1\n%/"
- "--------------------\n"
- @end smallexample
- @node Formatting Functions and Codes, , Balance format, Format Strings
- @section Formatting Functions and Codes
- @menu
- * Field Widths::
- * Colors::
- * Quantities and Calculations::
- * Date Functions::
- * Date and Time Format Codes::
- * Text Formatting::
- * Data File Parsing Information::
- @end menu
- @node Field Widths, Colors, Formatting Functions and Codes, Formatting Functions and Codes
- @subsection Field Widths
- The following codes return the width allocated for the specific fields.
- The defaults can be changed using the corresponding command-line
- options:
- @itemize
- @item @code{date_width}
- @item @code{payee_width}
- @item @code{account_width}
- @item @code{amount_width}
- @item @code{total_width}
- @end itemize
- @node Colors, Quantities and Calculations, Field Widths, Formatting Functions and Codes
- @subsection Colors
- The character-based formatting ledger can do is limited to the ANSI
- terminal character colors and font highlights in a normal TTY session.
- @multitable @columnfractions .3 .3 .3
- @item @code{red} @tab @code{magenta} @tab @code{bold}
- @item @code{green} @tab @code{cyan} @tab @code{underline}
- @item @code{yellow} @tab @code{white} @tab @code{blink}
- @item @code{blue} @tab @code{black}
- @end multitable
- @node Quantities and Calculations, Date Functions, Colors, Formatting Functions and Codes
- @subsection Quantities and Calculations
- @table @code
- @item amount_expr
- @item abs
- @item commodity
- @item display_amount
- @item display_total
- @item floor
- @item get_at
- @item is_seq
- @item market
- @item percent
- @item price
- @item quantity
- @item rounded
- @item truncated
- @item total_expr
- @item top_amount
- @item to_boolean
- @item to_int
- @item to_amount
- @item to_balance
- @item unrounded
- @end table
- @node Date Functions, Date and Time Format Codes, Quantities and Calculations, Formatting Functions and Codes
- @subsection Date Functions
- @findex --now @var{DATE}
- The following functions allow you to manipulate and format dates.
- @table @code
- @item date
- Return the date of the current transaction.
- @item format_date(date, "FORMAT_STRING")
- Format the date using the given format string.
- @item now
- Return the current date and time. If the @option{--now @var{DATE}}
- option is defined it will return that value.
- @item today
- Return the current date. If the @option{--now @var{DATE}} option is
- defined it will return that value.
- @item to_datetime
- Convert a string to a date-time value.
- @item to_date
- Convert a string to date value.
- @item value_date
- @end table
- @menu
- * Date and Time Format Codes::
- @end menu
- @node Date and Time Format Codes, Text Formatting, Date Functions, Formatting Functions and Codes
- @subsection Date and Time Format Codes
- Date and time format are specified as strings of single letter codes
- preceded by percent signs. Any separator, or no separator can be
- specified.
- @menu
- * Days::
- * Weekdays::
- * Month::
- * Miscellaneous Date Codes::
- @end menu
- @node Days, Weekdays, Date and Time Format Codes, Date and Time Format Codes
- @subsubsection Days
- Dates are formed from a combination of day, month and year codes, in
- whatever order you prefer:
- @table @code
- @item %Y
- Four digit year.
- @item %y
- Two digit year.
- @item %m
- Two digit month.
- @item %d
- Two digit date.
- @end table
- @noindent
- So @code{"%Y%m%d"} yields @samp{20111214} which provides a date that
- is simple to sort on.
- @node Weekdays, Month, Days, Date and Time Format Codes
- @subsubsection Weekdays
- You can have additional weekday information in your date with @samp{%A}
- as
- @table @code
- @item %m-%d-%Y %A
- yields @samp{02-10-2010 Wednesday}.
- @item %A %m-%d-%Y
- yields @samp{Wednesday 02-10-2010}.
- @end table
- @noindent
- These are options you can select for weekday
- @table @code
- @item %a
- weekday, abbreviated Wed.
- @item %A
- weekday, full Wednesday.
- @item %d
- day of the month (dd), zero padded up to 10.
- @item %e
- day of the month (dd), no leading zero up to 10.
- @item %j
- day of year, zero padded 000–366.
- @item %u
- day of week starting with Monday (1), i.e. @code{mtwtfss} 3.
- @item %w
- day of week starting with Sunday (0), i.e. @code{smtwtfs} 3.
- @end table
- @node Month, Miscellaneous Date Codes, Weekdays, Date and Time Format Codes
- @subsubsection Month
- You can have additional month information in your date with @samp{%B}
- as
- @table @code
- @item %m-%d-%Y %B
- yields @samp{02-10-2010 February}.
- @item %B %m-%d-%Y
- yields @samp{February 02-10-2010}.
- @end table
- @noindent
- These are options you can select for month
- @table @code
- @item %m
- @samp{mm} month as two digits.
- @item %b
- Locale’s abbreviated month, for example @samp{02} might be abbreviated
- as @samp{Feb}.
- @item %B
- Locale’s full month, variable length, e.g. February.
- @end table
- @node Miscellaneous Date Codes, , Month, Date and Time Format Codes
- @subsubsection Miscellaneous Date Codes
- Additional date format parameters which can be used:
- @table @code
- @item %U
- week number Sunday as first day of week, ranging 01–53.
- @item %W
- week number Monday as first day of week, ranging 01–53.
- @item %V
- week of the year, ranging 01–53.
- @item %C
- century, ranging 00–99.
- @item %D
- yields @code{%m/%d/%y} as in @samp{02/10/10}.
- @item %x
- locale’s date representation, as @samp{02/10/2010} for the U.S.
- @item %F
- yields @code{%Y-%m-%d} as in @samp{2010-02-10}.
- @end table
- @node Text Formatting, Data File Parsing Information, Date and Time Format Codes, Formatting Functions and Codes
- @subsection Text Formatting
- The following format functions allow you limited formatting of text:
- @table @code
- @item ansify_if(value, color)
- Surrounds the string representing value with ANSI codes to give it
- @code{color} on an TTY display. Has no effect if directed to a file.
- @item justify(value, first_width, latter_width, right_justify, colorize)
- Right or left justify the string representing @code{value}. The width
- of the field in the first line is given by @code{first_width}. For
- subsequent lines the width is given by @code{latter_width}. If
- @code{latter_width=-1}, then @code{first_width} is use for all lines.
- If @code{right_justify=true} then the field is right justify within
- the width of the field. If it is @code{false}, then the field is left
- justified and padded to the full width of the field. If
- @code{colorize} is true, then ledger will honor color settings.
- @item join(STR)
- Replaces line feeds in @code{STR} with @samp{\n}.
- @item quoted(STR)
- Return @code{STR} surrounded by double quotes, @samp{"STR"}.
- @item strip(value)
- Values can have numerous annotations, such as effective dates and lot
- prices. @code{strip} removes these annotations.
- @end table
- @node Data File Parsing Information, , Text Formatting, Formatting Functions and Codes
- @subsection Data File Parsing Information
- The following format strings provide locational metadata
- regarding the coordinates of entries in the source data file(s) that
- generated the posting.
- @table @code
- @item filename
- the name of the ledger data file from whence the posting came,
- abbreviated @samp{S}.
- @item beg_pos
- character position in @code{filename} where entry for posting begins,
- abbreviated @samp{B}.
- @item end_pos
- character position in @code{filename} where entry for posting ends,
- abbreviated @samp{E}.
- @item beg_line
- line number in @code{filename} where entry for posting begins,
- abbreviated @samp{b}.
- @item end_line
- line number in @code{filename} where entry for posting ends,
- abbreviated @samp{e}.
- @end table
- @node Extending with Python, Ledger for Developers, Format Strings, Top
- @chapter Extending with Python
- Python can be used to extend your Ledger experience. But first,
- a word must be said about Ledger's data model, so that other things
- make sense later.
- @menu
- * Basic data traversal::
- * Raw versus Cooked::
- * Queries::
- * Embedded Python::
- * Amounts::
- @end menu
- @node Basic data traversal, Raw versus Cooked, Extending with Python, Extending with Python
- @section Basic data traversal
- Every interaction with Ledger happens in the context of a Session.
- Even if you don't create a session manually, one is created for you by
- the top-level interface functions. The Session is where objects live
- like the Commodities that Amounts refer to.
- The make a Session useful, you must read a Journal into it, using the
- function `@code{read_journal}`. This reads Ledger data from the given
- file, populates a Journal object within the current Session, and
- returns a reference to that Journal object.
- Within the Journal live all the Transactions, Postings, and other
- objects related to your data. There are also AutomatedTransactions
- and PeriodicTransactions, etc.
- Here is how you would traverse all the postings in your data file:
- @smallexample
- import ledger
- for xact in ledger.read_journal("sample.dat").xacts():
- for post in xact.posts():
- print "Transferring %s to/from %s" % (post.amount, post.account)
- @end smallexample
- @node Raw versus Cooked, Queries, Basic data traversal, Extending with Python
- @section Raw versus Cooked
- Ledger data exists in one of two forms: raw and cooked. Raw objects are
- what you get from a traversal like the above, and represent exactly what
- was seen in the data file. Consider this journal:
- @smallexample @c input:validate
- = true
- (Assets:Cash) $100
- 2012-03-01 KFC
- Expenses:Food $100
- Assets:Credit
- @end smallexample
- In this case, the @emph{raw} regular transaction in this file is:
- @smallexample @c input:validate
- 2012-03-01 KFC
- Expenses:Food $100
- Assets:Credit
- @end smallexample
- While the @emph{cooked} form is:
- @smallexample @c input:validate
- 2012-03-01 KFC
- Expenses:Food $100
- Assets:Credit $-100
- (Assets:Cash) $100
- @end smallexample
- So the easy way to think about raw vs. cooked is that raw is the
- unprocessed data, and cooked has had all considerations applied.
- When you traverse a Journal by iterating over its transactions, you are
- generally looking at raw data. In order to look at cooked data, you
- must generate a report of some kind by querying the journal:
- @smallexample
- for post in ledger.read_journal("sample.dat").query("food"):
- print "Transferring %s to/from %s" % (post.amount, post.account)
- @end smallexample
- The reason why queries iterate over postings instead of transactions is
- that queries often return only a ``slice'' of the transactions they
- apply to. You can always get at a matching posting's transaction by
- looking at its @code{xact} member:
- @smallexample
- last_xact = None
- for post in ledger.read_journal("sample.dat").query(""):
- if post.xact != last_xact:
- for post in post.xact.posts:
- print "Transferring %s to/from %s" % (post.amount,
- post.account)
- last_xact = post.xact
- @end smallexample
- This query ends up reporting every cooked posting in the Journal, but
- does it transaction-wise. It relies on the fact that an unsorted report
- returns postings in the exact order they were parsed from the journal
- file.
- @node Queries, Embedded Python, Raw versus Cooked, Extending with Python
- @section Queries
- The Journal.query() method accepts every argument you can specify on the
- command-line, including @option{--options}.
- Since a query ``cooks'' the journal it applies to, only one query may be
- active for that journal at a given time. Once the query object is gone
- (after the for loop), then the data reverts back to its raw state.
- @node Embedded Python, Amounts, Queries, Extending with Python
- @section Embedded Python
- You can embed Python into your data files using the 'python' directive:
- @smallexample
- python
- import os
- def check_path(path_value):
- print "%s => %s" % (str(path_value), os.path.isfile(str(path_value)))
- return os.path.isfile(str(path_value))
- tag PATH
- assert check_path(value)
- 2012-02-29 KFC
- ; PATH: somebogusfile.dat
- Expenses:Food $20
- Assets:Cash
- @end smallexample
- Any Python functions you define this way become immediately available as
- valexpr functions.
- @node Amounts, , Embedded Python, Extending with Python
- @section Amounts
- When numbers come from Ledger, like post.amount, the type of the value
- is Amount. It can be used just like an ordinary number, except that
- addition and subtraction are restricted to amounts with the same
- commodity. If you need to create sums of multiple commodities, use
- a Balance. For example:
- @smallexample
- total = Balance()
- for post in ledger.read_journal("sample.dat").query(""):
- total += post.amount
- print total
- @end smallexample
- @node Ledger for Developers, Major Changes from version 2.6, Extending with Python, Top
- @chapter Ledger for Developers
- @menu
- * Internal Design::
- * Journal File Format for Developers::
- * Developer Commands::
- * Ledger Development Environment::
- @end menu
- @node Internal Design, Journal File Format for Developers, Ledger for Developers, Ledger for Developers
- @section Internal Design
- Ledger is developed as a tiered set of functionality, where lower tiers
- know nothing about the higher tiers. In fact, multiple libraries are
- built during the development the process, and link unit tests to these
- libraries, so that it is a link error for a lower tier to violate this
- modularity.
- Those tiers are:
- @itemize
- @item Utility code
- There's lots of general utility in Ledger for doing time parsing, using
- Boost.Regex, error handling, etc. It's all done in a way that can be
- reused in other projects as needed.
- @item Commoditized Amounts (amount_t, commodity_t and friends)
- A numerical abstraction combining multi-precision rational numbers (via
- GMP) with commodities. These structures can be manipulated like regular
- numbers in either C++ or Python (as Amount objects).
- @item Commodity Pool
- Commodities are all owned by a commodity pool, so that future parsing of
- amounts can link to the same commodity and established a consistent
- price history and record of formatting details.
- @item Balances
- Adds the concept of multiple amounts with varying commodities. Supports
- simple arithmetic, and multiplication and division with non-commoditized
- values.
- @item Price history
- Amounts have prices, and these are kept in a data graph which the amount
- code itself is only dimly aware of (there's three points of access so an
- amount can query its revalued price on a given date).
- @item Values
- Often the higher layers in Ledger don't care if something is an amount
- or a balance, they just want to add stuff to it or print it. For this,
- I created a type-erasure class, value_t/Value, into which many things
- can be stuffed and then operated on. They can contain amounts,
- balances, dates, strings, etc. If you try to apply an operation between
- two values that makes no sense (like dividing an amount by a balance),
- an error occurs at runtime, rather than at compile-time (as would happen
- if you actually tried to divide an @code{amount_t} by
- a @code{balance_t}).
- This is the core data type for the value expression language.
- @item Value expressions
- The next layer up adds functions and operators around the Value concept.
- This lets you apply transformations and tests to Values at runtime
- without having to bake it into C++. The set of functions available is
- defined by each object type in Ledger (posts, accounts, transactions,
- etc.), though the core engine knows nothing about these. At its base,
- it only knows how to apply operators to values, and how to pass them to
- and receive them from functions.
- @item Query expressions
- Expressions can be onerous to type at the command-line, so there's
- a shorthand for reporting called ``query expressions''. These add no
- functionality of their own, but are purely translated from the input
- string down to the corresponding value expression, for example the
- input string @samp{cash} is translated to @samp{(account
- =~ /cash/)}. This is a convenience layer.
- @item Format strings
- Format strings let you interpolate value expressions into strings, with
- the requirement that any interpolated value have a string
- representation. Really all this does is calculate the value expression
- in the current report context, call the resulting value's
- @code{to_string()} method, and stuffs the result into the output string.
- It also provides printf-like behavior, such as min/max width, right/left
- justification, etc.
- @item Journal items
- Next is a base type shared by anything that can appear in a journal: an
- item_t. It contains details common to all such parsed entities, like
- what file and line it was found on, etc.
- @item Journal posts
- The most numerous object found in a Journal, postings are a type of item
- that contain an account, an amount, a cost, and metadata. There are
- some other complications, like the account can be marked virtual, the
- amount could be an expression, etc.
- @item Journal transactions
- Postings are owned by transactions, always. This subclass of @code{item_t}
- knows about the date, the payee, etc. If a date or metadata tag is
- requested from a posting and it doesn't have that information, the
- transaction is queried to see if it can provide it.
- @item Journal accounts
- Postings are also shared by accounts, though the actual memory is
- managed by the transaction. Each account knows all the postings within
- it, but contains relatively little information of its own.
- @item The Journal object
- Finally, all transactions with their postings, and all accounts, are
- owned by a @code{journal_t} object. This is the go-to object for
- querying and reporting on your data.
- @item Textual journal parser
- There is a textual parser, wholly contained in @file{textual.cc}, which
- knows how to parse text into journal objects, which then get
- ``finalized'' and added to the journal. Finalization is the step that
- enforces the double-entry guarantee.
- @item Iterators
- Every journal object is ``iterable'', and these iterators are defined in
- @file{iterators.h} and @file{iterators.cc}. This iteration logic is kept out of the
- basic journal objects themselves for the sake of modularity.
- @item Comparators
- Another abstraction isolated to its own layer, this class encapsulating
- the comparison of journal objects, based on whatever value expression
- the user passed to @option{--sort @var{VEXPR}}.
- @item Temporaries
- Many reports bring pseudo-journal objects into existence, like postings
- which report totals in a @samp{Total} account. These objects are
- created and managed by a @code{temporaries_t} object, which gets used in
- many places by the reporting filters.
- @item Option handling
- There is an option handling subsystem used by many of the layers further
- down. It makes it relatively easy for me to add new options, and to
- have those option settings immediately accessible to value expressions.
- @item Session objects
- Every journal object is owned by a session, with the session providing
- support for that object. In GUI terms, this is the Controller object
- for the journal Data object, where every document window would be
- a separate session. They are all owned by the global scope.
- @item Report objects
- Every time you create any report output, a report object is created to
- determine what you want to see. In the Ledger REPL, a new report object
- is created every time a command is executed. In CLI mode, only one
- report object ever comes into being, as Ledger immediately exits after
- displaying the results.
- @item Reporting filters
- The way Ledger generates data is this: it asks the session for the
- current journal, and then creates an iterator applied to that journal.
- The kind of iterator depends on the type of report.
- This iterator is then walked, and every object yielded from the iterator
- is passed to an ``item handler'', whose type is directly related to the
- type of the iterator.
- There are many, many item handlers, which can be chained together. Each
- one receives an item (post, account, xact, etc.), performs some action
- on it, and then passes it down to the next handler in the chain. There
- are filters which compute the running totals; that queue and sort all
- the input items before playing them back out in a new order; that filter
- out items which fail to match a predicate, etc. Almost every reporting
- feature in Ledger is related to one or more filters. Looking at
- @file{filters.h}, there are over 25 of them defined currently.
- @item The filter chain
- How filters get wired up, and in what order, is a complex process based
- on all the various options specified by the user. This is the job of
- the chain logic, found entirely in @file{chain.cc}. It took a really
- long time to get this logic exactly right, which is why I haven't
- exposed this layer to the Python bridge yet.
- @item Output modules
- Although filters are great and all, in the end you want to see stuff.
- This is the job of special ``leaf'' filters called output modules. They
- are implemented just like a regular filter, but they don't have
- a ``next'' filter to pass the data on down to. Instead, they are the
- end of the line and must do something with the item that results in the
- user seeing something on their screen or in a file.
- @item Select queries
- Select queries know a lot about everything, even though they implement
- their logic by implementing the user's query in terms of all the other
- features thus presented. Select queries have no functionality of their
- own, they are simple a shorthand to provide access to much of Ledger's
- functionality via a cleaner, more consistent syntax.
- @item The Global Scope
- There is a master object which owns every other objects, and this is
- Ledger's global scope. It creates the other objects, provides REPL
- behavior for the command-line utility, etc. In GUI terms, this is the
- Application object.
- @item The Main Driver
- This creates the global scope object, performs error reporting, and
- handles command-line options which must precede even the creation of the
- global scope, such as @option{--debug @var{CODE}}.
- @end itemize
- And that's Ledger in a nutshell. All the rest are details, such as
- which value expressions each journal item exposes, how many filters
- currently exist, which options the report and session scopes define,
- etc.
- @node Journal File Format for Developers, Developer Commands, Internal Design, Ledger for Developers
- @section Journal File Format for Developers
- This chapter offers a complete description of the journal data format,
- suitable for implementers in other languages to follow. For users, the
- chapter on keeping a journal is less extensive, but more typical of
- common usage (@pxref{Keeping a Journal}).
- Data is collected in the form of @dfn{transactions} which occur in one
- or more @dfn{journal files}. Each transaction, in turn, is made up of
- one or more @dfn{postings}, which describe how @dfn{amounts} flow from
- one @dfn{account} to another. Here is an example of the simplest of
- journal files:
- @smallexample @c input:validate
- 2010/05/31 Just an example
- Expenses:Some:Account $100.00
- Income:Another:Account
- @end smallexample
- In this example, there is a transaction date, a payee, or description of
- the transaction, and two postings. The postings show movement of one
- hundred dollars from an account within the Income hierarchy, to the
- specified expense account. The name and meaning of these accounts is
- arbitrary, with no preferences implied, although you will find it useful
- to follow standard accounting practices (@pxref{Principles of Accounting
- with Ledger}).
- Since an amount is missing from the second posting, it is assumed to be
- the inverse of the first. This guarantees the cardinal rule of
- double-entry accounting: the sum of every transaction must balance to
- zero, or it is in error. Whenever Ledger encounters a @dfn{null
- posting} in a transaction, it uses it to balance the remainder.
- It is also typical, though not enforced, to think of the first posting
- as the destination, and the final as the source. Thus, the amount of
- the first posting is typically positive. Consider:
- @smallexample @c input:validate
- 2010/05/31 An income transaction
- Assets:Checking $1,000.00
- Income:Salary
- 2010/05/31 An expense transaction
- Expenses:Dining $100.00
- Assets:Checking
- @end smallexample
- @menu
- * Comments and meta-data::
- * Specifying Amounts::
- * Posting costs::
- * Primary commodities::
- @end menu
- @node Comments and meta-data, Specifying Amounts, Journal File Format for Developers, Journal File Format for Developers
- @subsection Comments and meta-data
- Comments are generally started using a @samp{;}. However, in order to
- increase compatibility with other text manipulation programs and methods
- three additional comment characters are valid if used at the beginning
- of a line: @samp{#}, @samp{|}, and @samp{*}.
- @node Specifying Amounts, Posting costs, Comments and meta-data, Journal File Format for Developers
- @subsection Specifying Amounts
- @cindex amounts
- The heart of a journal is the amounts it records, and this fact is
- reflected in the diversity of amount expressions allowed. All of them
- are covered here, though it must be said that sometimes, there are
- multiple ways to achieve a desired result.
- @emph{Note:} It is important to note that there must be at least two
- spaces between the end of the account and the beginning of the amount
- (including a commodity designator).
- @menu
- * Integer Amounts::
- * Commoditized Amounts::
- @end menu
- @node Integer Amounts, Commoditized Amounts, Specifying Amounts, Specifying Amounts
- @subsubsection Integer Amounts
- In the simplest form, bare decimal numbers are accepted:
- @smallexample @c input:validate
- 2010/05/31 An income transaction
- Assets:Checking 1000.00
- Income:Salary
- @end smallexample
- @cindex uncommoditized amounts
- Such amounts may only use an optional period for a decimal point. These
- are referred to as @dfn{integer amounts} or @dfn{uncommoditized
- amounts}. In most ways they are similar to @dfn{commoditized amounts},
- but for one significant difference: They always display in reports with
- @dfn{full precision}. More on this in a moment. For now, a word must
- be said about how Ledger stores numbers.
- Every number parsed by Ledger is stored internally as an
- infinite-precision rational value. Floating-point math is never used,
- as it cannot be trusted to maintain precision of values. So, in the
- case of @samp{1000.00} above, the internal value is @samp{100000/100}.
- While rational numbers are great at not losing precision, the question
- arises: How should they be displayed? A number like @samp{100000/100}
- is no problem, since it represents a clean decimal fraction. But what
- about when the number @samp{1/1} is divided by three? How should one
- print @samp{1/3}, an infinitely repeating decimal?
- Ledger gets around this problem by rendering rationals into decimal at
- the last possible moment, and only for display. As such, some
- rounding must, at times, occur. If this rounding would affect the
- calculation of a running total, special accommodation postings are
- generated to make you aware it has happened. In practice, it happens
- rarely, but even then it does not reflect adjustment of the
- @emph{internal amount}, only the displayed amount.
- What has still not been answered is how Ledger rounds values. Should
- @samp{1/3} be printed as @samp{0.33} or @samp{0.33333}? For
- commoditized amounts, the number of decimal places is decided by
- observing how each commodity is used; but in the case of integer
- amounts, an arbitrary factor must be chosen. Initially, this factor
- is six. Thus, @samp{1/3} is printed back as @samp{0.333333}.
- Further, this rounding factor becomes associated with each particular
- value, and is carried through mathematical operations. For example,
- if that particular number were multiplied by itself, the decimal
- precision of the result would be twelve. Addition and subtraction do
- not affect precision.
- Since each integer amount retains its own display precision, this is
- called @dfn{full precision}, as opposed to commoditized amounts, which
- always look to their commodity to know what precision they should
- round to, and so use @dfn{commodity precision}.
- @node Commoditized Amounts, , Integer Amounts, Specifying Amounts
- @subsubsection Commoditized Amounts
- A @dfn{commoditized amount} is an integer amount which has an
- associated commodity. This commodity can appear before or after the
- amount, and may or may not be separated from it by a space. Most
- characters are allowed in a commodity name, except for the following:
- @itemize @bullet
- @item Any kind of white-space
- @item Numerical digits
- @item Punctuation: @code{.,;:?!}
- @item Mathematical and logical operators: @code{-+*/^&|=}
- @item Bracketing characters: @code{<>[]()}@{@}
- @item The at symbol: @code{@@}
- @end itemize
- And yet, any of these may appear in a commodity name if it is
- surrounded by double quotes, for example:
- @smallexample
- 100 "EUN+133"
- @end smallexample
- If a @dfn{quoted commodity} is found, it is displayed in quotes as
- well, to avoid any confusion as to which part is the amount, and which
- part is the commodity.
- Another feature of commoditized amounts is that they are reported back
- in the same form as parsed. If you specify dollar amounts using
- @samp{$100}, they will print the same; likewise with @samp{100 $} or
- @samp{$100.000}. You may even use decimal commas, such as
- @samp{$100,00}, or thousand-marks, as in @samp{$10,000.00}.
- These display characteristics become associated with the commodity,
- with the result being that all amounts of the same commodity are
- reported consistently. Where this is most noticeable is the
- @dfn{display precision}, which is determined by the most precise value
- seen for a given commodity---in most cases.
- Ledger makes a distinction between @dfn{observed amounts} and
- unobserved amounts. An observed amount is critiqued by Ledger to
- determine how amounts using that commodity should be displayed;
- unobserved amounts are significant in their value only---no matter how
- they are specified, it does not change how other amounts in that
- commodity will be displayed.
- An example of this is found in cost expressions, covered next.
- @node Posting costs, Primary commodities, Specifying Amounts, Journal File Format for Developers
- @subsection Posting costs
- You have seen how to specify either a commoditized or an integer
- amount for a posting. But what if the amount you paid for something
- was in one commodity, and the amount received was another? There are
- two main ways to express this:
- @smallexample @c input:validate
- 2010/05/31 Farmer's Market
- Assets:My Larder 100 apples
- Assets:Checking -$20.00
- @end smallexample
- In this example, you have paid twenty dollars for one hundred apples.
- The cost to you is twenty cents per apple, and Ledger calculates this
- implied cost for you. You can also make the cost explicit using a
- @dfn{cost amount}:
- @smallexample @c input:validate
- 2010/05/31 Farmer's Market
- Assets:My Larder 100 apples @@ $0.200000
- Assets:Checking
- @end smallexample
- Here the @dfn{per-unit cost} is given explicitly in the form of a cost
- amount; and since cost amounts are @emph{unobserved}, the use of six
- decimal places has no effect on how dollar amounts are displayed in
- the final report. You can also specify the @dfn{total cost}:
- @smallexample @c input:validate
- 2010/05/31 Farmer's Market
- Assets:My Larder 100 apples @@@@ $20
- Assets:Checking
- @end smallexample
- These three forms have identical meaning. In most cases the first is
- preferred, but the second two are necessary when more than two
- postings are involved:
- @smallexample @c input:validate
- 2010/05/31 Farmer's Market
- Assets:My Larder 100 apples @@ $0.200000
- Assets:My Larder 100 pineapples @@ $0.33
- Assets:My Larder 100 "crab apples" @@ $0.04
- Assets:Checking
- @end smallexample
- Here the implied cost is @samp{$57.00}, which is entered into the null
- posting automatically so that the transaction balances.
- @node Primary commodities, , Posting costs, Journal File Format for Developers
- @subsection Primary commodities
- @findex --market
- @findex --basis
- In every transaction involving more than one commodity, there is
- always one which is the @dfn{primary commodity}. This commodity
- should be thought of as the exchange commodity, or the commodity used
- to buy and sell units of the other commodity. In the fruit examples
- above, dollars are the primary commodity. This is decided by Ledger
- based on the placement of the commodity in the transaction:
- @smallexample @c input:validate
- 2010/05/31 Sample Transaction
- Expenses 100 secondary
- Assets -50 primary
- 2010/05/31 Sample Transaction
- Expenses 100 secondary @@ 0.5 primary
- Assets
- 2010/05/31 Sample Transaction
- Expenses 100 secondary @@@@ 50 primary
- Assets
- @end smallexample
- The only case where knowledge of primary versus secondary comes into
- play is in reports that use the @option{--market (-V)} or
- @option{--basis (-B)} options. With these, only primary commodities are
- shown.
- If a transaction uses only one commodity, this commodity is also
- considered a primary. In fact, when Ledger goes about ensuring that
- all transactions balance to zero, it only ever asks this of primary
- commodities.
- @node Developer Commands, Ledger Development Environment, Journal File Format for Developers, Ledger for Developers
- @section Developer Commands
- @menu
- * @command{echo}::
- * @command{reload}::
- * @command{source}::
- * Debug Options::
- * Pre-Commands::
- @end menu
- @node @command{echo}, @command{reload}, Developer Commands, Developer Commands
- @subsection @command{echo}
- @findex echo
- This command simply echoes its argument back to the output.
- @node @command{reload}, @command{source}, @command{echo}, Developer Commands
- @subsection @command{reload}
- @findex reload
- Forces ledger to reload any journal files. This function exists to
- support external programs controlling a running ledger process and does
- nothing for a command-line user.
- @node @command{source}, Debug Options, @command{reload}, Developer Commands
- @subsection @command{source}
- @findex source
- The @command{source} command takes a journal file as an argument and
- parses it checking for errors; no other reports are generated, and no
- other arguments are necessary. Ledger will return success if no errors
- are found.
- @node Debug Options, Pre-Commands, @command{source}, Developer Commands
- @subsection Debug Options
- These options are primarily for Ledger developers, but may be of some
- use to a user trying something new.
- @ftable @option
- @item --args-only
- Ignore init files and environment variables for the ledger run.
- @item --debug @var{CODE}
- If Ledger has been built with debug options this will provide extra
- data during the run. The following are the available @var{CODES} to
- debug:
- @multitable @columnfractions .32 .43 .27
- @item @code{account.display} @tab @code{draft.xact} @tab @code{option.names}
- @item @code{account.sorted} @tab @code{expr.calc} @tab @code{org.next_amount}
- @item @code{amount.commodities} @tab @code{expr.compile} @tab @code{org.next_total}
- @item @code{amount.convert} @tab @code{expr.merged.compile} @tab @code{parser.error}
- @item @code{amount.is_zero} @tab @code{filters.changed_value} @tab @code{pool.commodities}
- @item @code{amount.parse} @tab @code{filters.changed_value.rounding} @tab @code{post.assign}
- @item @code{amount.price} @tab @code{filters.collapse} @tab @code{python.init}
- @item @code{amount.refs} @tab @code{filters.forecast} @tab @code{python.interp}
- @item @code{amount.roundto} @tab @code{filters.interval} @tab @code{query.mask}
- @item @code{amount.truncate} @tab @code{filters.revalued} @tab @code{report.predicate}
- @item @code{amount.unround} @tab @code{format.abbrev} @tab @code{scope.search}
- @item @code{annotate.less} @tab @code{format.expr} @tab @code{scope.symbols}
- @item @code{archive.journal} @tab @code{generate.post} @tab @code{select.parse}
- @item @code{auto.columns} @tab @code{generate.post.string} @tab @code{textual.include}
- @item @code{budget.generate} @tab @code{history.find} @tab @code{textual.parse}
- @item @code{commodity.annotated.strip} @tab @code{history.map} @tab @code{timelog}
- @item @code{commodity.annotations} @tab @code{item.meta} @tab @code{times.epoch}
- @item @code{commodity.compare} @tab @code{ledger.read} @tab @code{times.interval}
- @item @code{commodity.download} @tab @code{ledger.validate} @tab @code{times.parse}
- @item @code{commodity.exchange} @tab @code{lookup} @tab @code{value.sort}
- @item @code{commodity.price.find} @tab @code{lookup.account} @tab @code{value.storage.refcount}
- @item @code{commodity.prices.add} @tab @code{mask.match} @tab @code{xact.extend}
- @item @code{commodity.prices.find} @tab @code{memory.debug} @tab @code{xact.extend.cleared}
- @item @code{csv.mappings} @tab @code{op.memory} @tab @code{xact.extend.fail}
- @item @code{csv.parse} @tab @code{option.args} @tab @code{xact.finalize}
- @end multitable
- @
- @item --trace @var{INT}
- Enable tracing. The @var{INT} specifies the level of trace desired:
- @multitable @columnfractions .3 .7
- @item @code{LOG_OFF} @tab 0
- @item @code{LOG_CRIT} @tab 1
- @item @code{LOG_FATAL} @tab 2
- @item @code{LOG_ASSERT} @tab 3
- @item @code{LOG_ERROR} @tab 4
- @item @code{LOG_VERIFY} @tab 5
- @item @code{LOG_WARN} @tab 6
- @item @code{LOG_INFO} @tab 7
- @item @code{LOG_EXCEPT} @tab 8
- @item @code{LOG_DEBUG} @tab 9
- @item @code{LOG_TRACE} @tab 10
- @item @code{LOG_ALL} @tab 11
- @end multitable
- @
- @item --verbose
- @itemx -v
- Print detailed information on the execution of Ledger.
- @item --verify
- Enable additional assertions during run-time. This causes a significant
- slowdown. When combined with @option{--debug @var{CODE}} ledger will
- produce memory trace information.
- @item --verify-memory
- Verify that every constructed object is properly destructed. This is for
- debugging purposes only.
- @item --version
- Print version information and exit.
- @end ftable
- @node Pre-Commands, , Debug Options, Developer Commands
- @subsection Pre-Commands
- @cindex pre-commands
- Pre-commands are useful when you aren't sure how a command or option
- will work. The difference between a pre-command and a regular command
- is that pre-commands ignore the journal data file completely, nor is
- the user's init file read.
- @ftable @command
- @item eval @var{VEXPR}
- Evaluate the given value expression against the model transaction.
- @item format @var{FORMAT_STRING}
- Print details of how ledger uses the given formatting description and
- apply it against a model transaction.
- @item generate
- Randomly generates syntactically valid Ledger data from a seed. Used
- by the @samp{GenerateTests} harness for development testing.
- @item parse @var{VEXPR}
- @itemx expr @var{VEXPR}
- Print details of how ledger uses the given value expression description
- and apply it against a model transaction.
- @item period @var{PERIOD_EXPRESSION}
- Evaluate the given period and report how Ledger interprets it:
- @smallexample @c command:51F6A2C
- $ ledger period "this year" --now 2011-01-01
- @end smallexample
- @smallexample @c output:51F6A2C
- --- Period expression tokens ---
- TOK_THIS: this
- TOK_YEAR: year
- END_REACHED: <EOF>
- --- Before stabilization ---
- range: in year 2011
- --- After stabilization ---
- range: in year 2011
- start: 11-Jan-01
- finish: 12-Jan-01
- --- Sample dates in range (max. 20) ---
- 1: 11-Jan-01
- @end smallexample
- @item query
- @itemx args
- Evaluate the given arguments and report how Ledger interprets it against
- the following model transaction:
- @smallexample @c command:validate
- $ ledger query "/Book/"
- @end smallexample
- @smallexample
- --- Input arguments ---
- ("/Book/")
- --- Context is first posting of the following transaction ---
- 2004/05/27 Book Store
- ; This note applies to all postings. :SecondTag:
- Expenses:Books 20 BOOK @@ $10
- ; Metadata: Some Value
- ; Typed:: $100 + $200
- ; :ExampleTag:
- ; Here follows a note describing the posting.
- Liabilities:MasterCard $-200.00
- --- Input expression ---
- (account =~ /Book/)
- --- Text as parsed ---
- (account =~ /Book/)
- --- Expression tree ---
- 0x7fd639c0da40 O_MATCH (1)
- 0x7fd639c10170 IDENT: account (1)
- 0x7fd639c10780 VALUE: /Book/ (1)
- --- Compiled tree ---
- 0x7fd639c10520 O_MATCH (1)
- 0x7fd639c0d6c0 IDENT: account (1)
- 0x7fd639c0d680 FUNCTION (1)
- 0x7fd639c10780 VALUE: /Book/ (1)
- --- Calculated value ---
- true
- @end smallexample
- @item script
- @value{FIXME:UNDOCUMENTED}
- @item template
- Shows the insertion template that the @command{xact} sub-command
- generates. This is a debugging command.
- @end ftable
- @node Ledger Development Environment, , Developer Commands, Ledger for Developers
- @section Ledger Development Environment
- @menu
- * @file{acprep} build configuration tool::
- * Testing Framework::
- @end menu
- @node @file{acprep} build configuration tool, Testing Framework, Ledger Development Environment, Ledger Development Environment
- @subsection @file{acprep} build configuration tool
- @node Testing Framework, , @file{acprep} build configuration tool, Ledger Development Environment
- @subsection Testing Framework
- Ledger source ships with a fairly complete set of tests to verify that
- all is well, and no old errors have resurfaced. Tests are run
- individually with @file{ctest}. All tests can be run using @code{make
- check} or @code{ninja check} depending on which build tool you prefer.
- Once built, the ledger executable resides under the @file{build}
- subdirectory in the source tree. Tests are built and stored in the
- @file{test} subdirectory for the build. For example,
- @file{~/ledger/build/ledger/opt/test}.
- @menu
- * Running Tests::
- * Writing Tests::
- @end menu
- @node Running Tests, Writing Tests, Testing Framework, Testing Framework
- @subsubsection Running Tests
- The complete test suite can be run from the build directory using the
- check option for the build tool you use. For example, @code{make
- check}. The entire test suit lasts around a minute for the optimized
- built and many times longer for the debug version. While developing
- and debugging, running individual tests can save a great deal of time.
- Individual tests can be run from the @file{test} subdirectory of the
- build location. To execute a single test use @code{ctest -V -R regex},
- where the regex matches the name of the test you want to build.
- There are nearly 300 tests stored under the @file{test} subdirectory
- in the main source distribution. They are broken into two broad
- categories, baseline and regression. To run the @file{5FBF2ED8} test,
- for example, issue @code{ctest -V -R "5FB"}.
- @node Writing Tests, , Running Tests, Testing Framework
- @subsubsection Writing Tests
- To write a new test first decide to which broad category the test belongs:
- baseline or regression. Depending on the category tests are named differently
- baseline tests are prefixed with their type, e.g. @samp{cmd}
- (@pxref{Baseline Test Types} for valid types), whereas regressions are either
- named after the bug id, e.g. @samp{1234.test} or uuid @samp{91416D62.test}.
- In case several test files belong to the same bug number the files by appending
- @code{_X} where @samp{X} is the number of the test, e.g. @samp{1234_1.test},
- @samp{1234_2.test}.
- Baseline Test Types:
- @anchor{Baseline Test Types}
- @table @code
- @item cmd
- Ledger commands like @command{register} or @command{balance}
- @item dir
- Ledger directives like @code{account} or @code{alias}
- @item feat
- Ledger features such as balance assertions in journal file
- @item opt
- Ledger options such as @option{--period} or @option{--format}
- @end table
- A ledger test file contains three sections:
- @enumerate
- @item the journal data used for the test, this can be empty in certain
- scenarios
- @item the ledger command-line options used for the test
- @item the expected output
- @end enumerate
- Ledger has a special command directive for tests, everything between
- @code{test} and @code{end test} is treated like a comment, so every
- Ledger test is automatically a valid Ledger file.
- The test scripts take the remainder of the @code{test} line and use
- it as command-line arguments for ledger, the text enclosed in @code{test}
- and @code{end test} is expected output, for example:
- @smallexample @c input:validate
- ; This is the journal data
- year 2014
- 12/24 (C0d3) Santa Claus
- Assets:Bank ¤ -150,00
- Expenses:Presents
- ; The following line specifies the ledger command-line options for this test and
- ; everything between the next line and `end test` specifies the expected output
- test reg --payee=code
- 14-Dec-24 C0d3 Assets:Bank ¤ -150,00 ¤ -150,00
- 14-Dec-24 C0d3 Expenses:Presents ¤ 150,00 0
- end test
- @end smallexample
- When it is necessary to test for errors printed to @code{stderr} redirect
- the test output by adding @code{->} to the @code{test} line and match the
- expected error text in an @code{__ERROR__} section:
- @smallexample
- 2014/01/01 * Acme Corporation
- Assets:Bank:Checking ¤ 1.000,00
- [Fund:Vacation] ¤ 300,00
- [Fund:Studies] ¤ 600,00
- Income:Salary ¤ -2.000,00
- test reg ->
- __ERROR__
- While parsing file "$FILE", line 5:
- While balancing transaction from "$FILE", lines 1-5:
- > 2014/01/01 * Acme Corporation
- > Assets:Bank:Checking ¤ 1.000,00
- > [Fund:Vacation] ¤ 300,00
- > [Fund:Studies] ¤ 600,00
- > Income:Salary ¤ -2.000,00
- Unbalanced remainder is:
- ¤ -100,00
- Amount to balance against:
- ¤ 1.900,00
- Error: Transaction does not balance
- end test
- @end smallexample
- A special @code{$FILE} variable can be used to match the journal filename
- used during the test.
- To add new tests to the test suite use the rebuild_cache option for the
- build tool you use, for example @code{make rebuild_cache}, now the
- new tests can be run as documented in @ref{Running Tests}.
- @node Major Changes from version 2.6, Example Journal File, Ledger for Developers, Top
- @chapter Major Changes from version 2.6
- The following have been removed from Ledger 3.0:
- @itemize
- @item
- OFX support.
- @item
- GnuCash file import.
- @item
- The option @option{--performance (-g)}.
- @item
- The balance report now defaults to showing all relevant accounts. This
- is the opposite of 2.x. That is, @command{bal} in 3.0 does what @samp{-s
- bal} did in 2.x. To see 2.6 behavior, use @option{--collapse (-n)}
- option in 3.0, like @samp{bal -n}. The @option{--subtotal (-s)} option
- no longer has any effect on balance reports.
- @end itemize
- @noindent
- The following are deprecated in Ledger 3.0:
- @itemize
- @item
- Single character value expressions are deprecated and should be changed
- to the new value expressions available in 3.0
- @item
- The following environment variables have been renamed in Ledger 3.0:
- @table @env
- @item LEDGER
- is now @env{LEDGER_FILE},
- @item LEDGER_INIT
- is now @env{LEDGER_INIT_FILE},
- @item PRICE_HIST
- is now @env{LEDGER_PRICE_DB},
- @item PRICE_EXP
- is now @env{LEDGER_PRICE_EXP}.
- @end table
- @end itemize
- @node Example Journal File, Miscellaneous Notes, Major Changes from version 2.6, Top
- @appendix Example Journal File
- The following journal file is included with the source distribution of
- ledger. It is called @file{drewr3.dat} and exhibits many ledger
- features, include automatic and virtual transactions,
- @smallexample @c input:validate
- ; -*- ledger -*-
- = /^Income/
- (Liabilities:Tithe) 0.12
- ;~ Monthly
- ; Assets:Checking $500.00
- ; Income:Salary
- ;~ Monthly
- ; Expenses:Food $100
- ; Assets
- 2010/12/01 * Checking balance
- Assets:Checking $1,000.00
- Equity:Opening Balances
- 2010/12/20 * Organic Co-op
- Expenses:Food:Groceries $ 37.50 ; [=2011/01/01]
- Expenses:Food:Groceries $ 37.50 ; [=2011/02/01]
- Expenses:Food:Groceries $ 37.50 ; [=2011/03/01]
- Expenses:Food:Groceries $ 37.50 ; [=2011/04/01]
- Expenses:Food:Groceries $ 37.50 ; [=2011/05/01]
- Expenses:Food:Groceries $ 37.50 ; [=2011/06/01]
- Assets:Checking $ -225.00
- 2010/12/28=2011/01/01 Acme Mortgage
- Liabilities:Mortgage:Principal $ 200.00
- Expenses:Interest:Mortgage $ 500.00
- Expenses:Escrow $ 300.00
- Assets:Checking $ -1000.00
- 2011/01/02 Grocery Store
- Expenses:Food:Groceries $ 65.00
- Assets:Checking
- 2011/01/05 Employer
- Assets:Checking $ 2000.00
- Income:Salary
- 2011/01/14 Bank
- ; Regular monthly savings transfer
- Assets:Savings $ 300.00
- Assets:Checking
- 2011/01/19 Grocery Store
- Expenses:Food:Groceries $ 44.00 ; hastag: not block
- Assets:Checking
- 2011/01/25 Bank
- ; Transfer to cover car purchase
- Assets:Checking $ 5,500.00
- Assets:Savings
- ; :nobudget:
- apply tag hastag: true
- apply tag nestedtag: true
- 2011/01/25 Tom's Used Cars
- Expenses:Auto $ 5,500.00
- ; :nobudget:
- Assets:Checking
- 2011/01/27 Book Store
- Expenses:Books $20.00
- Liabilities:MasterCard
- end tag
- 2011/12/01 Sale
- Assets:Checking:Business $ 30.00
- Income:Sales
- end tag
- @end smallexample
- @node Miscellaneous Notes, Concepts Index, Example Journal File, Top
- @appendix Miscellaneous Notes
- Various notes from the discussion list that I haven't incorporated in
- to the main body of the documentation.
- @menu
- * Cookbook::
- @end menu
- @node Cookbook, , Miscellaneous Notes, Miscellaneous Notes
- @section Cookbook
- @menu
- * Invoking Ledger::
- * Ledger Files::
- @end menu
- @node Invoking Ledger, Ledger Files, Cookbook, Cookbook
- @subsection Invoking Ledger
- @smallexample @c command:validate
- $ ledger --group-by "tag('trip')" bal
- @end smallexample
- @c FIXME: The following example fails to validate due to:
- @c While applying is_realzero to :
- @c Error: Cannot determine if an uninitialized value is really zero
- @c @smallexample @c command:validate
- @c $ ledger reg --sort "tag('foo')" %foo
- @c @end smallexample
- @smallexample @c command:validate
- $ ledger cleared VWCU NFCU Tithe Misentry
- @end smallexample
- @smallexample @c command:validate
- $ ledger register Joint --uncleared
- @end smallexample
- @smallexample @c command:validate
- $ ledger register Checking --sort d -d 'd>[2011/04/01]' until 2011/05/25
- @end smallexample
- @node Ledger Files, , Invoking Ledger, Cookbook
- @subsection Ledger Files
- @smallexample @c input:validate
- = /^Income:Taxable/
- (Liabilities:Tithe Owed) -0.1
- = /Noah/
- (Liabilities:Tithe Owed) -0.1
- = /Jonah/
- (Liabilities:Tithe Owed) -0.1
- = /Tithe/
- (Liabilities:Tithe Owed) -1.0
- @end smallexample
- @node Concepts Index, Commands & Options Index, Miscellaneous Notes, Top
- @unnumbered Concepts Index
- @printindex cp
- @node Commands & Options Index, , Concepts Index, Top
- @unnumbered Commands & Options Index
- @printindex fn
- @bye
|