github.com/99MyCql/duffett@v0.1.0/app/strategy/exec.go (about)

     1  package strategy
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"strconv"
     9  	"time"
    10  
    11  	log "github.com/sirupsen/logrus"
    12  
    13  	"github.com/99MyCql/duffett/app/strategy/model"
    14  	"github.com/99MyCql/duffett/pkg"
    15  )
    16  
    17  const (
    18  	codeHeader string = `package main
    19  
    20  import (
    21  	"fmt"
    22  	"math/rand"
    23  	"time"
    24  
    25  	"github.com/99MyCql/duffett/app/data"
    26  	"github.com/99MyCql/duffett/pkg"
    27  )
    28  
    29  func init() {
    30  	pkg.InitConfig("conf.yaml")
    31  	pkg.InitLog(pkg.FatalLevel)
    32  }
    33  `
    34  )
    35  
    36  // ExecStrategy 执行决策
    37  func ExecStrategy(filepath *string, strategyName string, tsCode string) pkg.RspData {
    38  	// 获取决策
    39  	s := model.FindByName(strategyName)
    40  	if s == nil {
    41  		log.Error("错误的决策名:" + strategyName)
    42  		return pkg.ClientErr("错误的决策名")
    43  	}
    44  
    45  	if *filepath == "" {
    46  		// 设置文件路径
    47  		*filepath = "temp/" + strategyName + fmt.Sprintf("%v", time.Now().UnixNano()) + ".go"
    48  
    49  		// 创建go文件并写入代码
    50  		f, err := os.OpenFile(*filepath, os.O_WRONLY|os.O_CREATE, 0666)
    51  		if err != nil {
    52  			log.Error(err)
    53  			return pkg.ServerErr("")
    54  		}
    55  		defer f.Close()
    56  		_, err = f.WriteString(codeHeader + s.Content)
    57  		if err != nil {
    58  			log.Error(err)
    59  			return pkg.ServerErr("")
    60  		}
    61  
    62  	}
    63  
    64  	// 设置执行时间
    65  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    66  	defer cancel()
    67  
    68  	// 格式化导入包
    69  	cmd := exec.CommandContext(ctx, "goimports", "-w", *filepath)
    70  	out, _ := cmd.CombinedOutput()
    71  	log.Debug(string(out))
    72  
    73  	// 运行代码
    74  	cmd = exec.CommandContext(ctx, "go", "run", *filepath)
    75  	stdin, _ := cmd.StdinPipe()
    76  	stdin.Write([]byte(fmt.Sprintln(tsCode))) // 设置输入
    77  	out, err := cmd.CombinedOutput()          // 获取输出
    78  	log.Debug(string(out))
    79  	if err != nil {
    80  		log.Error(err)
    81  		return pkg.ClientErr(string(out))
    82  	}
    83  
    84  	amount, err := strconv.ParseFloat(string(out), 64)
    85  	if err != nil {
    86  		log.Error(err)
    87  		return pkg.ClientErr(string(out))
    88  	}
    89  
    90  	return pkg.SucWithData("", amount)
    91  }
    92  
    93  func execStrategy(strategyName string, tsCode string) (float64, error) {
    94  	code := `func main() {
    95  	var tsCode string
    96  	var ans float64
    97  
    98  	fmt.Scanf("%s", &tsCode)
    99  
   100  	realTime, err := data.GetRealTimeData(tsCode)
   101  	if err != nil {
   102  		fmt.Print(err)
   103  		return
   104  	}
   105  
   106  	today := time.Now()
   107  	yesterday := today.AddDate(0, 0, -1)
   108  	yesterdayData, err := data.GetDailyData(tsCode, yesterday)
   109  	if err != nil {
   110  		fmt.Print(err)
   111  		return
   112  	}
   113  
   114  	if (realTime.CurPrice-yesterdayData.Close)/yesterdayData.Close >= 0.05 {
   115  		ans = -200
   116  	} else if (realTime.CurPrice-yesterdayData.Close)/yesterdayData.Close <= -0.05 {
   117  		ans = 200
   118  	} else {
   119  		ans = 0
   120  	}
   121  	fmt.Print(ans)
   122  }
   123  `
   124  	code = codeHeader + code
   125  
   126  	filepath := "temp/" + strategyName + fmt.Sprintf("%v", time.Now().UnixNano()) + ".go"
   127  
   128  	f, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE, 0666)
   129  	if err != nil {
   130  		log.Error(err)
   131  		return 0, err
   132  	}
   133  	_, err = f.WriteString(code)
   134  	if err != nil {
   135  		log.Error(err)
   136  		return 0, err
   137  	}
   138  
   139  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
   140  	defer cancel()
   141  
   142  	cmd := exec.CommandContext(ctx, "goimports", "-w", filepath)
   143  	out, _ := cmd.CombinedOutput()
   144  	log.Debug(string(out))
   145  
   146  	cmd = exec.CommandContext(ctx, "go", "run", filepath)
   147  	stdin, _ := cmd.StdinPipe()
   148  	stdin.Write([]byte(fmt.Sprintln(tsCode)))
   149  	out, err = cmd.CombinedOutput()
   150  	log.Debug(string(out))
   151  	if err != nil {
   152  		log.Error(err)
   153  		return 0, err
   154  	}
   155  	amount, _ := strconv.ParseFloat(string(out), 64)
   156  
   157  	return amount, nil
   158  }