利用Warensoft Stock Service编写高频交易软件--DEMO

摘要:
目前WarensoftStockService已经实现了C#版本的客户端驱动,可以直接在Nuget上搜索Warensoft并安装。工程目录下图所示:添加Nuget引用包首先,为Warensoft.StockApp共享库添加Oxyplot引用,如下图所示:然后再分别安装Warensoft.EntLib.Common,Warensoft.EntLib.StockServiceClient,如下图所示:然后为Warensoft.StockApp.Droid添加OxyPlot的NuGet引用,如下所示:然后在Android的MainActivity中加入平台注册代码:OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();MainActivity.cs的代码如下所示:protectedoverridevoidOnCreate{TabLayoutResource=Resource.Layout.Tabbar;ToolbarResource=Resource.Layout.Toolbar;OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();base.OnCreate;global::Xamarin.Forms.Forms.Init;LoadApplication;}实现主窗口主界面的实现采用MVVM模式来实现,关于MVVM的讲解,网上应该有很多了,后面的文章中,我会把我自己的理解写出来,让大家分享。

利用Warensoft Stock Service编写高频交易软件

无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法。本文以SAR算法的实现过程为例,为大家说明如何使用Warensoft Stock Service来实现高频交易软件的快速开发。

目前WarensoftStockService已经实现了C# 版本的客户端驱动,可以直接在Nuget上搜索Warensoft并安装。客户端驱动已经编译为跨平台.net standard1.6版本,可以在桌面应用(WPFWinform)、Xamarin手机应用(WPAndroidIOS)、Webasp.net,asp.net core)中应用,操作系统可以是WindowAndroidIOSIMACLinux

下面将以Android为例(注:本Demo可以直接平移到WPF中),说明SAR指标的实现过程,其他指标计算的综合应用,在其他文章中会专门讲解。

  1. 软件环境说明

IDE

VS2017 RC

客户端

Android4.4

服务器环境

Ubuntu16

客户端运行环境

Xamarin.Forms

客户端图形组件

Oxyplot

  1. 建立一个Xamarin.Forms手机App

这里选择基于XAMLApp,注意共享库使用PCL

利用Warensoft Stock Service编写高频交易软件--DEMO第1张

利用Warensoft Stock Service编写高频交易软件--DEMO第2张

工程目录下图所示:

利用Warensoft Stock Service编写高频交易软件--DEMO第3张

  1. 添加Nuget引用包

首先,为Warensoft.StockApp共享库添加Oxyplot引用(此处可能需要科学上网),如下图所示:

利用Warensoft Stock Service编写高频交易软件--DEMO第4张

然后再分别安装Warensoft.EntLib.Common,Warensoft.EntLib.StockServiceClient,如下图所示:

利用Warensoft Stock Service编写高频交易软件--DEMO第5张

然后为Warensoft.StockApp.Droid添加OxyPlotNuGet引用,如下所示:

利用Warensoft Stock Service编写高频交易软件--DEMO第6张

然后在AndroidMainActivity中加入平台注册代码:

OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();

MainActivity.cs的代码如下所示:

protected override voidOnCreate(Bundle bundle)
        {
            TabLayoutResource =Resource.Layout.Tabbar;
            ToolbarResource =Resource.Layout.Toolbar;
            OxyPlot.Xamarin.Forms.Platform.Android.PlotViewRenderer.Init();
            base.OnCreate(bundle);
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(newApp());
        }
  1. 实现主窗口

主界面的实现采用MVVM模式来实现,关于MVVM的讲解,网上应该有很多了,后面的文章中,我会把我自己的理解写出来,让大家分享。本DEMOMVVM框架已经集成在了Warensoft.EntLib.Common中,使用起来很简单。

第一步:

编写主界面(需要了解XAML语法),并修改MainPage.xaml,如代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Warensoft.StockApp"
             xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"
             x:Class="Warensoft.StockApp.MainPage">
    <!--
    此处要注意在头中注册OxyPlot的命名空间
    xmlns:oxy="clr-namespace:OxyPlot.Xamarin.Forms;assembly=OxyPlot.Xamarin.Forms"-->
    <Grid>
        <!--此处添加图形组件-->
        <oxy:PlotView Model="{Binding Model}"VerticalOptions="Center"HorizontalOptions="Center" />
    </Grid>
</ContentPage>

第二步:

打开MainPage.xaml.cs并为视图(图面)添加其对应的模型,代码如下(注意要引入Warensoft.EntLib.Common):

