使用python实现一个简单的数字货币交易回测系统

目录

  • BaseStrategy(策略基类)
  • Broker(经纪人)
  • 示例代码
  • 数据可视化

BaseStrategy(策略基类)

BaseStrategy,交易策略基类

回调函数

  • on_start:策略开始运行
  • on_stop:策略运行结束
  • next_bar:回测收到新的K线时调用

其他函数

  • record:记录自定义数据
  • output_record:输出数据记录文件

Broker(经纪人)

Broker 经纪人,负责处理处理撮合交易订单等功能.

交易相关函数

  • pos:当前仓位
  • cancel_all:取消所有订单
  • buy:做多
  • sell:平多
  • short:做空
  • cover:平空
  • create_stop_order:创建止盈止损订单

示例代码

行情数据这里用的是币安上爬取的分钟数据,关于数据的爬取和整理可以看这里。

    from common.time_utils import timestamp_to_datetime# 读取分钟数据df = pd.read_csv('ETHUSDT-1m.csv', converters={'Open time': timestamp_to_datetime,'Close time': timestamp_to_datetime})# 数据清洗df.rename(columns={'Open time': 'open_time','Close time': 'close_time','Open': 'open','High': 'high','Low': 'low','Close': 'close','Volume': 'volume',}, inplace=True)# 截取指定时间范围的数据df = df[df['open_time'] >= '2021-05-01']df = df[df['close_time'] <= '2021-06-01']df.reset_index(inplace=True, drop=True)# print(df)broker = Broker()broker.set_symbol('ETHUSDT')broker.set_strategy(TripleFilterTradeSystemStrategy) # 设置策略类broker.set_leverage(1.0)  # 杠杆比例broker.set_cash(3600)  # 1初始资金.broker.set_commission(7 / 10000)  # 手续费broker.set_backtest_data(df)  # 数据.broker.run()broker.calculate().to_csv('triple_filter_trade_system_backtest.csv', index=False)broker.output_record('triple_filter_trade_system_record.csv')# 参数优化, 穷举法, 遗传算法。# broker.optimize_strategy(long_period=[i for i in range(30, 60, 5)], short_period=[i for i in range(5, 30, 1)])

数据可视化

策略中通过record方法记录了行情数据和交易信号,数据如下:
在这里插入图片描述

使用bokeh将K线数据、交易信号和相关技术指标可视化

