当前位置:   article > 正文

Windows环境联合开发:Docker Desktop QuantConnect Lean后端 & Panoptes GUI前端_quantconnect部署

quantconnect部署

Windows环境下离线本地化一个功能完整、性能强大的量化框架。
去bilibili看效果

本地化部署动机

  • Python运行太慢,C++开发效率太低,C#兼顾开发效率和运行性能!
  • 跟QuantConnect的Lean框架比,其他现有的、开源的量化框架,个人认为在功能上、性能上等等都和Lean有些差距!
  • Lean开源,但是缺失GUI前端,QuantConnect虽然提供了WEB GUI前端,但收费!
  • 量化平台本地化可以保护私有策略!
  • 真实金融数据获取也很贵!

框架特征

  • 以QuantConnect的开源框架Lean为核心量化回测、交易框架后端(使用Docker Desktop部署,免去开发环境、运行环境复杂配置);
  • Panoptes为量化回测、交易框架前端(基于Avalonia,跨Windows、Linux等平台);
  • 证券基础数据、基本面数据可随机生成(假数据,日常测试用),或者国信iQuant等第三方平台免费获取数据到本地再转换导入(真实数据,验证策略);

测试策略aaa.cs

测试功能点

  • 测试订阅数据;
  • 测试订单数据传输;
  • 测试图表数据传输;
  • C#测试策略
using System.Collections.Generic;
using QuantConnect.Data;
using QuantConnect.Interfaces;
using System;


namespace QuantConnect.Algorithm.CSharp
{
    public class aaa : QCAlgorithm
    {
        private decimal _fastMa;
        private decimal _slowMa;
        private decimal _lastPrice;
        private DateTime _resample;
        private TimeSpan _resamplePeriod;
        private readonly DateTime _startDate = new DateTime(2023, 10, 7);
        private readonly DateTime _endDate = new DateTime(2023, 11, 11);
        private Symbol symbol;

        public override void Initialize()
        {
            //本地已经生成stk000000~stk000999的1998~2024的日线数据
            SetStartDate(2023, 10, 07);
            SetEndDate(2023, 11, 11);
            SetCash(100000);
            //订阅数据
            symbol = AddEquity("stk000001", Resolution.Daily).Symbol;
            AddEquity("stk000000", Resolution.Daily);
            //设置基础资产,用来算一些指标用到
            SetBenchmark("stk000000");
            //图表初始化
            var avgCross = new Chart("Strategy Equity");
            var fastMa = new Series("FastMA", SeriesType.Line, 1);
            var slowMa = new Series("SlowMA", SeriesType.Line, 1);
            avgCross.AddSeries(fastMa);
            avgCross.AddSeries(slowMa);
            AddChart(avgCross);
            _resamplePeriod = TimeSpan.FromMinutes((_endDate - _startDate).TotalMinutes / 2000);
        }

        public override void OnData(Slice slice)
        {
            //测试Debug的通信
            Debug(slice.Bars["stk000001"].Open.ToString("F2"));
            //测试Order的通信
            if (!Portfolio.Invested)
            {
                SetHoldings(symbol, 1);
                Debug("Purchased Stock");
            }
            //测试Chart的通信
            _lastPrice = slice["stk000001"].Close;
            if (_fastMa == 0) _fastMa = _lastPrice;
            if (_slowMa == 0) _slowMa = _lastPrice;
            _fastMa = (0.01m * _lastPrice) + (0.99m * _fastMa);
            _slowMa = (0.001m * _lastPrice) + (0.999m * _slowMa);
            if (Time > _resample)
            {
                _resample = Time.Add(_resamplePeriod);
                Plot("Strategy Equity", "FastMA", _fastMa);
                Plot("Strategy Equity", "SlowMA", _slowMa);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • Python测试策略
from AlgorithmImports import *


class aaa(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2022,1,1)
        self.SetEndDate(2023,1,1)
        self.SetCash(100000)

        stk000001 = self.AddEquity("stk000001", Resolution.Daily).Symbol

        stockPlot = Chart("Trade Plot")
        stockPlot.AddSeries(Series("Buy", SeriesType.Scatter, 0))
        stockPlot.AddSeries(Series("Sell", SeriesType.Scatter, 0))
        stockPlot.AddSeries(Series("Price", SeriesType.Line, 0))
        self.AddChart(stockPlot)

        avgCross = Chart("Average Cross")
        avgCross.AddSeries(Series("FastMA", SeriesType.Line, 0))
        avgCross.AddSeries(Series("SlowMA", SeriesType.Line, 0))
        self.AddChart(avgCross)

        weeklySpyPlot = Chart("Weekly SPY")
        spyCandlesticks = CandlestickSeries("SPY")
        weeklySpyPlot.AddSeries(spyCandlesticks)
        self.AddChart(weeklySpyPlot)

        self.Consolidate(stk000001, Calendar.Weekly, lambda bar: self.Plot("Weekly SPY", "SPY", bar))

        self.fastMA = 0
        self.slowMA = 0
        self.lastPrice = 0
        self.resample = datetime.min
        self.resamplePeriod = (self.EndDate - self.StartDate) / 2000

    def OnData(self, slice):
        if slice["stk000001"] is None: return

        self.lastPrice = slice["stk000001"].Close
        if self.fastMA == 0: self.fastMA = self.lastPrice
        if self.slowMA == 0: self.slowMA = self.lastPrice
        self.fastMA = (0.01 * self.lastPrice) + (0.99 * self.fastMA)
        self.slowMA = (0.001 * self.lastPrice) + (0.999 * self.slowMA)


        if self.Time > self.resample:
            self.resample = self.Time  + self.resamplePeriod
            self.Plot("Average Cross", "FastMA", self.fastMA)
            self.Plot("Average Cross", "SlowMA", self.slowMA)

        # On the 5th days when not invested buy:
        if not self.Portfolio.Invested and self.Time.day % 13 == 0:
        	self.Order("stk000001", (int)(self.Portfolio.MarginRemaining / self.lastPrice))
        	self.Plot("Trade Plot", "Buy", self.lastPrice)
        elif self.Time.day % 21 == 0 and self.Portfolio.Invested:
            self.Plot("Trade Plot", "Sell", self.lastPrice)
            self.Liquidate()

    def OnEndOfDay(self, symbol):
       #Log the end of day prices:
       self.Plot("Trade Plot", "Price", self.lastPrice)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

一些效果图

  • VSCode启动的二次修改的镜像quantconnect/research:dockerdesktop;
    在这里插入图片描述
  • 运行策略后等待TCP客户端连接;
    在这里插入图片描述
  • 打开经过二次修改匹配Lean版本的Panoptes显示结果,Debug数据、图表数据、订单数据均正常接收显示;
    在这里插入图片描述
    在这里插入图片描述
  • 运行Python策略效果;
    在这里插入图片描述
    在这里插入图片描述

补充技术细节

补充1

  • 待续…
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/840166
推荐阅读
相关标签
  

闽ICP备14008679号