当前位置: 移动技术网 > 移动技术>移动开发>Android > 利用Warensoft Stock Service编写高频交易软件

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

无论是哪种交易软件,对于程序员来讲,最麻烦的就是去实现各种算法。本文以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。

工程目录下图所示:

添加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的代码如下所示:

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

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

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网