微信支付的策略是基于最后一笔,而支付宝的支付顺序总是瞎搞,无论是自动顺序支付和系统自动匹配,带着明显的平台倾向性。这些都不是我想要的结果。
我决定自己设计一个时间序列信用卡消费策略,完成每一笔信用卡支付。
形式逻辑和定义
時間序列:是一組按照時間發生先後順序進行排列的數據點序列。
时间序列对象:基于时间序列的程序语言对象。时间必须是第一成员。
例如:
1
2
3
4
5
6
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
时间序列函数:基于时间序列的程序语言函数。时间(或者时间序列对象)必须是第一参数成员。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
//资源池减一
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
// Cards 从本地文件加载信用卡信息,格式是每行 "银行 账单日/最后还款日"。如“农业银行 1/26”
func (z Zeusro) Cards(t time.Time) []Card {
//省略
}
时间序列不动点:信用卡账单日的第二天。
账单日第二天消费策略:在信用卡账单日的第二天信用卡消费策略。
最大交易折扣交易策略:每一笔信用卡支付选取折扣金额最大的交易途径的消费策略。
基本类型建模
信用卡、交易、交易策略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Card struct {
Bank string //金融机构
BillingDate time.Time //账单日
LastDate time.Time //最后还款日
}
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
type Policy interface {
Match(d Deal) bool
Name() string
MVP(d Deal) Policy
}
基于交易金额的二分算法
信用卡消费是一种延长应付账款的消费。单次交易的交易费用(1%左右)由商家承担。 而从消费者角度考虑,申请多张信用卡,并设置不同的账单日,就相当于循环账期,形成个人的“永续债”。
小额消费主要以薅银行羊毛为主。比如农业银行的18-0.3,浦发银行的16-0.01,广发银行的n-0.01。个人感受是1000元以上的消费,以账单日第二天消费为宜——即尽量在信用卡账单日的第二天消费,为最佳时序不动点。
因此总的入口算法,以消费金额,使用二分法消费:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (z Zeusro) Pay(deals []Deal) []Deal {
//follow the rule and find the best policy
discount := NewDiscountPolicys(DefaultDiscountPolicys)
for i, deal := range deals {
if deal.Money > SmallMoney {
//账单日第二天消费策略 BillingDatePolicy
policy1 := NewBillingDatePolicy(z.Cards(deal.t))
mvp := policy1.MVP(deal)
best := mvp.BestCard
deals[i].Payment = best
deals[i].policy = policy1.Name()
} else {
//最大交易折扣交易策略 DiscountPolicys
mvp := discount.MVP(deal)
card := Card{Bank: mvp.Bank}
deals[i].Payment = card
deals[i].policy = mvp.Name()
}
}
return deals
}
账单日第二天消费策略
基本交易倾向是遍历所有信用卡,尽量接近账单第二日交易。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p BillingDatePolicy) MVP(d Deal) BillingDatePolicy {
if len(p.cards) == 0 {
return p
}
now := d.t
var bestCard *Card
var bestDelta time.Duration = time.Hour * 24 * 31 // 极大值
for i := range p.cards {
c := &p.cards[i]
delta := now.Sub(c.BillingDate.AddDate(0, 0, 1))
if delta > 0 && delta < bestDelta {
bestDelta = delta
bestCard = c
}
}
if bestCard != nil {
p.BestCard = *bestCard
}
return p
}
最大交易折扣交易策略
也叫薅羊毛算法。这个算法很简单,就是哪里有钱去哪里。以农业银行来说,参加每月活动报名之后,日消费第一笔18元减0.3元,浦发银行需要16元,以此类推。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
//资源池减一
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
每天0.3元,我要薅到农行倒闭

