Python之關於量化投資實現代碼--根據策略提出的代碼--還未完善

  1 # 根據缺口的模式選股買股票
  2 '''
  3 --------------------------------------------
  4 一、整體回測前要作的事情
  5     initialize(context)
  6     1.一、設置策略參數 ----> 全局常量
  7     1.二、設置中間變量 ----> 全局變量
  8     1.三、設置回測條件 ----> JoinQuant額外須要的
  9 二、天天開盤前選股策略 (下面策略,發現這種股,不容錯過)
 10     2.一、設置手續費
 11     2.二、設置可行股票池,好比過濾當日停牌股票
 12     2.三、篩選上市滿一年的所有A股
 13     2.四、篩選上市發生向上缺口的時點
 14        定義爲:今日最低價>昨日最高價,刪除漲停的個股
 15        漲幅>5%
 16     2.五、篩選前期盤整階段,好比20-30個交易日,最高價-最低價/最低價<15%或者標準差較少的
 17     2.六、缺口當日成交量 > 前20個交易日平均成交量的50%,也就是15倍以上。
 18 三、天天交易時
 19     3.一、買入/賣出信號判斷 
 20     3.二、執行買入/賣出的操做
 21 四、天天收盤
 22  23 
 24 --------------------------------------------
 25 關於何時賣?
 26  策略有三,第一個就是設置止盈位。也就是不須要追求最高點賣出。
 27  好比你設置一個從最近高點下滑3%(比例自調)的位置做爲賣出點。
 28  第二個就是利用技術分析,看重要的壓力位,一方面是均線系統的壓力,
 29  要看的是日線,周線月線,週期越大,壓力越強,其次是前期的高點,
 30  密集成交區,這個區域是深度套牢區,所以能夠暫時止盈。
 31  還有就是識技術指標的圖,好比看MACD頂背離,這個比較準,KDJ超賣等等。
 32  建議多去分析大盤,80%的股票和大盤會保存同樣走勢,大盤觸頂,個股通常也好不到哪去。
 33  第三就是關注基本面,同行對比,分析當前的股價的PE,以及與同行業的公司來看,
 34  好比營業總收入排第幾,淨利潤排第幾,收入增速排第幾,它的總市值排在第幾。
 35  若是基本面排在行業第10,可是市值排在第一,這就表示高估了。能夠擇機止盈。
 36  
 37 '''
 38 
 39 
 40 #
 41 import jqdata
 42 import pandas as pd
 43 import datetime as dt
 44 import time
 45 
 46 '''
 47 ================================================================================
 48 整體回測前
 49 ================================================================================
 50 '''
 51 # 初始化函數,設定基準等等
 52 def initialize(context):
 53     print '初始化方法'
 54     set_params()                             # 設置策略常量
 55     set_variables()                          # 設置中間變量
 56     set_backtest()                           # 設置回測條件
 57     print '--------------------------------------'
 58     
 59 #1 
 60 #設置策略參數
 61 def set_params():
 62     print '設置策略參數'   
 63     g.tc = 15                                # 調倉天數
 64     g.num_stocks = 10                        # 每次調倉選取的最大股票數量
 65 
 66 #2
 67 #設置中間變量
 68 def set_variables():
 69     print '設置中間變量'
 70     g.t = 0                                  # 記錄回測運行的天數
 71     g.if_trade = False                       # 當天是否交易
 72 
 73 #3
 74 #設置回測條件
 75 def set_backtest():
 76     print '設置回測條件'
 77     
 78     # 設定滬深300做爲基準,就是基準收益
 79     set_benchmark('000300.XSHG')
 80     
 81     
 82     # 開啓動態復權模式(真實價格)
 83     set_option('use_real_price', True)
 84     # 輸出內容到日誌 log.info()
 85     log.info('初始函數開始運行且全局只運行一次')
 86     # 過濾掉order系列API產生的比error級別低的log
 87     # log.set_level('order', 'error')
 88     
 89     ### 股票相關設定 ###
 90     # 股票類每筆交易時的手續費是:買入時佣金萬分之三,賣出時佣金萬分之三加千分之一印花稅, 每筆交易佣金最低扣5塊錢
 91     set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
 92     
 93     ## 運行函數(reference_security爲運行時間的參考標的;傳入的標的只作種類區分,所以傳入'000300.XSHG'或'510300.XSHG'是同樣的)
 94       # 開盤前運行
 95     run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') 
 96       # 開盤時運行
 97     run_daily(market_open, time='every_bar', reference_security='000300.XSHG')
 98       # 收盤後運行
 99     run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')