public partial classMainPage : ContentPage
    {
        publicMainPage()
        {
            InitializeComponent();
            //此处注册ViewModel
            this.BindingContext = newMainPageViewModel();
        }
    }
    public classMainPageViewModel : ViewModelBase
    {
        public override Task ShowCancel(string title, stringmessage)
        {
            throw newNotImplementedException();
        }
        public override Task<bool> ShowConfirm(string title, stringmessage)
        {
            throw newNotImplementedException();
        }
        public override void ShowMessage(stringmessage)
        {
            Application.Current.MainPage.DisplayAlert("提示",message,"OK");
        }
        protected override voidInitBindingProperties()
        {
        }
}

第三步:

定义图像组件的模型,并为图像添加XY坐标轴,添加一个K线和一条直线,代码如下所示:

  publicPlotModel Model
        {
            get { return this.GetProperty<PlotModel>("Model"); }
            set { this.SetProperty("Model", value); }
        }
        protected override voidInitBindingProperties()
        {
            this.Model = newPlotModel();
            //添加X、Y轴
            this.Model.Axes.Add(newOxyPlot.Axes.DateTimeAxis()
            {
                Position =AxisPosition.Bottom,
                StringFormat = "HH:mm",
                MajorGridlineStyle =LineStyle.Solid,
                IntervalType =DateTimeIntervalType.Minutes,
                IntervalLength = 30,
                MinorIntervalType =DateTimeIntervalType.Minutes,
                Key = "Time",
            });
            this.Model.Axes.Add(newOxyPlot.Axes.LinearAxis()
            {
                Position =AxisPosition.Right,
                MajorGridlineStyle =LineStyle.Solid,
                MinorGridlineStyle =LineStyle.Dot,
                IntervalLength = 30,
                IsPanEnabled = false,
                IsZoomEnabled = false,
                TickStyle =TickStyle.Inside,
            });
            //添加K线和直线
            this.candle = newOxyPlot.Series.CandleStickSeries();
            this.line = new OxyPlot.Series.LineSeries() { Color =OxyColors.Blue };
            this.Model.Series.Add(this.candle);
            this.Model.Series.Add(this.line);
        }

第四步:

添加获取K线函数(以OKCoin为例),代码如下:

/// <summary>
        ///读取OKCoin的15分钟K线
        /// </summary>
        /// <returns></returns>
        public async Task<List<Kline>>LoadKline()
        {
            var url = $"https://www.okcoin.cn/api/v1/kline.do?symbol=btc_cny&type=15min&size=100";
            HttpClient client = newHttpClient();
            var result = awaitclient.GetStringAsync(url);
            dynamic k =Newtonsoft.Json.JsonConvert.DeserializeObject(result);
            List<Kline> lines = new List<Kline>();
            int index = 0;
            foreach (var item ink)
            {
                List<double> d = new List<double>();
                foreach (var dd initem)
                {
                    d.Add((double)((dynamic)dd).Value);
                }
                lines.Add(new Kline() { Data =d.ToArray()});
                index++;
            }
            returnlines;
        }

第五步:

添加定时刷新并绘制图像的函数,代码如下所示:

privateStockServiceDriver driver;
        public asyncTask UpdateData()
        {
            //初始化WarensoftSocketService客户端驱动,此处使用的是测试用AppKey和SecretKey
            this.driver = new StockServiceDriver("C6651783-A3B9-4B72-8B02-A2E67A59C5A6", "6C442B3AF58D4DDA81BB03B353C0D7D8");
            await Task.Run(async()=>
            {
                while (true)
                {
                    try
                    {
                        //读取K线
                        var kline =await this.LoadKline();
                        //远程Warensoft Stock Service 分析SAR曲线
                        var sar = await this.driver.GetSAR(kline);
                        //绘图,注意办为需要更新UI,因此需要在主线程中执行更新代码
                        this.SafeInvoke(()=>{
                            //每次更新前,需要将旧数据清空
                            this.candle.Items.Clear();
                            this.line.Points.Clear();
                            foreach (var item in kline.OrderBy(k=>k.Time))
                            {
                                //注意将时间改为OxyPlot能识别的格式
                                var time =OxyPlot.Axes.DateTimeAxis.ToDouble(item.Time);
                                this.candle.Items.Add(newHighLowItem(time,item.High,item.Low,item.Open,item.Close));
                            }
                            if(sar.OperationDone)
                            {
                                foreach (var item in sar.AdditionalData.OrderBy(s=>s.DateTime))
                                {
                                    var time=OxyPlot.Axes.DateTimeAxis.ToDouble(item.DateTime);
                                    this.line.Points.Add(newDataPoint(time, item.Value));
                                }
                            }
                            //更新UI
                            this.Model.InvalidatePlot(true);
                        });
                    }
                    catch(Exception ex)
                    {
                    }
                    await Task.Delay(5000);
                }
            });
        }

