V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
thinkingmind
V2EX  ›  推广

看的第一个量化策略,闲的无聊,加了注释,共享一下

  •  
  •   thinkingmind · 2016-07-05 15:20:30 +08:00 · 3874 次点击
    这是一个创建于 3092 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家可以看一下,来这里跑起来看看

    
    # 可以自己 import 我们平台支持的第三方 python 模块,比如 pandas 、 numpy 等。
    import math
    import numpy as np
    import pandas as pd
    import talib
    # 在这个方法中编写任何的初始化逻辑。 context 对象将会在你的算法策略的任何方法之间做传递。
    def init(context):   #初始化全局变量,相当于 main()
        context.number=10       #选取十只股
        context.period = 20        #定义 XXXXX 周期为 20
        context.SMAPERIOD = 5     #定义 XXXXX 周期为 5
        context.marketval = context.portfolio.market_value
        context.stocks = sector('信息技术')     #定义所选板块
        update_universe(context.stocks)     #更新股票池
        scheduler.run_monthly(get_head,monthday=1)         #get_head 函数每月 1 日运行一次,选股算法
        scheduler.run_monthly(position,monthday=1)           #position 函数每月 1 日运行一次,调整持仓
        scheduler.run_daily(stoploss)             #stoploss 函数每天运行一次,止损函数
        
    def get_head(context,bar_dict):                #选股算法!找龙头, get_head (),每月运行一次
        prices = history(context.period+1,'1d','close')    #将历史数据放入 prices 中, pandas 类型。 context.period 是回溯的数量、 1d 是按照日线回溯、 close 是收盘价。 context.period 是回溯的时间周期 20 天
        b_prices = history(6, '1d', 'close')[context.benchmark].values     #回溯当前时间往后推 6 天,
        volumes = history(context.period+1,'1d','volume')        #成交量放入 volumes
        score = {}            #初始化 score{}
        for stock in prices.columns:       #逐一轮询 prices 的行, stock 是行号
            p = prices[stock]
            v = volumes[stock]
            temp = 0
            for i in list(range(1,context.period)):       #1 到 20 ,轮询 20 天
                if p[i] > p[i-1]:                                        
                    if v[i] > v[i-1]:
                        temp = temp + 2         #价升量升 +2
                    else:
                        temp = temp + 1         #价升量跌 +1
                else:
                    if v[i] < v[i-1]:
                        temp = temp - 1           #价跌量升 -1    
                    else:
                        temp = temp - 2            #价跌量跌 -2 
            score[stock] = temp                   #将决策值存入 score 的序列中
        s = pd.Series(score,name = 'scores')        #把 score 和 name 放入 series 中
        s.sort(ascending=False)         #按照降序排列
        context.to_buy = s.index[0:context.number]   #to_buy , 1 到 10 号的股票放入
        if b_prices[0]/b_prices[4] <= 0.92:          #大盘调整 8%,将 context.to_buy 值为空
            context.to_buy = []
            
    def position(context,bar_dict):        #仓位变更算法,每月运行一次,
        stocks = set(context.to_buy)        #将 get_head 选出的股票 set 到 stocks 中
        holdings = set(get_holdings(context))      #读取持有的股票
        to_buy = stocks - holdings                #读取要买入的股票
        holdings = set(get_holdings(context))            #读取持有的股票
        to_sell = holdings - stocks            #读取要卖出的股票
        for stock in to_sell:            #卖出
            if bar_dict[stock].is_trading:        #判断 stock 是否可以交易(停牌)
                order_target_percent(stock , 0)    #将 stock 的仓位调整为“ 0%” order_target_percent 按照百分比调整仓位
        to_buy = get_trading_stocks(to_buy, context, bar_dict)      #调用下文中的函数 get_trading_stocks ,去除不能交易的票
        cash = context.portfolio.cash        #cash 是现在投资组合中的剩余的金额
        average_value = 0
        if len(to_buy) > 0:
            average_value = 0.98 * cash / len(to_buy)                #98%的仓位平均到 to_buy 的所有股票, len(to_buy)
        for stock in to_buy:            #买入 to_buy 的股票
            if bar_dict[stock].is_trading:            #判断 stock 是否可以交易(停牌)
                order_value(stock ,average_value)     #将 stock 的仓位调整至 average_value 数
        context.marketval = context.portfolio.market_value     #当前投资组合的市值
        
    def get_trading_stocks(to_buy, context, bar_dict):       #重新计算 to_buy 中的股票,去掉不能交易的股票
        trading_stocks = []
        for stock in to_buy:       # 在 to_buy 中循环
            if bar_dict[stock].is_trading:       #判断 stock 是否可以交易(停牌)
                trading_stocks.append(stock)            
        return trading_stocks
    
    def get_holdings(context):                #读取持有的股票
        positions = context.portfolio.positions    #读取当前持仓, positions    所有仓位的字典
        
        holdings = []
        for position in positions:
            if positions[position].quantity > 0:            #quantity 未平仓部分的全部股数大于零
                holdings.append(position)
        return holdings
        
    def stoploss(context,bar_dict):         #止损策略
        if context.portfolio.market_value < context.marketval * 0.95:      #context.marketval 当月初市值, context.portfolio.market_value 当前市值
            for stock in context.portfolio.positions:      #清仓, context.portfolio.positions 所有持仓
                if bar_dict[stock].is_trading:
                    order_target_value(stock,0)            #将 stock 的仓位调整为“ 0%”
    
    
    4 条回复    2017-11-21 13:59:14 +08:00
    GreatMartial
        1
    GreatMartial  
       2016-07-05 15:42:24 +08:00 via Android
    前排关注一波
    zingl
        2
    zingl  
       2016-07-05 15:43:49 +08:00
    上真金白银成交图
    bigtan
        3
    bigtan  
       2016-07-05 15:46:36 +08:00
    回测时间短,大部分涨幅由股灾之前的泡沫贡献,从净值曲线看,目前应该还在回撤里面没有出来。结论就是,看看就行。
    sunnyGo
        4
    sunnyGo  
       2017-11-21 13:59:14 +08:00
    我认为 目前 A 股市场 完全不适合做量化,期货市场 更适合些。就策略而言,趋势策略万变不离趋势跟踪 这个类型,经典的例子 就是 海龟交易法, 圣杯是天天变换形态的。不要迷信 算法 方法,适应市场规律 才是王道。类似的策略我在 BotVS 量化平台上 写过好多, 不论模拟盘测试 还是 回测,甚至 实盘,发现 和海龟 都是一个模式。 趋势来了只要是 趋势跟踪类型的都会开仓,早晚而已。 有行情来了,就是个简单的双均线一样 可以赚钱。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1130 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 23:38 · PVG 07:38 · LAX 15:38 · JFK 18:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.