100     
101     log.set_level('order','error')           # 設置報錯等級
102     
103 '''
104 ================================================================================
105 天天開盤前
106 ================================================================================
107 二、天天開盤前選股策略 (下面策略,發現這種股,不容錯過)
108     2.一、設置手續費
109     2.二、設置可行股票池,好比過濾當日停牌股票
110     2.三、篩選上市滿一年的所有A股
111     2.四、篩選上市發生向上缺口的時點
112        定義爲:今日最低價>昨日最高價,刪除漲停的個股
113        漲幅>5%
114     2.五、篩選前期盤整階段,好比20-30個交易日,最高價-最低價/最低價<15%或者標準差較少的
115     2.六、缺口當日成交量 > 前20個交易日平均成交量的50%,也就是15倍以上。
116 '''
117 ## 開盤前運行函數     
118 def before_market_open(context):
119     # 輸出運行時間
120     log.info('函數運行時間(before_market_open):'+str(context.current_dt.time()))
121 
122     print '----天天開盤前要作的事情----'
123 
124     set_slip_fee(context)                    # 設置滑點與手續費
125     # g.stocks=get_index_stocks('000300.XSHG') # 設置滬深300爲初始股票池 
126     g.stocks=get_index_stocks('000002.XSHG') # 設置000002.XSHG所有上市A股
127     # 設置可行股票池
128     g.feasible_stocks = set_feasible_stocks(g.stocks,context)
129 
130 
131     # 給微信發送消息(添加模擬交易,並綁定微信生效)
132     # send_message('美好的一天~')
133 
134     # 要操做的股票:平安銀行(g.爲全局變量)
135     # g.security = '000001.XSHE'
136 
137 #
138 # 設置可行股票池:過濾掉當日停牌的股票
139 # 輸入:initial_stocks爲list類型,表示初始股票池; context(見API)
140 # 輸出:unsuspened_stocks爲list類型,表示當日未停牌的股票池,即:可行股票池
141 def set_feasible_stocks(initial_stocks,context):
142     # 判斷初始股票池的股票是否停牌,返回list
143     # print '設置可行股票池:過濾掉當日停牌的股票',context.current_dt.day
144     # print '當前時期%10s' %(context.current_dt.strftime("%Y-%m-%d"))
145     paused_info = []# 存儲對應股票是否停牌的信息數組
146     liste_Date_info = []# 存儲對應的上市時間
147     # 在股票基本信息表 - STK_STOCKINFO能找到
148     stock_info = get_all_securities(['stock']);
149     
150     
151     # get_current_data ♠ - 獲取當前時間數據
152     current_data = get_current_data()
153     print '打印--',initial_stocks
154     print '再打印--當前時間數據對象返回是空的',current_data
155     
156     for i in initial_stocks:
157         # i是遍歷出來的每一個股票的代碼
158         # 而後paused是判斷這個股票是否停牌,False表示沒有停牌
159         paused_info.append(current_data[i].paused)
160         
161         # print '獲取全部股票數據',stock_info[i].start_date
162         # 如何獲取上市滿一年的股票
163         # 先獲取全部股票數據 .start_data
164         # print '當前時期:%10s--股票上市時期:%10s' %(context.current_dt.strftime("%Y-%m-%d"),stock_info.at[i,'start_date'])
165         # print '當前時期:%10s--股票上市時期' %((stock_info.at[i,'start_date']-context.current_dt).days)
166         # 存儲上市時間是否滿一年,若是滿一年爲YES
167         isGoPublicOneYear = calculate_goPublick_OneYear(context.current_dt.strftime("%Y-%m-%d"),str(stock_info.at[i,'start_date']))
168         liste_Date_info.append(isGoPublicOneYear)
169         if isGoPublicOneYear == False:
170             print '上市不滿一年的股票%10s:%10s' %(i,stock_info.at[i,'display_name'])
171         
172         
173     df_paused_public_info = pd.DataFrame({'paused_info':paused_info,'liste_Date_info':liste_Date_info},index = initial_stocks)
174     # print 'df_paused_public_info:\n',df_paused_public_info
175     unsuspened_stocks = list(df_paused_public_info.index[(df_paused_public_info.paused_info == False) and (df_paused_public_info.liste_Date_info == True)])
176     
177     # print '最後得到的index',unsuspened_stocks
178     
179     
180     
181 
182     return unsuspened_stocks
183     
184 # 計算當天交易時間是否爲上市時間滿一年
185 def calculate_goPublick_OneYear(currentTime,goPublicTime):
186     currentTimeDate = time.strptime(currentTime,"%Y-%m-%d")
187     y,m,d = currentTimeDate[0:3]
188 
189     goPublicTimeDate = time.strptime(goPublicTime,"%Y-%m-%d")
190     y2,m2,d2 = goPublicTimeDate[0:3]
191     
192     # print (dt.datetime(y,m,d)-dt.datetime(y2,m2,d2)).days
193     
194     if ((dt.datetime(y,m,d)-dt.datetime(y2,m2,d2)).days)>366:
195         return True
196     else:
197         return False
198     
199     
200 #5
201 # 根據不一樣的時間段設置滑點與手續費
202 # 輸入:context(見API)
203 # 輸出:none
204 def set_slip_fee(context):
205     print '根據不一樣的時間段設置滑點與手續費'
206     # 將滑點設置爲0
207     set_slippage(FixedSlippage(0)) 
208     # 根據不一樣的時間段設置手續費
209     print '根據不一樣的時間段設置手續費'
210     dt=context.current_dt
211     if dt>datetime.datetime(2013,1, 1):
212         set_commission(PerTrade(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) 
213         
214     elif dt>datetime.datetime(2011,1, 1):
215         set_commission(PerTrade(buy_cost=0.001, sell_cost=0.002, min_cost=5))
216             
217     elif dt>datetime.datetime(2009,1, 1):
218         set_commission(PerTrade(buy_cost=0.002, sell_cost=0.003, min_cost=5))
219     else:
220         set_commission(PerTrade(buy_cost=0.003, sell_cost=0.004, min_cost=5))
221 
222 
223 '''
224 ================================================================================
225 天天交易時
226 ================================================================================
227 '''
228 ## 開盤時運行函數
229 def market_open(context):
230     log.info('函數運行時間(market_open):'+str(context.current_dt.time()))
231     security = g.security
232     # 獲取股票的收盤價
233     close_data = attribute_history(security, 5, '1d', ['close'])
234     # 取得過去五天的平均價格
235     MA5 = close_data['close'].mean()
236     # 取得上一時間點價格
237     current_price = close_data['close'][-1]
238     # 取得當前的現金
239     cash = context.portfolio.available_cash
240 
241     # 若是上一時間點價格高出五天平均價1%, 則全倉買入
242     if current_price > 1.01*MA5:
243         # 記錄此次買入
244         log.info("價格高於均價 1%%, 買入 %s" % (security))
245         # 用全部 cash 買入股票
246         # order_value(security, cash)
247     # 若是上一時間點價格低於五天平均價, 則空倉賣出
248     elif current_price < MA5 and context.portfolio.positions[security].closeable_amount > 0:
249         # 記錄此次賣出
250         log.info("價格低於均價, 賣出 %s" % (security))
251         # 賣出全部股票,使這隻股票的最終持有量爲0
252         # order_target(security, 0)
253 
254 '''
255 ================================================================================
256 天天收盤後
257 ================================================================================
258 '''
259 
260 ## 收盤後運行函數  
261 def after_market_close(context):
262     log.info(str('函數運行時間(after_market_close):'+str(context.current_dt.time())))
263     #獲得當天全部成交記錄
264     trades = get_trades()
265     for _trade in trades.values():
266         log.info('成交記錄:'+str(_trade))
267     log.info('一天結束')
268     log.info('##############################################################')
相關文章
相關標籤/搜索