经过两周的时间,在老虎证券开放api基础上起一个策略,上穿20日均线买入,下穿20日均线卖出,标普500股票池,运行在阿里云上。用crontab定时,美股开盘前运行。策略文件夹下需要有sp500code.dat保存着标普500股票代码,也可以每次运行的时候去维基百科爬取。
# -*- coding: utf-8 -*-
"""
Created on 2018/9/20
@author: gaoan
"""
import logging
import traceback
import pandas as pd
import talib as ta
import re
import math
import threading
import time
import sys
import signal
from datetime import datetime
#账户设置包导入
from tigeropen.examples.client_config import get_client_config
#交易包导入
from tigeropen.trade.domain.order import ORDER_STATUS
from tigeropen.trade.request.model import AccountsParams
from tigeropen.common.response import TigerResponse
from tigeropen.tiger_open_client import TigerOpenClient
from tigeropen.trade.trade_client import TradeClient
from tigeropen.quote.request import OpenApiRequest
from tigeropen.common.util.contract_utils import option_contract, future_contract
#行情包导入
from tigeropen.examples.sp500 import save_sp500_tickers as getsp500code
from tigeropen.common.consts import Market, QuoteRight, BarPeriod,Language
from tigeropen.quote.quote_client import QuoteClient
#判断可以买入的股票代码
buy_set=set()
#判断可以卖出的股票代码
sell_set=set()
#当前持仓股票代码和数量的字典
cur_quant={}
goal=5
#日志设置
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s',
filemode='a', )
logger = logging.getLogger('TigerOpenApi')
#客户端设置
client_config = get_client_config()
#定义交易客户端
openapi_client = TradeClient(client_config, logger=logger)
#定义行情客户端
quote_client = QuoteClient(client_config, logger=logger)
#获取标普500的20日bars
def get_price(bars_num):
stocks = read_sp_500code()
df=pd.DataFrame(columns=['symbol','time','open','high','low','close','volume'])
#每次取数据要取的条目数量
items=math.floor(1000/bars_num)
stock_num=len(stocks)
print(stock_num)
roundtrip=math.floor(stock_num/items)
print(roundtrip)
for i in range(roundtrip):
bars = quote_client.get_bars(stocks[i*items:i*items+items],period=BarPeriod.DAY,begin_time=-1, end_time=-1,right=QuoteRight.BR,limit=bars_num)
df=df.append(bars,ignore_index=True)
print(bars)
bars = quote_client.get_bars(stocks[stock_num-roundtrip*items:stock_num],\
period=BarPeriod.DAY,begin_time=-1,end_time=-1,right=QuoteRight.BR,limit=bars_num)
df=df.append(bars,ignore_index=True)
return(df)
def generate_trade_info():
stocks = read_sp_500code()
prices=get_price(20)
print(prices)
ave=[]
buy_set.clear()
sell_set.clear()
for i in range(len(stocks)):
price=prices[i*20:i*20+20]['close'].values
mai=ta.MA(price,timeperiod=20,matype=0)
ave.append(mai[-1])
print(ave)
for i in range(len(stocks)):
price=prices[i*20:i*20+20]['close'].values
if price[-2]<ave[i] and price[-1]>ave[i]:
buy_set.add(stocks[i])
elif price[-2]>ave[i] and price[-1]<ave[i]:
sell_set.add(stocks[i])
print(buy_set)
print(sell_set)
def trade():
#generate_trade_info()
account = client_config.paper_account
curset=get_curset(account)
print(curset)
tosell=curset & sell_set
tosell_list=list(tosell)
print(tosell_list)
market_status_list = quote_client.get_market_status(Market.US)
#print(market_status_list)
#print(type(market_status_list))
'''
if market_status_list[0].status=='Not Yet Open':
print('市场还没有开始交易')
return
'''
#卖出股票
for i in range(len(tosell_list)):
contract = openapi_client.get_contracts(tosell_list[i])[0]
order = openapi_client.create_order(account, contract, 'SELL', 'MKT' , cur_quant(tosell_list[i]))
openapi_client.place_order(order)
curset=get_curset(account)
print(buy_set)
tobuy=buy_set-curset
tobuy_list=list(tobuy)
#变成列表后会产生排序,这个顺序是默认的
print(tobuy_list)
tofill=goal-len(curset)
print(tofill)
tofill= min(tofill,len(tobuy_list))
cur_asset=openapi_client.get_assets(account=account)
potfolio=cur_asset[0]
cash=potfolio.summary.available_funds*0.01
print("Cash",cash)
if tofill>0:
for i in range(tofill):
contract = openapi_client.get_contracts(tobuy_list[i])[0]
#print(contract)
#print(type(tobuy_list[i]))
#print(tobuy_list[i])
brief=quote_client.get_briefs(symbols=[tobuy_list[i]],right=QuoteRight.BR)
latest_price=brief[0].latest_price
order = openapi_client.create_order(account, contract, 'BUY', 'MKT' , math.floor(cash/tofill/latest_price))
print('buy order sent')
openapi_client.place_order(order)
#position对象:[contract: TVIX/STK/USD, quantity: 5, average_cost: 36.0764, market_price: 0.0]
def get_curset(account):
pos=openapi_client.get_positions(account=account)
print(len(pos))
curset=set()
cur_quant={}
for i in range(len(pos)):
print('当前持仓\n',pos[i])
cont=pos[i].contract
code = re.search(r'[A-Z]*(?=/STK)',str(cont)).group(0)
curset.add(code)
cur_quant[code]=pos[i].quantity
return curset
#卖出当前所有持仓
def all_off(account):
pos=openapi_client.get_positions(account=account)
for i in range(len(pos)):
contract=pos[i].contract
quantity=pos[i].quantity
if quantity>0:
order = openapi_client.create_order(account, contract, 'SELL', 'MKT' , quantity)
openapi_client.place_order(order)
elif quantity<0:
order = openapi_client.create_order(account, contract, 'BUY', 'MKT' , -quantity)
openapi_client.place_order(order)
def read_sp_500code():
infile = open('sp500code.dat','r')
incontent = infile.read()
incontent=incontent.lstrip('[')
incontent=incontent.rstrip(']')
stocks = incontent.split(', ')
new= []
for i in range(len(stocks)):
new.append(eval(stocks[i]))
return new
def before_market_open():
generate_trade_info()
#Not Yet Open, Pre Market Trading, Market Trading
if __name__ == '__main__':
p = threading.Thread(target=before_market_open)
p.setDaemon(True)
p.start()
time.sleep(10)
p.join()
while True:
time.sleep(1)
market_status_list = quote_client.get_market_status(Market.US)
print(market_status_list)
if market_status_list[0].status == 'Trading':
trade()
break
#get_curset(client_config.paper_account)
#all_off(client_config.paper_account)