完整的ViewModel代码如下:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingXamarin.Forms;
usingWarensoft.EntLib.Common;
usingWarensoft.EntLib.StockServiceClient;
usingOxyPlot;
usingOxyPlot.Axes;
usingOxyPlot.Series;
usingWarensoft.EntLib.StockServiceClient.Models;
usingSystem.Net.Http;
namespaceWarensoft.StockApp
{
    public partial classMainPage : ContentPage
    {
        publicMainPage()
        {
            InitializeComponent();
            this.BindingContext = newMainPageViewModel();
        }
    }
    public classMainPageViewModel : ViewModelBase
    {
        privateCandleStickSeries candle;
        privateLineSeries line;
        public override Task ShowCancel(string title, stringmessage)
        {
            throw newNotImplementedException();
        }
        public override Task<bool> ShowConfirm(string title, stringmessage)
        {
            throw newNotImplementedException();
        }
        public override void ShowMessage(stringmessage)
        {
            Application.Current.MainPage.DisplayAlert("提示",message,"OK");
        }
        publicPlotModel Model
        {
            get { return this.GetProperty<PlotModel>("Model"); }
            set { this.SetProperty("Model", value); }
        }
        protected override voidInitBindingProperties()
        {
            this.Model = newPlotModel();
            //添加X、Y轴
            this.Model.Axes.Add(newOxyPlot.Axes.DateTimeAxis()
            {
                Position =AxisPosition.Bottom,
                StringFormat = "HH:mm",
                MajorGridlineStyle =LineStyle.Solid,
                IntervalType =DateTimeIntervalType.Minutes,
                IntervalLength = 30,
                MinorIntervalType =DateTimeIntervalType.Minutes,
                Key = "Time",
            });
            this.Model.Axes.Add(newOxyPlot.Axes.LinearAxis()
            {
                Position =AxisPosition.Right,
                MajorGridlineStyle =LineStyle.Solid,
                MinorGridlineStyle =LineStyle.Dot,
                IntervalLength = 30,
                IsPanEnabled = false,
                IsZoomEnabled = false,
                TickStyle =TickStyle.Inside,
            });
            //添加K线和直线
            this.candle = newOxyPlot.Series.CandleStickSeries();
            this.line = new OxyPlot.Series.LineSeries() { Color =OxyColors.Blue };
            this.Model.Series.Add(this.candle);
            this.Model.Series.Add(this.line);
            this.UpdateData();
        }
        /// <summary>
        ///读取OKCoin的15分钟K线
        /// </summary>
        /// <returns></returns>
        public async Task<List<Kline>>LoadKline()
        {
            var url = $"https://www.okcoin.cn/api/v1/kline.do?symbol=btc_cny&type=15min&size=100";
            HttpClient client = newHttpClient();
            var result = awaitclient.GetStringAsync(url);
            dynamic k =Newtonsoft.Json.JsonConvert.DeserializeObject(result);
            List<Kline> lines = new List<Kline>();
            int index = 0;
            foreach (var item ink)
            {
                List<double> d = new List<double>();
                foreach (var dd initem)
                {
                    d.Add((double)((dynamic)dd).Value);
                }
                lines.Add(new Kline() { Data =d.ToArray()});
                index++;
            }
            returnlines;
        }
        privateStockServiceDriver driver;
        public asyncTask UpdateData()
        {
            //初始化WarensoftSocketService客户端驱动,此处使用的是测试用AppKey和SecretKey
            this.driver = new StockServiceDriver("C6651783-A3B9-4B72-8B02-A2E67A59C5A6", "6C442B3AF58D4DDA81BB03B353C0D7D8");
            await Task.Run(async()=>
            {
                while (true)
                {
                    try
                    {
                        //读取K线
                        var kline =await this.LoadKline();
                        //远程Warensoft Stock Service 分析SAR曲线
                        var sar = await this.driver.GetSAR(kline);
                        //绘图,注意办为需要更新UI,因此需要在主线程中执行更新代码
                        this.SafeInvoke(()=>{
                            //每次更新前,需要将旧数据清空
                            this.candle.Items.Clear();
                            this.line.Points.Clear();
                            foreach (var item in kline.OrderBy(k=>k.Time))
                            {
                                //注意将时间改为OxyPlot能识别的格式
                                var time =OxyPlot.Axes.DateTimeAxis.ToDouble(item.Time);
                                this.candle.Items.Add(newHighLowItem(time,item.High,item.Low,item.Open,item.Close));
                            }
                            if(sar.OperationDone)
                            {
                                foreach (var item in sar.AdditionalData.OrderBy(s=>s.DateTime))
                                {
                                    var time=OxyPlot.Axes.DateTimeAxis.ToDouble(item.DateTime);
                                    this.line.Points.Add(newDataPoint(time, item.Value));
                                }
                            }
                            //更新UI
                            this.Model.InvalidatePlot(true);
                        });
                    }
                    catch(Exception ex)
                    {
                    }
                    await Task.Delay(5000);
                }
            });
        }
    }
}

