统一单入口 Go 工程与前端依赖目录,增加后台供应商配置、候选审核、计划预算、成交冲正、持仓复盘和站内通知。接入策略版本、Python 回测、可配置 A 股公开行情及 zap 文件轮转日志,补充迁移、契约与验证。
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
// Package research executes the embedded Python research engine with bounded inputs.
|
||||
package research
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:embed backtest.py
|
||||
var script string
|
||||
|
||||
type Engine struct{ executable string }
|
||||
|
||||
func New(executable string) *Engine { return &Engine{executable} }
|
||||
func (e *Engine) Execute(ctx context.Context, input json.RawMessage) (json.RawMessage, error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, e.executable, "-I", "-c", script)
|
||||
// No application credentials or Python startup configuration reach the child.
|
||||
cmd.Env = []string{"PATH=" + os.Getenv("PATH"), "LANG=en_US.UTF-8"}
|
||||
cmd.Stdin = bytes.NewReader(input)
|
||||
var output boundedBuffer
|
||||
cmd.Stdout = &output
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, errors.New("Python research execution failed; check Python installation and input data")
|
||||
}
|
||||
if !json.Valid(output.Bytes()) {
|
||||
return nil, errors.New("invalid research result")
|
||||
}
|
||||
return json.RawMessage(output.Bytes()), nil
|
||||
}
|
||||
|
||||
type boundedBuffer struct{ bytes.Buffer }
|
||||
|
||||
func (b *boundedBuffer) Write(p []byte) (int, error) {
|
||||
if b.Len()+len(p) > 2<<20 {
|
||||
return 0, errors.New("research output exceeds limit")
|
||||
}
|
||||
return b.Buffer.Write(p)
|
||||
}
|
||||
Reference in New Issue
Block a user