WeChat Pay’s strategy is based on the last transaction, while Alipay’s payment order is always chaotic. Whether it is automatic payment order or system auto‑matching, the platform bias is obvious. None of these behaviors are what I want.
I decided to design my own time‑series credit‑card consumption strategy to control every single credit‑card payment.
Formal Logic and Definitions
Time series: a sequence of data points arranged according to the order in which they occur over time.
Time‑series object: a programming‑language object based on a time series. Time must be the first member.
Example:
1
2
3
4
5
6
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
Time‑series function: a programming‑language function based on a time series. Time (or a time‑series object) must be the first parameter.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
// reduce resource pool
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
// Cards loads credit‑card information from a local file.
// Format: each line is "Bank BillingDate/LastDate".
// Example: "AgriculturalBank 1/26"
func (z Zeusro) Cards(t time.Time) []Card {
// omitted
}
Time‑series fixed point: the second day after a credit card’s billing date.
Billing‑date‑plus‑one strategy: a credit‑card spending strategy that executes on the day after the billing date.
Maximum‑discount transaction strategy: for each transaction, choose the payment method that yields the highest discount.
Basic Type Modeling
Credit cards, transactions, and transaction strategies.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Card struct {
Bank string // financial institution
BillingDate time.Time // billing date
LastDate time.Time // last repayment date
}
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
type Policy interface {
Match(d Deal) bool
Name() string
MVP(d Deal) Policy
}
Binary‑Search Algorithm Based on Transaction Amount
Credit‑card spending is a way to extend accounts payable. The transaction fee (around 1%) is paid by the merchant.
From the consumer’s perspective, applying for multiple credit cards with different billing dates effectively forms a rotating credit cycle — a kind of personal “perpetual bond.”
Small transactions are mainly used to farm bank rewards. For example, Agricultural Bank offers 18 yuan − 0.3 yuan for the day’s first payment after activation; SPD Bank has 16 yuan − 0.01 yuan; GF Bank has n − 0.01 yuan, etc.
Based on personal experience, for payments over 1000 yuan, the best timing is the second day after the billing date — the optimal time‑series fixed point.
Therefore, the top‑level algorithm uses a binary decision on the transaction amount:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (z Zeusro) Pay(deals []Deal) []Deal {
// follow the rule and find the best policy
discount := NewDiscountPolicys(DefaultDiscountPolicys)
for i, deal := range deals {
if deal.Money > SmallMoney {
// BillingDatePolicy: spend on the day after billing date
policy1 := NewBillingDatePolicy(z.Cards(deal.t))
mvp := policy1.MVP(deal)
best := mvp.BestCard
deals[i].Payment = best
deals[i].policy = policy1.Name()
} else {
// Maximum discount strategy: go wherever the discount is highest
mvp := discount.MVP(deal)
card := Card{Bank: mvp.Bank}
deals[i].Payment = card
deals[i].policy = mvp.Name()
}
}
return deals
}
Billing‑Date‑Plus‑One Strategy
The fundamental tendency is to iterate over all credit cards and choose the one whose billing‑date‑plus‑one is closest.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p BillingDatePolicy) MVP(d Deal) BillingDatePolicy {
if len(p.cards) == 0 {
return p
}
now := d.t
var bestCard *Card
var bestDelta time.Duration = time.Hour * 24 * 31 // large initial value
for i := range p.cards {
c := &p.cards[i]
delta := now.Sub(c.BillingDate.AddDate(0, 0, 1))
if delta > 0 && delta < bestDelta {
bestDelta = delta
bestCard = c
}
}
if bestCard != nil {
p.BestCard = *bestCard
}
return p
}
Maximum‑Discount Transaction Strategy
Also called the “reward‑farming algorithm.” It is simple: follow the discount.
For example, with Agricultural Bank, after registering for the monthly activity, the first daily consumption of 18 yuan gives a 0.3 yuan discount; SPD Bank requires 16 yuan; GF Bank uses n − 0.01, and so on.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
// reduce resource pool
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
The complete algorithm is in my self‑implemented OOOS.
0.3 Yuan per Day — I Will Farm Until Agricultural Bank Collapses