最后编译,并部署到手机上,最终运行效果如下:

利用Warensoft Stock Service编写高频交易软件--DEMO第7张

最终编译完毕的APK文件(下载)。

作者:科学家

Emailwarensoft@163.com

微信:43175692

免责声明:文章转载自《利用Warensoft Stock Service编写高频交易软件--DEMO》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mDNS故障排查(译)ansible实现mysql数据库主从复制下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SQL Server与Oracle有什么区别?

1.可操作平台上: Oracle可在所有主流平台上运行,Oracle数据库采用开放的策略目标,它使得客户可以选择一种最适合他们特定需要的解决方案。客户可以利用很多种第三方应用程序、工具。而SQL Server却只能在Windows上运行了。 但SQL Sever在Window平台上的表现,和Windows操作系统的整体结合程度,使用方便性,和Microso...

特来电CMDB应用实践

        配置管理数据库(Configuration Management Database,以下简称CMDB)是一个老生常谈的话题,不同的人有不同的见解,实际应用时,因为企业成熟度以及软硬件规模不同,别人的成功经验很难直接复制,因此用好了会成为整个应用系统的基石,用不好就成了鸡肋。特来电云平台在规划伊始,便意识到了CMDB的重要性,在实践中不断丰富...

高可用的Spring FTP上传下载工具类(已解决上传过程常见问题)

前言 最近在项目中需要和ftp服务器进行交互,在网上找了一下关于ftp上传下载的工具类,大致有两种。 第一种是单例模式的类。 第二种是另外定义一个Service,直接通过Service来实现ftp的上传下载删除。 这两种感觉都有利弊。 第一种实现了代码复用,但是配置信息全需要写在类中,维护比较复杂。 第二种如果是spring框架,可以通过propertis...

Beta阶段项目展示

1.团队简介 韩青长 前端工程师 我是韩青长,技术小白,抱着对软工的好奇和对未来工作的憧憬选了这门课。暂时选择了测试的工作,也对开发和UI有一定兴趣。从前上帝创造了我们,现在轮到我们来创造自己的软件了~ 陈彦吉 前端工程师PM 呃,自我介绍。。怎么说呢,我叫陈彦吉。。作为一个没什么基础的渣渣,感觉一路被碾压了两年,成绩不如大多数人,能力可能也不如大多数人...

共享文件夹切换用户、局域网共享切换用户的方法

在局域网访问共享文件时,有时候我们需要切换访问用户,便于获得对共享文件访问的不同权限。但是,由于windows操作系统为了方便用户访问共享,提供了用户信息和共享会话记忆功能,使得当用户访问共享文件时,会自动按照用户以前访问共享时的账号密码自动通过验证,而无需再次输入账号密码。这样,当用户想切换用户访问共享文件时常常就比较麻烦。 本文提供了两种方法,可以参考...

前端UI 原型设计版本号1.0.0

1. 首页:(初步设想是类似网易云课堂的首页风格) 按钮 功能 登陆 进入登陆页面 注册 进入注册页面 搜索 (待讨论是否需要) 搜索相关课程并呈现 右侧标签 当鼠标移到标签的时候,会弹出次级标签 2. 移动鼠标到相应标签上, 会出现相应的次级标题, 点击次级标题可以进入学习界面 3. 登陆之后, 这里主要的变化在于右上角的...