backtrader sar

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 28 16:40:56 2020

@author: zhangjun
"""

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
 
import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])
import pandas as pd
#from WindPy import w
# Import the backtrader platform
import backtrader as bt
from sqlalchemy import create_engine
import stockstats 
import backtrader.feeds as btfeeds

class SarData(btfeeds.PandasData):
    lines = ('sarbull', 'sarbear')
    params = (
        ('datetime', None),
        ('open', 'open'),
        ('high', 'high'),
        ('low', 'low'),
        ('close', 'close'),
        ('volume','vol'),
        ('openinterest', None),
        ('sarbull', 'sarbull'),
        ('sarbear', 'sarbear'),
    )
    datafields = btfeeds.PandasData.datafields + (['sarbull', 'sarbear'])
 
# Create a Stratey
class TestStrategy(bt.Strategy):
 
    def log(self, txt, dt=None):
        ''' Logging function fot this strategy'''
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))
 
    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        self.sarbull = self.datas[0].sarbull
        self.sarbear = self.datas[0].sarbear

        # To keep track of pending orders
        self.order = None
#        self.log('Close, %.2f' % self.dataclose[0])
 
    def notify(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            # Buy/Sell order submitted/accepted to/by broker - Nothing to do
            return
 
        # Check if an order has been completed
        # Attention: broker could reject order if not enougth cash
        if order.status in [order.Completed, order.Canceled, order.Margin]:
            if order.isbuy():
                self.log(
                    'BUY EXECUTED, Size: %.2f, Price: %.2f, Value: %.2f, Comm %.2f' %
                    (order.executed.size,
                     order.executed.price,
                     self.broker.getvalue(),
                     order.executed.comm))

                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:  # Sell
                self.log('SELL EXECUTED, Size: %.2f,Price: %.2f, Value: %.2f, Comm %.2f' %
                         (order.executed.size,
                          order.executed.price,
                          self.broker.getvalue(),
                          order.executed.comm))
 
            self.bar_executed = len(self)
 
        # Write down: no pending order
        self.order = None
 
    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])

        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return
 
        # Check if we are in the market
        if not self.position:
            if pd.isna(self.sarbear[0]) and not pd.isna(self.sarbear[-1]):
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
#                size = int(self.broker.get_cash() / self.dataclose[0]*0.9)
                self.order = self.buy()
            # Not yet ... we MIGHT BUY if ...
#            if self.dataclose[0] < self.dataclose[-1]:
                # current close less than previous close
 
#                if self.dataclose[-1] < self.dataclose[-2]:
                    # previous close less than the previous close
 
                    # BUY, BUY, BUY!!! (with default parameters)
#                    self.log('BUY CREATE, %.2f' % self.dataclose[0])
 
                    # Keep track of the created order to avoid a 2nd order
#                    self.order = self.buy()
 
        else:
 
            # Already in the market ... we might sell
#            if len(self) >= (self.bar_executed + 5):
            if pd.isna(self.sarbull[0]) and not pd.isna(self.sarbull[-1]):
                # SELL, SELL, SELL!!! (with all possible default parameters)
                self.log('SELL CREATE, %.2f' % self.dataclose[0])
 
                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()
 
 
if __name__ == '__main__':
    # Create a cerebro entity
    cerebro = bt.Cerebro()
 
    # Add a strategy
    cerebro.addstrategy(TestStrategy)
 
    # Create a Data Feed
    # 本地数据,笔者用Wind获取的东风汽车数据以csv形式存储在本地。
    # parase_dates = True是为了读取csv为dataframe的时候能够自动识别datetime格式的字符串,big作为index
    # 注意,这里最后的pandas要符合backtrader的要求的格式
    engine = create_engine('sqlite:home/zhangjun/quanter/quant/test.sqlite')
    k_data_code='300017'
    k_data=pd.read_sql('select distinct * from k_data where ts_code=\'300017.SZ\' order by trade_date',engine)
    
    convert_datetime = lambda x: pd.to_datetime(str(x))
    k_data['trade_date'] = k_data['trade_date'].apply(convert_datetime)
    k_data.set_index(["trade_date"], inplace=True)
#    dataframe = pd.read_csv('dfqc.csv', index_col=0, parse_dates=True)
    stockStat = stockstats.StockDataFrame.retype(k_data,index_column='trade_date')
#    print(stockStat)
    dataframe=k_data
    dataframe['sarbull']=stockStat['sarbull']
    dataframe['sarbear']=stockStat['sarbear']

    dataframe['openinterest'] = 0
    data = SarData(dataname=dataframe,
                       fromdate = datetime.datetime(2020, 1, 1),
                       todate = datetime.datetime(2020,12, 28)
                       )
    # Add the Data Feed to Cerebro
#    print(k_data)
    cerebro.adddata(data)
 
    # Set our desired cash start
    cerebro.broker.setcash(100000.0)
 
    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    cerebro.addsizer(bt.sizers.PercentSizer,percents = 95)
    cerebro.broker.setcommission(commission=0.003)
    # Run over everything
    cerebro.run()
 
    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    # Plot the result
#    cerebro.plot()
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值