WeChat Pay の戦略は「最後の一筆」に基づいていますが、Alipay の支払順序は常に混乱しており、自動順序決済やシステム自動マッチングにおいても明らかなプラットフォーム側のバイアスが存在します。これらは私が望む結果ではありません。
そこで私は、自分自身で時間系列に基づくクレジットカード消費戦略を設計し、すべてのクレジットカード決済をコントロールすることにしました。
形式論理と定義
時間序列(Time Series):時間の発生順に並べられたデータ点の集合。
時間序列オブジェクト:時間系列に基づくプログラミング言語のオブジェクト。時間は必ず最初のメンバーであること。
例:
1
2
3
4
5
6
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
時間系列関数(Time-series function):時間系列に基づく関数。時間(または時間系列オブジェクト)が必ず最初の引数である。
例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
//資源プールを1減らす
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
// Cards はローカルファイルからクレジットカード情報を読み込む。
// フォーマット:1行につき「銀行名 账单日/最後還款日」。例:「农业银行 1/26」
func (z Zeusro) Cards(t time.Time) []Card {
//省略
}
時間系列の不動点:クレジットカードの「账单日(締め日)の翌日」。
账单日翌日消費戦略:クレジットカードの締め日の翌日に消費する戦略。
最大割引消費戦略:各取引に対して最も割引額が大きい支払方法を選択する戦略。
基本タイプモデリング
クレジットカード、取引、取引戦略の定義。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Card struct {
Bank string //金融機関
BillingDate time.Time //账单日(締め日)
LastDate time.Time //最後還款日(返済期限)
}
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
type Policy interface {
Match(d Deal) bool
Name() string
MVP(d Deal) Policy
}
取引金額に基づく二分アルゴリズム
クレジットカードの消費は「应付账款(未払金)」を延長する行為と言えます。1% 前後の手数料は店舗側が負担します。
消費者の視点では、複数のクレジットカードを申し込み、異なる账单日を設定することで、回転する支払サイクルを作り出し、個人の「永続債(Perpetual bond)」のような仕組みを形成できます。
小額消費は主に「銀行のキャンペーンを最大限利用する」目的で行います。例えば:
- 农业银行:18 元 − 0.3 元
- 浦发银行:16 元 − 0.01 元
- 广发银行:n − 0.01 元
そして、私の実感では、1000 元を超える支払いについては、账单日翌日の消費が最適です。すなわち「時間系列の最適不動点」。
したがって上位アルゴリズムは、金額によって二分する方式を採用します:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (z Zeusro) Pay(deals []Deal) []Deal {
//follow the rule and find the best policy
discount := NewDiscountPolicys(DefaultDiscountPolicys)
for i, deal := range deals {
if deal.Money > SmallMoney {
//账单日翌日消費戦略 BillingDatePolicy
policy1 := NewBillingDatePolicy(z.Cards(deal.t))
mvp := policy1.MVP(deal)
best := mvp.BestCard
deals[i].Payment = best
deals[i].policy = policy1.Name()
} else {
//最大取引割引戦略 DiscountPolicys
mvp := discount.MVP(deal)
card := Card{Bank: mvp.Bank}
deals[i].Payment = card
deals[i].policy = mvp.Name()
}
}
return deals
}
账单日翌日消費戦略
基本方針は「全カードを走査し、账单日翌日に最も近いタイミングで決済する」ことです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p BillingDatePolicy) MVP(d Deal) BillingDatePolicy {
if len(p.cards) == 0 {
return p
}
now := d.t
var bestCard *Card
var bestDelta time.Duration = time.Hour * 24 * 31 // 極大値
for i := range p.cards {
c := &p.cards[i]
delta := now.Sub(c.BillingDate.AddDate(0, 0, 1))
if delta > 0 && delta < bestDelta {
bestDelta = delta
bestCard = c
}
}
if bestCard != nil {
p.BestCard = *bestCard
}
return p
}
最大割引取引戦略
別名「羊毛狩り(ポイント稼ぎ)アルゴリズム」。
やることは単純で、「割引があるところに行く」だけです。
农业银行の例:
- 月次キャンペーン登録後、1日の最初の 18 元消費:0.3 元割引
- 浦发銀行:16 元
- 以此类推(などなど)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
//資源プールを1減らす
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
1日 0.3 元、私は農業銀行が倒れるまで取り続ける