from math import pi
from bokeh.plotting import figure
import numpy as np
from common.indicator import EMA
import pandas as pd
import talib
from bokeh.layouts import column
from bokeh.io import output_file, show, save
from bokeh.models import ColumnDataSource, HoverTool, RangeTool, CDSView, BooleanFilter, DataRange1d, LinearAxis, \Range1d, CustomJS
from datetime import datetime
from common.time_utils import timestamp_to_datetimeclass Signal:def __init__(self, data, marker='inverted_triangle', color='#10B479'):"""信号:param data: 信号集数据:param marker: 标记类型:param color: 颜色"""self.data = dataself.marker = markerself.color = color@staticmethoddef signal_below_price(data, price, func):"""计算信号标记位置使其位于价格底部:param data:    信号数据:param price:   价格数据:param func:    目标信号判断条件方法:return: 位于价格底部的信号集合数据"""signal = []for date, value in data.iteritems():if func(value):# signal.append(price[date] * 0.99)signal.append(price[date])else:signal.append(np.nan)return signal@staticmethoddef signal_above_price(data, price, func):"""计算信号标记位置使其位于价格顶部:param data:    信号数据:param price:   价格数据:param func:    目标信号判断条件方法:return: 位于价格顶部的信号集合数据"""signal = []for date, value in data.iteritems():if func(value):# signal.append(price[date] * 1.01)signal.append(price[date])else:signal.append(np.nan)return signaldef make_range_tool(date, close, x_range=None, source=None):"""时间范围选择工具:param date::param close::param x_range::param source:"""select = figure(title="", plot_height=100, plot_width=1500, x_axis_type="datetime", y_axis_type=None, tools="", toolbar_location=None, background_fill_color="#efefef")range_tool = RangeTool(x_range=x_range)range_tool.overlay.fill_color = "navy"range_tool.overlay.fill_alpha = 0.2select.line(date, close)select.ygrid.grid_line_color = Noneselect.add_tools(range_tool)select.toolbar.active_multi = range_toolreturn selectdef make_force_index_plot(source, color='#7922AD', x_range=None):"""强力指数:param source: 列格式:date, efi, colors_efi:param color::param x_range::param source:"""TOOLS = "crosshair,pan,wheel_zoom,box_zoom,reset,save"p = figure(x_axis_type="datetime", title="Force Index", plot_width=1500, plot_height=240, tools=TOOLS, toolbar_location='right', x_range=x_range)line = p.line(x='date', y='efi', line_width=1, color=color, source=source)# 悬浮提示hover_tool = HoverTool(tooltips="""<div"><div><b>EFI:</b><span style="font-size: 10px; color: @colors_efi;">@efi{0,0}</span></div><div><b>Date:</b>@date{%F %T}</div><div><b>Y:</b>$y{0.000}</div></div>""",formatters={'@date': 'datetime',  # use 'datetime' formatter for 'date' field},# display a tooltip whenever the cursor is vertically in line with a glyph# "mouse":only when the mouse is directly over a glyph# "vline":	whenever the a vertical line from the mouse position intersects a glyph# "hline":	whenever the a horizontal line from the mouse position intersects a glyphmode='vline',# 是否显示箭头show_arrow=True,# line_policy='nearest',renderers=[line])p.add_tools(hover_tool)return pdef make_candlestick_plot(df, period=None, signals=None, title='', filename=None, ema=(5, 10, 20), ema_color=('#C09A1C', '#7922AD', '#167BE1'), source=None):"""蜡烛图:param df: 数据集,格式:date, open, high, low, close, volume:param period: 时间周期,默认,单位毫秒:param signals: 信号集:param title: 标题:param filename: 文件名:param ema: 移动平均线:param ema_color: 移动平均线颜色:param source: 数据源"""inc = df.close > df.opendec = df.open > df.closew = period * 0.5 if period else 24 * 60 * 60 * 1000  # half day in ms# TOOLS = "pan,wheel_zoom,box_zoom,reset,save"TOOLS = "crosshair,pan,wheel_zoom,box_zoom,reset,save"# 蜡烛图p_candlestick = figure(x_axis_type="datetime", plot_width=1500, plot_height=450, tools=TOOLS, title=title, x_range=(df.date.iloc[0], df.date.iloc[-1]))# p_candlestick.sizing_mode = 'stretch_both'  # 全屏p_candlestick.xaxis.major_label_orientation = pi / 4  # x轴标题倾斜p_candlestick.grid.grid_line_alpha = 0.3# 绘制影线p_candlestick.segment(x0='date', y0='high', x1='date', y1='low', color="black", source=source)# 绘制柱体p_candlestick.vbar(df.date[inc], w, df.open[inc], df.close[inc], fill_color="#10B479", line_color="black")p_candlestick.vbar(df.date[dec], w, df.open[dec], df.close[dec], fill_color="#DD253E", line_color="black")# 绘制EMAema_lines = []if ema:for index in range(0, len(ema)):key = 'ema%s' % ema[index]if key not in df:df[key] = EMA(df.close, ema[index])line = p_candlestick.line(x='date', y=key, line_color=ema_color[index], legend_label='EMA%s' % (ema[index]), source=source)ema_lines.append(line)# 绘制信号if signals:for signal in signals:p_candlestick.scatter(df.date, signal.data, marker=signal.marker, size=20, color=signal.color, alpha=0.6)if filename:output_file(filename, title=title, mode='inline')# show(p_candlestick)# 图例p_candlestick.legend.location = "top_left"p_candlestick.legend.border_line_alpha = 0p_candlestick.legend.background_fill_alpha = 0p_candlestick.legend.click_policy = "hide"return p_candlestick, ema_linesdef plot_middle_period(path, symbol):"""绘制中周期图标:param path:    数据表路径,列格式:date, open, high, low, close, volume:param symbol:  交易对名称"""df = pd.read_csv(path, parse_dates=True, index_col=0)df["date"] = df.indexup_color = '#10B479'down_color = '#DD253E'# 计算涨幅pre_close = df.close.shift(1)df['increase'] = (df.close - pre_close) / pre_close * 100# EMAdf['ema5'] = EMA(df.close, 5)df['ema10'] = EMA(df.close, 10)df['ema20'] = EMA(df.close, 20)# 开高低收价格颜色df['colors_open'] = np.where((df.open - pre_close) > 0, up_color, down_color)df['colors_high'] = np.where((df.high - pre_close) > 0, up_color, down_color)df['colors_low'] = np.where((df.low - pre_close) > 0, up_color, down_color)df['colors_close'] = np.where((df.close - pre_close) > 0, up_color, down_color)# 均线颜色df['colors_ema5'] = np.where((df['ema5'].diff()) > 0, up_color, down_color)df['colors_ema10'] = np.where((df['ema10'].diff()) > 0, up_color, down_color)df['colors_ema20'] = np.where((df['ema20'].diff()) > 0, up_color, down_color)# EFI颜色df['colors_efi'] = np.where(df['efi'] > 0, up_color, down_color)# 做多信号long_signal = Signal(Signal.signal_below_price(df['signals'], df['low'], lambda signals: 'buy' in signals), 'triangle', '#10B479')# 做空信号short_signal = Signal(Signal.signal_above_price(df['signals'], df['high'], lambda signals: 'short' in signals), 'inverted_triangle', '#DD253E')filename = 'triple_filter_trade_system_middle.html'title = '%s 三重滤网交易系统' % symbol# 数据源source = ColumnDataSource(df)# ETH/USDT 5分钟K线图p_candlestick, ema_lines = make_candlestick_plot(df, period=5 * 60 * 1000, signals=[long_signal, short_signal], title=title, source=source)# 强力指数图p_efi = make_force_index_plot(source, x_range=p_candlestick.x_range)# 悬浮提示hover_tool = HoverTool(tooltips="""<div"><div><b>Open:</b><span style="font-size: 10px; color: @colors_open;">@open{0.000}</span></div><div><b>High:</b><span style="font-size: 10px; color: @colors_high;">@high{0.000}</span></div><div><b>Low:</b><span style="font-size: 10px; color: @colors_low;">@low{0.000}</span></div><div><b>Close:</b><span style="font-size: 10px; color: @colors_close;">@close{0.000}</span></div><div><b>Increase:</b><span style="font-size: 10px; color: @colors_close;">@increase{0.00}%</span></div><div><b>Volume:</b><span style="font-size: 10px; color: @colors_close;">@volume{0,0}</span></div><div><b>EMA5:</b><span style="font-size: 10px; color: @colors_ema5;">@ema5{0.000}</span></div><div><b>EMA10:</b><span style="font-size: 10px; color: @colors_ema10;">@ema10{0.000}</span></div><div><b>EMA20:</b><span style="font-size: 10px; color: @colors_ema20;">@ema20{0.000}</span></div><div><b>EFI:</b><span style="font-size: 10px; color: @colors_efi;">@efi{0,0}</span></div><div><b>Date:</b>@date{%F %T}</div><div><b>Y:</b>$y{0.000}</div></div>""",formatters={'@date': 'datetime',},mode='vline',# 是否显示箭头show_arrow=True,renderers=[ema_lines[0]],# point_policy='snap_to_data',)p_candlestick.add_tools(hover_tool)range_tool = make_range_tool(df.date, df.close, x_range=p_candlestick.x_range, source=source)layout = column(range_tool, p_candlestick, p_efi)output_file(filename, title=title, mode='inline')show(layout)

