mirror of https://github.com/midoks/mdserver-web
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
5.2 KiB
128 lines
5.2 KiB
'''
|
|
pip install git+https://github.com/catalyst-team/catalyst@master --upgrade
|
|
|
|
|
|
cd /www/server/mdserver-web && python3 plugins/cryptocurrency_trade/ccxt/test/p1.py
|
|
|
|
|
|
cd /Users/midoks/Desktop/mwdev/server/mdserver-web && source bin/activate
|
|
|
|
python3 plugins/cryptocurrency_trade/ccxt/test/p1.py
|
|
'''
|
|
|
|
from datetime import datetime
|
|
import akshare as ak
|
|
import pandas as pd
|
|
import backtrader as bt
|
|
|
|
|
|
class BollStrategy(bt.Strategy): # BOLL策略程序
|
|
params = (("nk", 13), # 求均值的天数
|
|
('printlog', False),) # 打印log
|
|
|
|
def __init__(self): # 初始化
|
|
self.data_close = self.datas[0].close # 指定价格序列
|
|
# 初始化交易指令、买卖价格和手续费
|
|
self.order = None
|
|
self.buy_price = None
|
|
self.buy_comm = None
|
|
# Boll指标计算
|
|
self.top = bt.indicators.BollingerBands(
|
|
self.datas[0], period=self.params.nk).top
|
|
self.bot = bt.indicators.BollingerBands(
|
|
self.datas[0], period=self.params.nk).bot
|
|
# 添加移动均线指标
|
|
self.sma = bt.indicators.SimpleMovingAverage(
|
|
self.datas[0], period=self.params.nk)
|
|
|
|
def next(self): # 买卖策略
|
|
if self.order: # 检查是否有指令等待执行
|
|
return
|
|
# 检查是否持仓
|
|
"""
|
|
if not self.position: # 没有持仓
|
|
if self.data_close[0] > self.sma[0]: # 执行买入条件判断:收盘价格上涨突破20日均线
|
|
self.order = self.buy(size=100) # 执行买入
|
|
else:
|
|
if self.data_close[0] < self.sma[0]: # 执行卖出条件判断:收盘价格跌破20日均线
|
|
self.order = self.sell(size=100) # 执行卖出
|
|
"""
|
|
if not self.position: # 没有持仓
|
|
if self.data_close[0] < self.bot[0]: # 收盘价格跌破下轨
|
|
self.log("BUY CREATE, %.2f" % self.data_close[0])
|
|
self.order = self.buy() # 执行买入
|
|
else:
|
|
if self.data_close[0] > self.top[0]: # 收盘价格上涨突破上轨
|
|
self.log("SELL CREATE, %.2f" % self.data_close[0])
|
|
self.order = self.sell() # 执行卖出
|
|
|
|
def log(self, txt, dt=None, do_print=False): # 日志函数
|
|
if self.params.printlog or do_print:
|
|
dt = dt or self.datas[0].datetime.date(0)
|
|
print('%s, %s' % (dt.isoformat(), txt))
|
|
|
|
def notify_order(self, order): # 记录交易执行情况
|
|
# 如果order为submitted/accepted,返回空
|
|
if order.status in [order.Submitted, order.Accepted]:
|
|
return
|
|
# 指令为buy/sell,报告价格结果
|
|
if order.status in [order.Completed]:
|
|
if order.isbuy():
|
|
self.log(
|
|
f"买入:\n价格:{order.executed.price},\
|
|
成本:{order.executed.value},\
|
|
手续费:{order.executed.comm}"
|
|
)
|
|
self.buyprice = order.executed.price
|
|
self.buycomm = order.executed.comm
|
|
else:
|
|
self.log(
|
|
f"卖出:\n价格:{order.executed.price},\
|
|
成本: {order.executed.value},\
|
|
手续费{order.executed.comm}"
|
|
)
|
|
self.bar_executed = len(self)
|
|
|
|
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
|
|
self.log("交易失败") # 指令取消/交易失败, 报告结果
|
|
self.order = None
|
|
|
|
def notify_trade(self, trade): # 记录交易收益情况
|
|
if not trade.isclosed:
|
|
return
|
|
self.log(f"策略收益:\n毛收益 {trade.pnl:.2f}, 净收益 {trade.pnlcomm:.2f}")
|
|
|
|
def stop(self): # 回测结束后输出结果
|
|
self.log("(BOLL线: %2d日) 期末总资金 %.2f" %
|
|
(self.params.nk, self.broker.getvalue()), do_print=True)
|
|
|
|
code = "600036" # 股票代码
|
|
start_cash = 1000000 # 初始自己为1000000
|
|
stake = 100 # 单次交易数量为1手
|
|
commfee = 0.0005 # 佣金为万5
|
|
sdate = '20210101' # 回测时间段
|
|
edate = '20220930'
|
|
cerebro = bt.Cerebro() # 创建回测系统实例
|
|
# 利用AKShare获取股票的前复权数据的前6列
|
|
df_qfq = ak.stock_zh_a_hist(
|
|
symbol=code, adjust="qfq", start_date=sdate, end_date=edate).iloc[:, :6]
|
|
# 处理字段命名,以符合Backtrader的要求
|
|
df_qfq.columns = ['date', 'open', 'close', 'high', 'low', 'volume', ]
|
|
# 把date作为日期索引,以符合Backtrader的要求
|
|
df_qfq.index = pd.to_datetime(df_qfq['date'])
|
|
start_date = datetime.strptime(sdate, "%Y%m%d") # 转换日期格式
|
|
end_date = datetime.strptime(edate, "%Y%m%d")
|
|
# start_date=datetime(2022,1,4)
|
|
# end_date=datetime(2022,9,16)
|
|
data = bt.feeds.PandasData(
|
|
dataname=df_qfq, fromdate=start_date, todate=end_date) # 规范化数据格式
|
|
cerebro.adddata(data) # 加载数据
|
|
cerebro.addstrategy(BollStrategy, nk=13, printlog=True) # 加载交易策略
|
|
cerebro.broker.setcash(start_cash) # broker设置资金
|
|
cerebro.broker.setcommission(commission=commfee) # broker手续费
|
|
cerebro.addsizer(bt.sizers.FixedSize, stake=stake) # 设置买入数量
|
|
print("期初总资金: %.2f" % start_cash)
|
|
cerebro.run() # 运行回测
|
|
end_value = cerebro.broker.getvalue() # 获取回测结束后的总资金
|
|
print("期末总资金: %.2f" % end_value)
|
|
cerebro.plot()
|
|
|