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

本文介绍如何在Windows环境下,利用C#和开源框架Lean进行量化策略的本地化部署,包括使用DockerDesktop简化环境配置,以及通过Panoptes构建GUI前端。文章还展示了如何测试策略功能,如数据订阅、订单传输和图表显示。
摘要由CSDN通过智能技术生成

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);
            }
        }
    }
}
  • 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)

一些效果图

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

补充技术细节

补充1

  • 待续…
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值