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


  1 # 根據缺口的模式選股買股票
  2 '''
  3 --------------------------------------------
  4 1、總體回測前要做的事情
  5     initialize(context)
  6     1.1、設置策略參數 ----> 全局常量
  7     1.2、設置中間變量 ----> 全局變量
  8     1.3、設置回測條件 ----> JoinQuant額外需要的
  9 2、每天開盤前選股策略 (下面策略,發現這種股,不容錯過)
 10     2.1、設置手續費
 11     2.2、設置可行股票池,比如過濾當日停牌股票
 12     2.3、篩選上市滿一年的全部A股
 13     2.4、篩選上市發生向上缺口的時點
 14        定義為:今日最低價>昨日最高價,刪除漲停的個股
 15        漲幅>5%
 16     2.5、篩選前期盤整階段,比如20-30個交易日,最高價-最低價/最低價<15%或者標准差較少的
 17     2.6、缺口當日成交量 > 前20個交易日平均成交量的50%,也就是15倍以上。
 18 3、每天交易時
 19     3.1、買入/賣出信號判斷 
 20     3.2、執行買入/賣出的操作
 21 4、每天收盤
 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 2、每天開盤前選股策略 (下面策略,發現這種股,不容錯過)
108     2.1、設置手續費
109     2.2、設置可行股票池,比如過濾當日停牌股票
110     2.3、篩選上市滿一年的全部A股
111     2.4、篩選上市發生向上缺口的時點
112        定義為:今日最低價>昨日最高價,刪除漲停的個股
113        漲幅>5%
114     2.5、篩選前期盤整階段,比如20-30個交易日,最高價-最低價/最低價<15%或者標准差較少的
115     2.6、缺口當日成交量 > 前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('##############################################################')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM