# -*- coding: utf-8 -*-
"""AI旺财 EA 马丁格尔网格参数建模（本金 60000 USD, XAUUSD）"""
PRICE = 4320.0      # XAUUSD 现货价
CONTRACT = 100.0    # 1手 = 100 盎司
POINT = 0.01        # 1 point = 0.01 美元
EQUITY = 60000.0    # 本金 USD
LEV = 2000.0        # 杠杆
STEP = 0.01         # 手数步进


def ladder(init, mult, n, maxlot=99.0):
    out = []
    v = init
    for _ in range(n):
        v = min(v, maxlot)
        q = round(round(v / STEP) * STEP, 2)
        if q < STEP:
            q = STEP
        out.append(q)
        v = v * mult
    return out


def metrics(init, mult, n, dist_pts, maxlot=99.0, lev=LEV):
    L = ladder(init, mult, n, maxlot)
    d = dist_pts * POINT
    S = sum(L)
    dd = sum(L[i] * CONTRACT * (i * d) for i in range(n))
    return dict(L=L, S=S, dd=dd, d=d,
                span=(n - 1) * d,
                margin=S * CONTRACT * PRICE / lev,
                be=dd / (S * CONTRACT))


def solve_init(mult, n, dist_pts, target_dd, maxlot=99.0):
    lo, hi, best = 0.01, 20.0, 0.01
    for _ in range(60):
        mid = (lo + hi) / 2
        if metrics(mid, mult, n, dist_pts, maxlot)['dd'] <= target_dd:
            best = mid
            lo = mid
        else:
            hi = mid
    return max(0.01, round(best / STEP) * STEP)


def row(label, init, mult, n, dist_pts, maxlot=99.0, tp=0.0):
    m = metrics(init, mult, n, dist_pts, maxlot)
    rebound_tp = (tp + m['dd']) / (m['S'] * CONTRACT) if tp else 0.0
    return (label, init, m['S'], m['dd'], m['dd'] / EQUITY * 100,
            m['span'], m['span'] / PRICE * 100, m['be'], rebound_tp,
            m['margin'], m['margin'] / EQUITY * 100, m['L'])


def show(rows):
    print('%-40s %6s %6s %9s %7s %8s %7s %8s %8s' % (
        '配置', '起手', '满仓手', '浮亏USD', '回撤%', '覆盖USD', '覆盖%', '保本反弹', '止盈反弹'))
    print('-' * 108)
    for r in rows:
        print('%-40s %6.2f %6.2f %9.0f %6.1f%% %8.0f %6.2f%% %8.1f %8.1f' % (
            r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8]))


if __name__ == '__main__':
    print('=' * 108)
    print('基准: XAUUSD %.0f | 本金 %.0f USD | 杠杆 1:%.0f | 1手=100oz | 1point=0.01USD' % (
        PRICE, EQUITY, LEV))
    print('=' * 108)

    print('\n[1] 原版参数搬到 60000 本金 (0.01起手/1.5倍/15单/0.4封顶/2500pt)')
    m0 = metrics(0.01, 1.5, 15, 2500, 0.4)
    print('    阶梯 %s' % ' '.join('%.2f' % x for x in m0['L']))
    print('    满仓 %.2f 手 -> 浮亏 %.0f USD = 本金 %.1f%%  <<< 爆仓' % (
        m0['S'], m0['dd'], m0['dd'] / EQUITY * 100))

    print('\n[2] 回撤目标 10%% (6000 USD) 下的可行起手手数')
    rows = []
    for mult, n, dpt in [(1.5, 15, 2500), (1.5, 12, 4000), (1.4, 12, 4000),
                         (1.3, 12, 4000), (1.3, 10, 5000), (1.25, 12, 5000),
                         (1.25, 15, 4000), (1.2, 15, 4000), (1.3, 15, 4000)]:
        i = solve_init(mult, n, dpt, EQUITY * 0.10)
        rows.append(row('mult=%.2f N=%d 间距%dpt' % (mult, n, dpt), i, mult, n, dpt))
    show(rows)

    print('\n[3] 回撤目标 20%% (12000 USD) 下的可行起手手数')
    rows = []
    for mult, n, dpt in [(1.5, 15, 2500), (1.5, 12, 4000), (1.4, 12, 4000),
                         (1.3, 12, 4000), (1.3, 10, 5000), (1.25, 12, 5000),
                         (1.25, 15, 4000), (1.2, 15, 4000), (1.3, 15, 4000)]:
        i = solve_init(mult, n, dpt, EQUITY * 0.20)
        rows.append(row('mult=%.2f N=%d 间距%dpt' % (mult, n, dpt), i, mult, n, dpt))
    show(rows)

    print('\n[4] 候选方案详细阶梯 (回撤目标 20%%)')
    cands = [
        ('A 保守', 1.25, 12, 4000, EQUITY * 0.10),
        ('B 均衡', 1.3, 12, 4000, EQUITY * 0.20),
        ('C 激进', 1.4, 12, 4000, EQUITY * 0.35),
    ]
    for name, mult, n, dpt, tgt in cands:
        i = solve_init(mult, n, dpt, tgt)
        m = metrics(i, mult, n, dpt)
        print('\n  %s: 起手%.2f mult=%.2f N=%d 间距%dpt' % (name, i, mult, n, dpt))
        print('    阶梯: %s' % ' '.join('%.2f' % x for x in m['L']))
        print('    满仓 %.2f 手 | 浮亏 %.0f (%.1f%%) | 覆盖 %.0f USD (%.2f%%)' % (
            m['S'], m['dd'], m['dd'] / EQUITY * 100, m['span'], m['span'] / PRICE * 100))
        print('    保证金占用 %.0f (%.1f%%) | 保本反弹 %.1f USD' % (
            m['margin'], m['margin'] / EQUITY * 100, m['be']))
        for tp in (300, 600, 1200):
            r = (tp + m['dd']) / (m['S'] * CONTRACT)
            print('    止盈目标 %4d USD -> 需从满仓点反弹 %.1f USD (%.2f%%)' % (
                tp, r, r / PRICE * 100))
