起因是我跟 ChatGPT 对话问他作为一个新手应该怎样进行投资几记录,一段时间的交流之后我们确定了对于新手来说采用简要记录法是最直观和利于执行的方式,
简言之,作为定投性投资者,不频繁操作,只关心整体结果,定期更新一次资产的用户,关心的核心功能是现金流的投入/转出,市值变化和收益计算。
然后我又问 作为一个程序员是否有必要自己开发一个工具来记录
没错,ChatGPT 果断的否决了我的这个问题,因为无论是时间成本或者是最初的记录目的都不适合自己去开发一个工具, 并且给出了方案使用 Excel 或者 Notion 之类现成的工具就完全能够满足所有的需求。
虽然但是,又问到: "你可以帮我设计一个 DSL 语言来记录吗?因为我想让记录这件事本身看起来很酷" 然后就是一段时间的 PUA ,终于确定了这套 DSL 的 EBNF ,很简单,但是我自己用起来起来感受确实很酷 :)
# 顶层结构
<program> ::= <statement>*
<statement> ::= <record> | <plan> | <define> | <portfolio>
# 记录语句
<record> ::= <date> <action> <details> [<note>]
# 投资计划(简化版)
<plan> ::= "PLAN" <string> <plan_body> "END"
<plan_body> ::= <plan_rule>*
<plan_rule> ::= <schedule> | <start_date> | <end_date>
<schedule> ::= "SCHEDULE" <frequency> <amount> <unit> "INTO" <symbol>
<start_date> ::= "START" <date>
<end_date> ::= "END_DATE" <date>
<frequency> ::= "DAILY" | "WEEKLY" | "MONTHLY" | "QUARTERLY" | "YEARLY"
# 定义元信息
<define> ::= "DEFINE" <symbol> <define_body> "END"
<define_body> ::= [ <alias> ] [ <target_return> ]
<alias> ::= "ALIAS" <string>
<target_return>::= "TARGET" "RETURN" <number>
# 定义组合
<portfolio> ::= "PORTFOLIO" <string> <portfolio_body> "END"
<portfolio_body> ::= <symbols> [ <target_return> ]
<symbols> ::= "ASSETS" <symbol_list>
<symbol_list> ::= <symbol> { "," <symbol> }
# 基础元素
<date> ::= <year> "-" <month> "-" <day>
<action> ::= "TRADE" | "MARK"
<details> ::= <trade_details> | <mark_details>
<trade_details>::= <symbol> <signed_amount> <unit> ["@" <number>]
<mark_details> ::= <symbol> "VALUE" <number> <unit>
# 通用定义
<amount> ::= <number> | "ALL"
<signed_amount>::= ("+" | "-")? <number>
<unit> ::= <identifier>
<symbol> ::= <identifier> ":" <identifier>
<note> ::= "NOTE" <string>
# 基础类型
<identifier> ::= [A-Z][A-Z0-9_]*
<number> ::= [0-9]+ ("." [0-9]+)?
<string> ::= '"' [^"]* '"'
# 日期组件
<year> ::= [0-9]{4}
<month> ::= [0-9]{2}
<day> ::= [0-9]{2}
# 完整示例
2024-01-02 TRADE ETF:510300 +5000 CNY @ 4.56
2024-01-05 TRADE ETF:510300 +3000 CNY @ 4.62
2024-01-15 MARK ETF:510300 VALUE 8800 CNY
2024-02-01 TRADE ETF:510300 +6000 CNY @ 4.32
2024-02-15 TRADE ETF:159915 -1000 CNY @ 2.58 # 转出部分
2024-02-29 MARK ETF:510300 VALUE 22800 CNY
2024-02-29 MARK ETF:159915 VALUE 3600 CNY
PLAN "分散投资计划"
SCHEDULE MONTHLY 2500 CNY INTO ETF:510300
SCHEDULE MONTHLY 1500 CNY INTO ETF:159915
START 2024-03-01
END
DEFINE ETF:510300
ALIAS "沪深 300ETF"
TARGET RETURN 0.09
END
DEFINE ETF:159915
ALIAS "创业板 ETF"
TARGET RETURN 0.10
END
# 创建组合
PORTFOLIO "ETF 长期投资"
ASSETS ETF:510300, ETF:159915
TARGET RETURN 0.09
END
最后我又让 Claude Code 实现了这个 DSL ,并且提供了一个简单的计算引擎 https://github.com/lneoe/cashly
这期间过程很有趣,并且期间还是实现了一个 iOS 的版本,也是我完全利用 Claude Code 实现了 iOS 版本的解析器和计算引擎,并且提供了一个 dashboard 提供数据展示,都很有趣。
这两个都不是我熟悉的语言,但即便我最擅长的 golang ,完整的实现这个解释器和计算引擎(包括单元测试用例)我估计也要 3-5 天才能完成。vibe coding 真是帮了大忙,几分钟就能有了一个最基础的可运行版本。
你也可以自行尝试,根据自己的需求开发自己愉悦自己的工具。
另外,正经的投资记录我其实用的有知有行,不定期的(通常几周周或者一个月)更新一次资产