量化交易开发之context与判断(五)

量化交易开发之context与判断(五)

通过前文的讲解,我们已经能理解最开始那个最简单的策略例子,如下:

    def initialize(context):
        run_daily(period, time = 'every_bar')
        g.security = '000001.XSHE'
    
    def period(context):
        order(g.security, 100)

下面我们看看什么是context。

一、context的结构

  • context是一个回测系统建立的Context类型的对象,其中存储了如当前策略运行的时间点、所持有的股票、数量、持仓成本等数据。

  • 对象可以理解为特殊类型的变量,对象的结构往往比我们之前见过的list与dict更复杂,被定义好的对象是有名字的,比如context是一个变量,它的变量类型是一个Context类型的对象,就像dict包括key与value,Context类型的对象也包括很多属性,而且可以嵌套另一个种类型的对象。

1706520776061.png

二、数据取用方法

  • 获取对象类型变量内包含的数据方法是用英文句号隔开,而当包含的是另一个对象时,只需在应用英文句号隔开即可,例子如下:
    # 打印可用的资金
    print(context.portfolio.available_cash)
    # 打印运行的频率
    print(context.run_params.frequency)
    # 打印当前时间的开始时间
    print(context.current_dt)

    # 执行后日志内容如下
    # 1000000.0
    # day
    # 2016-06-01 09:30:00

1706520776061.png
  • 当要获取的对象内的数据是另一种有结构的变量类型时,比如dict或者list,正常按照该变量类型进一步取用数据即可。例如context.portfolio.posiotions是一个dct,例子如下,这次给出完整代码:
# context.portfolio.positions的含义是仓位信息,需要在取之前买入并持有股票

def initialize(context):
    run_daily(period, time='every_bar')
    g.security = '000001.XSHE'

def period(context):
    order(g.security, 100)
    # 打印所有键
    print(context.portfolio.positions.keys())
    # 打印所有值
    print(context.portfolio.positions.values())
    # 打印g.security的开仓均价
    print(context.portfolio.positions[g.security].avg_cost)

    # 执行后日志内容如下
    # ['000001.XSHE']
    # [UserPosition({'avg_cost': 8.539999999999997, 'security': '000001.XSHE', 'closeable_amount':    0, 'price': 8.53, 'total_amount': 100})]
    # 8.54

常用的context数据写法如下,推荐自己动手试一下

  • 当前时间 context.current_dt
  • 当前时间的“年-月-日”的字符串格式 context.current_dt.strftime("%Y-%m-%d")
  • 前一个交易日 context.previous_date
  • 当前可用资金 context.portfolio.available_cash
  • 持仓价值 context.portfolio.positions_value
  • 累计收益 context.portfolio.returns
  • 当前持有股票 context.portfolio.positions.keys()
  • 当前持有的某股票的开仓均价 context.portfolio.positions['xxxxxx.xxxx'].avg_cost
  • 当前持有的某股票的可卖持仓量 context.portfolio.positions['xxxxxx.xxxx'].closeable_amount

三、条件判断

能够获取context的数据后,我们会考虑利用这些数据丰富策略的逻辑,但在此之前我们还要学习if条件判断语句,如下:

    # 如果 条件1成立为 True 将执行代码块1
    # 如果 条件1不成立为False,将判断条件2
    # 如果 条件2成立为 True 将执行代码块2
    # 如果 条件2还不成立为False,将执行代码块3

    if 条件1:
        代码块1
    elif 条件2:
        代码块2
    else:
        代码块3

    # 注意
    # elif 可以有多个连续写
    # 且elif和else都可以省略
    # 条件判断语句中可以嵌套条件判断语句

举几个例子:

    # 打印a、b中最大值
    if a>=b:
        print(a)
    else:
        print(b)

    # 判断a的正负性   
    if a>0:
        print('正')
    elif a<0:
        print('负')
    elif a==0:
        print('零')

    # 如果当前是2018-05-04,则下单买入100股平安银行
    date=context.current_dt.strftime("%Y-%m-%d")
    if date=='2018-05-04':
        order('000001.XSHE',100)

    # 判断a大小情况
    if a>0:
        if a<1:
            print('a大于0且小于1')
        else:
            print('a大于等于1')
    else:
        print('a小于等于0')

条件判断语句比较简单,但还需说明的是条件的写法中用到的运算符:

    # 写条件常用运算符:
    # < 小于
    # > 大于
    # <= 小于等于
    # >= 大于等于
    # == 等于
    # != 不等于
    # and 与,即and两边条件同为真,则真
    # or 或,即or两边条件任意一个为真,则真
    # not 非,即not右侧条件为真,则假,not右侧条件为假,则真

    # 以判断a是否为0的几个写法为例
    # 写法1
    if a!=0:
        print('否')
    else:
        print('是')
    # 写法2    
    if a>0 or a<0:
        print('否')
    else:
        print('是')
    # 写法2    
    if a>=0 and a=<0:
        print('是')
    else:
        print('否')
    # 写法3   
    if not a==0:
        print('否')
    else:
        print('是')

四、止损

  • 狭义的止损是指当亏损达到一定幅度后下单卖出该股票的操作,目的是减少进一步的亏损。广义则指在狭义的思路上衍生的复杂的减少亏损的方法。
  • 更多的情况下指狭义的止损。综合运用前文的讲过的内容我们已经可以实现当亏损达到一定幅度后下单卖出该股票的止损操作了。

通过context的数据可以得到持有股票的成本和现价,从而可以算出该股票的盈亏情况,运用条件判断语句根据盈亏情况从而决定是否卖出股票,从而实现止损操作,代码如下:

    def initialize(context):
        run_daily(period,time='every_bar')
        g.security = '000001.XSHE'

    def period(context):
        # 买入股票
        order(g.security, 100)
        # 获得股票持仓成本
        cost=context.portfolio.positions['000001.XSHE'].avg_cost
        # 获得股票现价
        price=context.portfolio.positions['000001.XSHE'].price
        # 计算收益率
        ret=price/cost-1
        # 打印日志
        print('成本价:%s' % cost)
        print('现价:%s' % price)
        print('收益率:%s' % ret)
        # 如果收益率小于-0.01,即亏损达到1%则卖出股票,幅度可以自己调,一般10%
        if ret<-0.01:
            order_target('000001.XSHE',0)
            print('触发止损')

  • 设置回测时间为从2017-03-01到2017-03-31,初始资金为100000,频率为天。回测发现会在2017-03-20触发止损。

五、未完待续

下章将继续介绍context中的数据和条件判断。

欢迎关注知乎:北京不北

欢迎+V:beijing_bubei

欢迎关注douyin:near.X (北京不北)

获得技术答疑,长期技术交流。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,104评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,816评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,697评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,836评论 1 298
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,851评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,441评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,992评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,899评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,457评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,529评论 3 341
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,664评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,346评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,025评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,511评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,611评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,081评论 3 377
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,675评论 2 359

推荐阅读更多精彩内容