欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-23 10:59:52
无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法。本文以sar算法的实现过程为例,为大家说明如何使用warensoft stock service来实现高频交...

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

目前warensoftstockservice已经实现了c# 版本的客户端驱动,可以直接在nuget上搜索warensoft并安装。客户端驱动已经编译为跨平台.net standard1.6版本,可以在桌面应用(wpf,winform)、xamarin手机应用(wp,android,ios)、web(asp.net,asp.net core)中应用,操作系统可以是window,android,ios,imac,linux。

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

软件环境说明

ide

vs2017 rc

客户端

android4.4

服务器环境

ubuntu16

客户端运行环境

xamarin.forms

客户端图形组件

oxyplot

建立一个xamarin.forms手机app

这里选择基于xaml的app,注意共享库使用pcl。

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

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

工程目录下图所示:

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

添加nuget引用包

首先,为warensoft.stockapp共享库添加oxyplot引用(此处可能需要*),如下图所示:

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

然后再分别安装warensoft.entlib.common,warensoft.entlib.stockserviceclient,如下图所示:

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

然后为warensoft.stockapp.droid添加oxyplot的nuget引用,如下所示:

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

然后在android的mainactivity中加入平台注册代码:

oxyplot.xamarin.forms.platform.android.plotviewrenderer.init();

mainactivity.cs的代码如下所示:

protected override void oncreate(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(new app());
 }

实现主窗口

主界面的实现采用mvvm模式来实现,关于mvvm的讲解,网上应该有很多了,后面的文章中,我会把我自己的理解写出来,让大家分享。本demo的mvvm框架已经集成在了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 class mainpage : contentpage
 {
 public mainpage()
 {
 initializecomponent();
 //此处注册viewmodel
 this.bindingcontext = new mainpageviewmodel();
 }
 }
 public class mainpageviewmodel : viewmodelbase
 {
 public override task showcancel(string title, string message)
 {
 throw new notimplementedexception();
 }
 public override task<bool> showconfirm(string title, string message)
 {
 throw new notimplementedexception();
 }
 public override void showmessage(string message)
 {
 application.current.mainpage.displayalert("提示",message,"ok");
 }
 protected override void initbindingproperties()
 {
 }
}

第三步:

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

public plotmodel model
 {
 get { return this.getproperty<plotmodel>("model"); }
 set { this.setproperty("model", value); }
 }
 protected override void initbindingproperties()
 {
 this.model = new plotmodel();
 //添加x、y轴
 this.model.axes.add(new oxyplot.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(new oxyplot.axes.linearaxis()
 {
 position = axisposition.right,
 majorgridlinestyle = linestyle.solid,
 minorgridlinestyle = linestyle.dot,
 intervallength = 30,
 ispanenabled = false,
 iszoomenabled = false,
 tickstyle = tickstyle.inside,
 });
 //添加k线和直线
 this.candle = new oxyplot.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 = new httpclient();
 var result = await client.getstringasync(url);
 dynamic k = newtonsoft.json.jsonconvert.deserializeobject(result);
 list<kline> lines = new list<kline>();
 int index = 0;
 foreach (var item in k)
 {
 list<double> d = new list<double>();
 foreach (var dd in item)
 {
  d.add((double)((dynamic)dd).value);
 }
 lines.add(new kline() { data = d.toarray()});
 index++;
 }
 return lines;
 }

第五步:

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

private stockservicedriver driver;
 public async task 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(new highlowitem(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(new datapoint(time, item.value));
  }
  }
  //更新ui
  this.model.invalidateplot(true);
  });
  }
  catch (exception ex)
  {
  }
  await task.delay(5000);
 }
 });
 }

完整的viewmodel代码如下:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
using xamarin.forms;
using warensoft.entlib.common;
using warensoft.entlib.stockserviceclient;
using oxyplot;
using oxyplot.axes;
using oxyplot.series;
using warensoft.entlib.stockserviceclient.models;
using system.net.http;
namespace warensoft.stockapp
{
 public partial class mainpage : contentpage
 {
 public mainpage()
 {
 initializecomponent();
 this.bindingcontext = new mainpageviewmodel();
 }
 }
 public class mainpageviewmodel : viewmodelbase
 {
 private candlestickseries candle;
 private lineseries line;
 public override task showcancel(string title, string message)
 {
 throw new notimplementedexception();
 }
 public override task<bool> showconfirm(string title, string message)
 {
 throw new notimplementedexception();
 }
 public override void showmessage(string message)
 {
 application.current.mainpage.displayalert("提示",message,"ok");
 }
 public plotmodel model
 {
 get { return this.getproperty<plotmodel>("model"); }
 set { this.setproperty("model", value); }
 }
 protected override void initbindingproperties()
 {
 this.model = new plotmodel();
 //添加x、y轴
 this.model.axes.add(new oxyplot.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(new oxyplot.axes.linearaxis()
 {
 position = axisposition.right,
 majorgridlinestyle = linestyle.solid,
 minorgridlinestyle = linestyle.dot,
 intervallength = 30,
 ispanenabled = false,
 iszoomenabled = false,
 tickstyle = tickstyle.inside,
 });
 //添加k线和直线
 this.candle = new oxyplot.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 = new httpclient();
 var result = await client.getstringasync(url);
 dynamic k = newtonsoft.json.jsonconvert.deserializeobject(result);
 list<kline> lines = new list<kline>();
 int index = 0;
 foreach (var item in k)
 {
 list<double> d = new list<double>();
 foreach (var dd in item)
 {
 d.add((double)((dynamic)dd).value);
 }
 lines.add(new kline() { data = d.toarray()});
 index++;
 }
 return lines;
 }
 private stockservicedriver driver;
 public async task 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(new highlowitem(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(new datapoint(time, item.value));
 }

 }
 //更新ui
 this.model.invalidateplot(true);
 });
 }
 catch (exception ex)
 {
 }
 await task.delay(5000);
 }
 });
 }
 }
}

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

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

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!