# Crpyto-Quant 加密资产量化从0开始之1下单执行(小白版)

By [new world](https://paragraph.com/@new-world) · 2023-03-13

---

0x0 题记
------

*   **书接上文** 上次一次不是写了一篇《Crpyto-Quant 加密资产量化从0开始之0信号通知》。但是没写如何自动下单交易。既然quant肯定要自动化了。今天就开始如何自动化，由0到1了。
    

0x1 操作
------

*   修改原来信号模块，增加返回`return`数据信号数据`1`和`-1`,注释掉邮件通知。
    

    function getboll() { //信号捕捉模块
        var records = exchange.GetRecords(14400); //获取K线周期为4小时的K线数据
        if (records && records.length > 20) {
            var boll = TA.BOLL(records, 20, 3) //将K线数据转换为boll带数据
            var upLine = boll[0]
            var midLine = boll[1]
            var downLine = boll[2]
            var price = exchange.GetTicker().Last
            if (price > upLine[upLine.length - 1]) { // 对比成交价与boll上轨线
              //注释邮件通  sendtomail("卖出信号", "价格：" + price + "大于BOLL上轨线:" + upLine[upLine.length - 1]) //发送邮件
                Log("卖出信号:" + "价格：" + price + "大于BOLL上轨线:" + upLine[upLine.length - 1] + "@") //打印信号信息
                return -1;  //返回-1 等于返回一个卖出信号
            } else if (price < downLine[downLine.length - 1]) {
               //注释邮件通知 sendtomail("买入信号", "价格：" + price + "小于BOLL下轨线:" + downLine[downLine.length - 1])
                Log("买入信号:" + "价格：" + price + "小于BOLL下轨线:" + downLine[downLine.length - 1] + "@")
                return 1 //返回1 等于返回一个买入信号
            }
        }
        return 0;
    }
    

*   设置一个全局的交易者信息，主要用于设置一些全局信息
    

     let trader = { //初始化 
            direction: 0, //买卖方向标记
            tip: 10, //下单数量
            order: 0,      //下单确认开关
            lever: 20, ////杠杆倍数
            period: "quarter", ////合约类型，这儿设置为季度合约
            long: 35, //止盈点设置,均已usd都是简单计算
            close: -50 //止损点设置
        };
    

*   添加主执行模块
    

    function fox(trader) { //执行主模块
        var id;
        var aount = exchange.GetAccount(); //获取账户信息
        if (trader.order == 1) {           //再次确认下单信号
            if (trader.direction == 1) {   //判断下单方向
                price = getprice("buy", 1);  //获取执行价格，这儿是买二价格，
                if (aount.Stocks > trader.tip / trader.lever) {
                    exchange.SetDirection("buy");
                    id = exchange.Buy(price, trader.tip);
                    
                    if (id != null) {
                        trader.price = price;
                        trader.direction = 0;
                    }
                }
    
            } else if (trader.direction == -1) {
                price = getprice("sell", 1);
                if (aount.Stocks >= trader.tip / trader.lever) {
                    exchange.SetDirection("sell")
                    id = exchange.Sell(price, trader.tip)
                    trader.price = price;
                    trader.direction = 0;
                }
            }
        }
        return trader;
    }
    

*   修改主函数
    

     while (true) {
            if (tm == 60) { //1分钟执行一次
                if(trader.order==0){  //确认无订单状态
                    let signal=getboll(trader); //获取入市信号
                  if(signal!=0){  //确认入市信号
                      trader.order=1   //改变交易下单信息
                      trader.direction=signal;//设置买卖方向
                      trader = fox(trader); //进入执行模块
                  }
                }
              
                tm = 0;
            }
          
            trader = riskcode(trader); //执行风险控制代码
            Sleep(1000); //1秒执行一次
            tm++;
        }
    }
    

0x2 回测
------

*   设置回测信息
    

    /*backtest
    start: 2022-01-01 00:00:00
    end: 2023-03-09 00:00:00
    period: 1h
    basePeriod: 15m
    exchanges: [{"eid":"Futures_HuobiDM","currency":"BTC_USD"}]
    */
    

当然也可以通过系统提供来设置

\*

0x3 后记
------

*   今天展示如何执行订单。本来还计划准备专门写一下动态仓位管理与风控的。可能短期没什么时间。看看以后。。。目前也算由0到1了。
    
