feat: 完成模拟交易闭环、App 与 A 股行情接入
Checks / verify (push) Failing after 9m52s

统一单入口 Go 工程与前端依赖目录,增加后台供应商配置、候选审核、计划预算、成交冲正、持仓复盘和站内通知。接入策略版本、Python 回测、可配置 A 股公开行情及 zap 文件轮转日志,补充迁移、契约与验证。
This commit is contained in:
2026-10-08 22:58:52 +08:00
parent bffdb3858b
commit 92329ddce2
145 changed files with 18593 additions and 587 deletions
+55
View File
@@ -0,0 +1,55 @@
import sys, json
from decimal import Decimal
def cents(value):
n = Decimal(value) * 100
if n != n.to_integral_value() or n <= 0:
raise ValueError('invalid price')
return int(n)
def money(value):
return ('-' if value < 0 else '') + str(abs(value)//100) + '.' + str(abs(value)%100).zfill(2)
def run(data):
p = data['parameters']
bars = data['bars']
cash = int(Decimal(data['initial_cash'])*100)
initial = cash
quantity, cost, peak, drawdown, previous = 0, 0, cash, 0, False
trades, equity = [], []
closes = [cents(b['close']) for b in bars]
for i, bar in enumerate(bars):
# Only preceding completed bars generate a signal. Execute at next open.
if i >= p['long_window']:
short = sum(closes[i-p['short_window']:i]) * p['long_window']
long = sum(closes[i-p['long_window']:i]) * p['short_window']
bullish = short > long
open_price = cents(bar['open'])
if bullish and not previous and quantity == 0:
price = (open_price*(10000+p['slippage_bps'])+9999)//10000
unit = p['lot_size']
units = cash*10000//(price*unit*(10000+p['fee_bps']))
quantity = units*unit
gross = quantity*price
fee = (gross*p['fee_bps']+9999)//10000
if quantity:
cash -= gross+fee
cost = gross+fee
trades.append({'date':bar['date'],'side':'BUY','quantity':str(quantity),'price':money(price),'fee':money(fee),'realized_pnl':None})
elif not bullish and previous and quantity:
price = max(1,open_price*(10000-p['slippage_bps'])//10000)
gross = quantity*price
fee = (gross*p['fee_bps']+9999)//10000
cash += gross-fee
trades.append({'date':bar['date'],'side':'SELL','quantity':str(quantity),'price':money(price),'fee':money(fee),'realized_pnl':money(gross-fee-cost)})
quantity, cost = 0, 0
previous = bullish
value = cash+quantity*closes[i]
peak = max(peak,value)
drawdown = max(drawdown,(peak-value)*10000//peak)
equity.append({'date':bar['date'],'equity':money(value)})
final = cash+quantity*closes[-1]
return {'engine_version':'sma_cross_v1','final_equity':money(final),'cash':money(cash),'remaining_quantity':str(quantity),'total_return_bps':(final-initial)*10000//initial,'max_drawdown_bps':drawdown,'trades':trades,'equity_curve':equity,'valuation':'Final close valuation; open positions are not liquidated.'}
if __name__ == '__main__':
print(json.dumps(run(json.load(sys.stdin)),separators=(',',':')))