在这里插入图片描述
项目地址:https://github.com/linchaolong/SimpleQuant

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/35537.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

各国纷纷推出数字货币,数字货币发展正当其时

各国央行应如何应对数字技术的挑战&#xff1f;这已成为一个紧迫的问题。部分原因是&#xff0c;各国央行和政府都必须掌控这个私营货币泛滥的新蛮荒时代。现在&#xff0c;它们必须推出自己的数字货币。 试想在不使用纸币的情况下&#xff0c;所有的付款行为将如何实现&#…

网格交易法以及在数字货币中基于Python的量化实现

介绍 我一直觉得程序员都应该试试量化投资&#xff0c;因为在投资里最忌讳的就是情绪波动&#xff0c;而程序员们都相对理性一些&#xff0c;更加愿意相信规则与数据&#xff0c;而同时程序员们又有能力去实现自动交易&#xff0c;所以我这篇文章主要的目标是面向程序员&#…

如何获取免费的数字货币历史数据

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

数字货币量化交易策略—基于移动平均线MA

本文介绍金融市场中的量化交易策略之移动平均线MA策略。 一、概念 移动平均线&#xff0c;Moving Average&#xff0c;简称MA&#xff0c;MA是用统计分析的方法&#xff0c;将一定时期内的证券价格&#xff08;指数&#xff09;加以平均&#xff0c;并把不同时间的平均值连接…