Стратегия WeChat Pay основана на «последней транзакции», тогда как порядок платежей Alipay всегда хаотичен. Автоматическое списание и системное сопоставление демонстрируют явный платформенный перекос. Всё это не соответствует тому, что мне нужно.
Поэтому я решил разработать собственную стратегию расходования кредитных карт на основе временных рядов, чтобы контролировать каждую операцию.
Формальная логика и определения
Временной ряд — последовательность точек данных, упорядоченных по времени.
Объект временного ряда — объект языка программирования, основанный на временном ряде. Время обязательно является первым полем.
Пример:
1
2
3
4
5
6
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
Функция временного ряда — это функция, основанная на временных данных. Параметр времени (или объект временного ряда) должен быть первым параметром.
Например:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
// уменьшение ресурсного пула
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
// Cards загружает информацию о кредитных картах из локального файла.
// Формат: каждая строка — «банк дата_биллинга/дата_погашения».
// Например: «ABC 1/26»
func (z Zeusro) Cards(t time.Time) []Card {
// опущено
}
Неподвижная точка временного ряда — второй день после даты выписки кредитной карты.
Стратегия расходования на второй день после даты выписки — стратегия использования кредитных карт на следующий день после даты выписки.
Стратегия максимальной скидки — для каждой операции выбирается способ оплаты с наибольшей скидкой.
Моделирование базовых типов
Кредитные карты, транзакции, стратегии транзакций.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Card struct {
Bank string // финансовая организация
BillingDate time.Time // дата выписки
LastDate time.Time // крайний срок погашения
}
type Deal struct {
t time.Time
Money float32
policy string
Payment Card
}
type Policy interface {
Match(d Deal) bool
Name() string
MVP(d Deal) Policy
}
Бинарный алгоритм на основе суммы транзакции
Расходование по кредитной карте — это форма продления кредиторской задолженности. Комиссия за транзакцию (около 1%) оплачивается продавцом.
С точки зрения потребителя, оформление нескольких кредитных карт с разными датами выписки создаёт цикл вращающихся долгов — персональный «вечный долг» (perpetual bond).
Мелкие покупки в основном используются для получения бонусов банков. Например:
- ABC: 18 – 0.3
- SPDB: 16 – 0.01
- CGB: n – 0.01
По моему опыту, для расходов более 1000 юаней оптимально платить на второй день после даты выписки — это оптимальная неподвижная точка временного ряда.
Поэтому общий алгоритм определяет стратегию на основе бинарного разбиения суммы:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func (z Zeusro) Pay(deals []Deal) []Deal {
// follow the rule and find the best policy
discount := NewDiscountPolicys(DefaultDiscountPolicys)
for i, deal := range deals {
if deal.Money > SmallMoney {
// стратегия расходования на второй день после биллинга
policy1 := NewBillingDatePolicy(z.Cards(deal.t))
mvp := policy1.MVP(deal)
best := mvp.BestCard
deals[i].Payment = best
deals[i].policy = policy1.Name()
} else {
// стратегия максимальной скидки
mvp := discount.MVP(deal)
card := Card{Bank: mvp.Bank}
deals[i].Payment = card
deals[i].policy = mvp.Name()
}
}
return deals
}
Стратегия расходования на второй день после даты выписки
Основной принцип — перебрать все кредитные карты и выбрать ту, чья дата «выписка + 1 день» наиболее близка к текущему времени.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p BillingDatePolicy) MVP(d Deal) BillingDatePolicy {
if len(p.cards) == 0 {
return p
}
now := d.t
var bestCard *Card
var bestDelta time.Duration = time.Hour * 24 * 31 // большое значение
for i := range p.cards {
c := &p.cards[i]
delta := now.Sub(c.BillingDate.AddDate(0, 0, 1))
if delta > 0 && delta < bestDelta {
bestDelta = delta
bestCard = c
}
}
if bestCard != nil {
p.BestCard = *bestCard
}
return p
}
Стратегия максимальной скидки
Называется также алгоритмом «снятия сливок» — идти туда, где дают выгоду.
Например, в ABC после регистрации в ежемесячной акции первая ежедневная операция на 18 юаней даёт скидку 0.3 юаня.
SPDB — 16 юаней.
И так далее.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func (p *DiscountPolicys) MVP(d Deal) DiscountPolicy {
var best DiscountPolicy
var maxDiscount float32 = 0
for _, policy := range p.Resource {
if !policy.Match(d) {
continue
}
if policy.Discount >= maxDiscount {
continue
}
best = policy
if best.N > 0 {
maxDiscount = best.Discount
// уменьшение ресурсного пула
best.N--
}
}
if len(best.Bank) > 0 {
p.Resource[best.Bank] = best
}
return best
}
Полный алгоритм находится в моём собственном проекте OOOS。
Каждый день 0.3 юаня — буду получать, пока ABC не развалится