*   附录全部源码
    

    /*backtest
    start: 2022-01-01 00:00:00
    end: 2023-03-09 00:00:00
    period: 1h
    basePeriod: 15m
    exchanges: [{"eid":"Futures_HuobiDM","currency":"BTC_USD"}]
    */
    
    
    
    function main() { //主程序入口
    
        let tm = 0; //初始化次数
        let trader = { //初始化 
            direction: 0, //买卖方向标记
            tip: 10, //下单数量
            order: 0, //下单确认开关
            lever: 20, ////杠杆倍数
            period: "quarter", ////合约类型，这儿设置为季度合约
            long: 35, //止盈点设置,均已usd都是简单计算
            close: -50 //止损点设置
    
        };
        exchange.SetContractType(trader.period); //设置合约类型
        exchange.SetMarginLevel(trader.lever); //设置杠杆倍数
        while (true) {
            if (tm == 60) { //1分钟执行一次
                if (trader.order == 0) {
                    let signal = getboll(trader);
                    if (signal != 0) {
                        trader.order = 1
                        trader.direction = signal;
                        trader = fox(trader);
                    }
                }
    
                tm = 0;
            }
    
            trader = riskcode(trader); //执行风险控制代码
            Sleep(1000); //1秒执行一次
            tm++;
        }
    }
    
    
    function getboll() { //信号捕捉模块
        let records = exchange.GetRecords(14400); //获取K线周期为4小时的K线数据
        if (records && records.length > 20) {
            var boll = TA.BOLL(records, 20, 3) //将K线数据转换为boll带数据
            var upLine = boll[0]
            var midLine = boll[1]
            var downLine = boll[2]
            var price = exchange.GetTicker().Last
            if (price > upLine[upLine.length - 1]) { // 对比成交价与boll上轨线
                //注释邮件通  sendtomail("卖出信号", "价格：" + price + "大于BOLL上轨线:" + upLine[upLine.length - 1]) //发送邮件
                Log("卖出信号:" + "价格：" + price + "大于BOLL上轨线:" + upLine[upLine.length - 1] + "@") //打印信号信息
                return -1; //返回-1 等于返回一个卖出信号
            } else if (price < downLine[downLine.length - 1]) {
                //注释邮件通知 sendtomail("买入信号", "价格：" + price + "小于BOLL下轨线:" + downLine[downLine.length - 1])
                Log("买入信号:" + "价格：" + price + "小于BOLL下轨线:" + downLine[downLine.length - 1] + "@")
                return 1 //返回-1 等于返回一个卖出信号
            }
        }
        return 0;
    }
    
    
    
    
    
    function getprice(type, i) { //获取买卖二价
        var price = 0;
        var depth = exchange.GetDepth();
        if (type == "buy") {
            price = depth.Asks[i].Price;
        } else if (type == 'sell') {
            price = depth.Bids[i].Price;
        } else {
            Log('不交易');
        }
    
        return price;
    }
    
    function fox(trader) { //执行主模块
        var id;
        var aount = exchange.GetAccount();
        if (trader.order == 1) {
            if (trader.direction == 1) {
                price = getprice("buy", 1);
                if (aount.Stocks > trader.tip / trader.lever) {
                    exchange.SetDirection("buy");
                    id = exchange.Buy(price, trader.tip);
    
                    if (id != null) {
                        trader.price = price;
                        trader.direction = 0;
                    }
                }
    
            } else if (trader.direction == -1) {
                price = getprice("sell", 1);
                if (aount.Stocks >= trader.tip / trader.lever) {
                    exchange.SetDirection("sell")
                    id = exchange.Sell(price, trader.tip)
                    trader.price = price;
                    trader.direction = 0;
                }
            }
        }
    
        return trader;
    }
    
    
    
    
    
    function usdt(trader) { //usdt转换
        pricedata = {
            long: 0,
            close: 0
        }
        price = getprice("sell", 0);
        pricedata.long = trader.long / price;
        pricedata.close = trader.close / price;
        return pricedata;
    }
    
    
    
    function closeorder(direction, trader) {
        var id;
        var pricedata = usdt(trader);
        if (direction.Profit > pricedata.long || direction.Profit < pricedata.close) {
            if (direction.Type == 0) {
                price = getprice("sell", 0);
                exchange.SetDirection("closebuy");
                id = exchange.Sell(price, trader.tip);
                if (id != null) {
                    trader.order = 0;
                } else {
                    price = getprice("sell", 0);
                    id = exchange.Sell(price, trader.tip);
                }
    
            } else if (direction.Type == 1) {
                price = getprice("buy", 0);
                exchange.SetDirection("closesell");
                id = exchange.Buy(price, trader.tip);
                if (id != null) {
                    trader.order = 0;
                } else {
                    price = getprice("buy", 0);
                    id = exchange.Buy(price, trader.tip);
                }
            }
            Log(direction.Profit);
        }
    }
    
    function riskcode(trader) {
        var position = exchange.GetPosition();
        if (position.length >= 1) {
            for (var i = 0; i < position.length; i++) {
                closeorder(position[i], trader);
            }
        }
        return trader;
    }

---

*Originally published on [new world](https://paragraph.com/@new-world/crpyto-quant-0-1)*
