Backtrader(十四)- Order订单 - 订单有效期与涨停跌停

关于订单有效期

buy/sell/close 方法有个参数 valid 控制订单的有效期,也就是到哪一天(含)之前订单都有效
但是,有效期对市价单和收盘价单是不起作用的,这两种订单肯定会在下一个实际bar上成交,对其他类型的订单。比如限价单,有效期起作用。

valid参数的值

1、买单有效期截止到valid 这一天的 23时59分59秒 (秒)

from datetime import timedelta

def next(self):
	#当前日期时间之后三个自然日内有效
	valid = self.data.datetime.datetime(0) + timedelta(days=3)

self.buy(
	size=100,
	valid=valid,
	exectype=bt.Order.Limit,
	price=10
)

2、根据实际bar数量(非自然日)来确定有效期

from datetime import timedelta

def next(self):
	# 当前bar后面10根bar的结束时间到期
	valid = self.data.datetime.datetime(10)

self.buy(
	size=100,
	valid=valid,
	exectype=bt.Order.Limit,
	price=10
)

关于涨停、跌停

是指开盘即涨停一直持续到收盘为止的K线形态。因为这种K线形态类似于汉字的一,因此称为一字涨停。
一字涨停的股票因为开盘就有大量买单封住涨停,而卖单数量远远小于买单。
代表人们对这只股票强烈看好,所以在一字涨停期间,几乎不可能买到这支股票

涨停:无法执行买单;跌停,无法执行卖单

import datetime
import backtrader as bt
from feed import feed
from logger import lg
import backtrader.indicators as btind


class SmaCross(bt.Strategy):
    params = dict(
        period=5
    )

    def __init__(self):
        self.order = None
        self.move_average = bt.ind.MovingAverageSimple(
            self.data.close,
            period=self.p.period
        )

    def log(self, txt, dt=None):
        dt = dt or self.data.datetime.date(0)
        if isinstance(dt, float):
            dt = bt.num2date(dt)
        lg.info(
            '%s, %s' % (dt.isoformat(), txt)
        )

    def notify_order(self, order):
        typ = lambda: "Buy" if order.isbuy() else "Sell"
        self.log(f'订单状态 {order.getstatusname()} 订单类型 {typ()}')
        if order.status in [order.Submitted, order.Accepted]:
            self.order = order
            return
        if order.status in [order.Completed]:
            self.log(
                f' {typ()} 订单执行价格 {order.executed.price}'
            )
        self.order = None

    def notify_trade(self, trade):
        if trade.isclosed:
            self.log(
                f'毛收益 {trade.pnl}, 扣佣后收益 {trade.pnlcomm}, 佣金 {trade.commission}'
            )

    def next(self):
        if self.order:
            return

        if not self.position:
            if self.data.close[-1] < self.move_average[-1] \
                and self.data.close[0] > self.move_average[0]:
                validday = self.data.datetime.datetime(1)
                # 次日涨停价判断条件
                upperprice = self.data.close[0] * 1.1 - 0.02
                # 必然触发涨停逻辑
                # upperprice = self.data.close[0] * 1.1 - 5
                self.order = self.buy(
                    size=100,
                    valid=validday,
                    exectype=bt.Order.Limit,
                    price=upperprice
                )

        elif self.data.close[-1] > self.move_average[-1] \
            and self.data.close[0] < self.move_average[0]:
            validday = self.data.datetime.datetime(1)
            # 次日一字跌停判断条件
            # lowerprice = self.data.close[0] * 0.9 + 0.02
            # 必然触发一字跌停
            lowerprice = self.data.close[0] * 0.9 + 5
            self.log(
                f'卖单跌停价格 {lowerprice}'
            )
            self.order = self.sell(
                size=100,
                valid=validday,
                exectype=bt.Order.Limit,
                plimit=lowerprice
            )


if __name__ == '__main__':
    cerebro = bt.Cerebro()
    cerebro.adddata(feed)
    cerebro.addstrategy(SmaCross)
    cerebro.broker.setcash(10000.0)
    cerebro.broker.setcommission(0.001)
    cerebro.broker.set_slippage_fixed(0.05)

    lg.warning(f'初始市值 {cerebro.broker.get_value()}')
    cerebro.run(stdstats=False)
    lg.warning(f'最终市值 {cerebro.broker.get_value()}')

    cerebro.plot()
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值