中国央行将发行全球首个法定数字货币,你准备好了吗?

二月初央行推动的基于区块链的数字票据交易平台已测试成功&#xff0c;由央行发行的法定数字货币已在该平台试运行。这一消息表明中国成为全球首个发行数字货币的国家&#xff0c;长达4年的研究让中国在数字货币领域走在了世界前列。 数字货币是什么&#xff1f;央行又为何如此…

全球传统证券外汇交易商进军区块链数字资产·统计(一)

越来越多合规的基础设施建立完善之后&#xff0c;这些资产管理公司与持牌机构将有能力为这些传统的「老钱」打通投资渠道&#xff0c;那么现有的市场份额会成倍的增加&#xff0c;同时也会打破现有的行业市场格局。 目录 一、eToro互联网券商 二、盈透证券集团 三、TD Ameri…

数字货币量化交易策略操作(61BTC分享)

数字货币基金量化主要进行无风险套利和趋势套利两类操作&#xff0c;其中 无风险套利主要包括&#xff1a; 1、比特币在不同交易所的价差搬砖 2、流通性比较好的代币的三角套利 3、盘口价差很大&#xff0c;交易活跃的盘口套利 4、期货对冲套利。 趋势套利主要包括 5、杠…

mac checkra1n越狱14.0-14.8

首先安装checkra1n 请到官网自行下载安装 All Releases checkra1n 可参考 Sina Visitor System 启动软件件操作 1、 进入初始界面&#xff0c;如果start按键亮到&#xff0c;直接到 3 2、设置步骤内容 如下内容 3、准备开始 4、操作越狱操作界面&#xff08;重点&#x…

iOS逆向一iPhone手机越狱/APP脱壳/IPA签名

全工具&#xff0c;无门槛。 iPhone越狱一一某助手 APP脱壳一一CrackerXI IPA签名一一某助手 iPhone越狱 越狱方法和步骤&#xff1a; 1.下载并打开某助手电脑端&#xff0c;将需要越狱设备连接至电脑。 2.在某助手“工具箱”中&#xff0c;找到并打开“一键越狱”功能。…

iOS安全攻防(二十):越狱检测的攻与防

越狱检测的攻与防 在应用开发过程中,我们希望知道设备是否越狱,正以什么权限运行程序,好对应采取一些防御和安全提示措施。iOS7相比之前版本的系统而言,升级了沙盒机制,封锁了几乎全部应用沙盒可以共享数据的入口。即使在越狱情况下,限制也非常多,大大增加了应用层攻击难…

iOS 越狱-砸壳工具的使用

1.越狱概述 1.1 通过iOS系统安全启动链漏洞&#xff0c;从而禁止掉信任链中负责验证的组件。拿到iOS系统最大权限ROOT权限. 1.2 当启动一台iOS设备时&#xff0c;系统首先会从只读的ROM中读取初始化指令&#xff0c;也就是系统的引导程序(事实上所有的操作系统启动时都要经过这…

iOS(越狱) 应用脱壳反编译hook教程 (系统ios11.3.1)

为什么会有这边博文? 因为公司原因,领导又让我捡起荒废了一年多的ios,了解对ios应用脱壳以及反编译hook相关知识.相比于安卓的hook来说(想了解安卓hook的可以参考我的另外一篇文章),ios的hook要麻烦的多,前人栽树后人乘凉,希望我的这边文章能给大家对ios的hook有个清晰的认识…

iOS 越狱检测/反越狱

在 iOS 越狱设备上&#xff0c;游戏外挂开发人员可以对游戏程序砸壳用于逆向分析&#xff0c;也可以利用 substrate 对游戏逻辑进行 hook 从而制作出各种游戏外挂。这些游戏外挂程序可以被其他越狱玩家直接安装&#xff0c;也可以通过 cydia 商店进行分发。鉴于用户使用越狱设备…

初涉iOS逆向工程:免越狱修改微信(外观篇)

点击上方“iOS开发”&#xff0c;选择“置顶公众号” 关键时刻&#xff0c;第一时间送达&#xff01; 美国学者埃德加戴尔&#xff08;Edgar Dale&#xff09;1946年提出了“学习金字塔”&#xff08;Cone of Learning&#xff09;的理论。他提到&#xff1a;学习效果在50%以上…

【电商运营】如何吸引客户?经典WhatsApp营销案例分享!

关键词&#xff1a;电商运营&#xff0c;WhatsApp营销 电子商务日趋成熟&#xff0c;竞争也越来越激烈。如果企业想保持领先地位&#xff0c;持续吸引客户&#xff0c;则需要将WhatsApp等消息传递应用程序添加到你的营销渠道。但是什么类型的WhatsApp营销活动适合电子商务呢&a…

通达信超跌反弹选股公式,使用筹码函数WINNER

在前面的文章中&#xff0c;已经介绍了WINNER函数&#xff0c;不过对于如何使用函数&#xff0c;当时只进行了简单举例&#xff0c;没有做深入研究。本文将结合WINNER函数的特性&#xff0c;编写通达信超跌反弹选股公式。 WINNER函数表示获利盘比例&#xff0c;取值范围是0-1&…

散户打板,一夜暴富?Pyhton量化11万次涨停,跟着买,收益竟...?【邢不行

你问我涨停敢死队算什么东西&#xff1f;我现在告诉你&#xff0c;你们机构不敢买的涨停&#xff0c;我们买&#xff1b;你们机构不敢割的肉&#xff0c;我们割。 一句话&#xff0c;机构能买的我们买&#xff0c;机构不能买的我们更要买&#xff01;追逐涨停&#xff0c;只买…

交易员普遍使用的几个高胜率指标公式分享给你

交易者普遍运用的都是以下几个技术指标&#xff1a; 1、MACD指标 2、DMI指标 3、KDJ指标 4、布林线 5、移动平均线 6、RSI指标 7、波段买卖点技术指标 第7个那个指标我也是听朋友说他在做的比较好用的&#xff0c;而且没有滞后性。具体如下&#xff1a; 看下图 &…

教你炒股票7:给-赚-了指数亏-了-钱的一些忠告

教你炒股票7&#xff1a;给-赚-了指数亏-了-钱的一些忠告 2006/11/16 12:00:01 周四 今天不宠幸孔-二爷了&#xff0c;宠幸一下股票。早就说过&#xff0c;中国没有人有资格和本ID谈论股票。国庆前&#xff0c;香-港有几个大的基-金-经理过来&#xff0c;吃饭时让本ID给修理了一…

Java 的完整故事-从 1991 年到 2022 年

Java 的完整故事&#xff0c;从 1991 年到 2022 年 个人网站&#xff1a;www.gydblog.com 01、前言 今天&#xff0c;Java已经发展为世界上最流行和最受欢迎的编程语言之一&#xff0c;每年有超过数以万计的人在学习Java或从事Java开发相关的工作。毋庸置疑&#xff0c;Java技…