#-*- coding:utf-8 -*-
from appium import webdriver
from selenium.webdriver.common.by import By
from appium.webdriver.extensions.android.nativekey import AndroidKey
import time
from datetime import datetime
import time
from datetime import timedelta
import csv
from selenium.common.exceptions import NoSuchElementException
from appium.webdriver.common.touch_action import TouchAction
import pandas as pd
from bs4 import BeautifulSoup
import requests
import re
import numpy as np
import backtrader as bt
desired_caps = {
'platformName': 'Android', # 被测手机是安卓
'platformVersion': '10', # 手机安卓版本
'deviceName': 'xxx', # 设备名,安卓手机可以随意填写
'appPackage': 'com.eg.android.AlipayGphone', # 启动APP Package名称
'appActivity': '.AlipayLogin', # 启动Activity名称
'unicodeKeyboard': True, # 使用自带输入法,输入中文时填True
'resetKeyboard': True, # 执行完程序恢复原来输入法
'noReset': True, # 不要重置App
'newCommandTimeout': 6000,
'automationName' : 'UiAutomator2',
'skipServerInstallation':True
# 'app': r'd:apkbili.apk',
}
# 连接Appium Server,初始化自动化环境
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
# 设置缺省等待时间
driver.implicitly_wait(10)
def data():
#下拉列表
driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[6]/android.view.View').click()
time.sleep(2)
#基金编码
ele0=driver.find_element(By.XPATH,'//android.webkit.WebView/android.view.View/android.view.View/android.view.View[2]')
#持仓金额
ele1=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[2]/android.view.View[1]')
ele2=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[2]/android.view.View[2]')
#持有收益
ele7=driver.find_element(By.XPATH,'//android.view.View/android.view.View[5]/android.view.View[4]/android.view.View[1]')
ele8=driver.find_element(By.XPATH,'//android.view.View/android.view.View[5]/android.view.View[4]/android.view.View[2]/android.view.View')
#持仓成本价
ele3=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[4]/android.view.View[1]')
ele4=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[4]/android.view.View[2]')
#持仓份额
ele5=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[5]/android.view.View[1]')
ele6=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[5]/android.view.View[2]')
#基金净值
ele9=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[7]/android.view.View[1]')
ele10=driver.find_element(By.XPATH,'//android.view.View[5]/android.view.View[7]/android.view.View[7]/android.view.View[2]')
rate = float(ele2.text.replace(',','')) / 10000
print("基金代码:%s"%ele0.text,"持仓金额:%s"%ele2.text,"目标市值10000,当前仓位占比:%.2f"%rate,"持有收益:%s"%ele8.text,"持仓成本价:%s"%ele4.text,"基金净值:%s"%ele10.text,"持仓份额:%s"%ele6.text)
time.sleep(2)
# text=ele0.text
now = time.localtime(time.time())
# print(now,type(now)) #
# now = dt.datetime.now()
now_date = time.strftime("%Y-%m-%d", now) # 日期格式转字符串
# print(now_date)
end_date = datetime.strptime(now_date, "%Y-%m-%d") # 字符串转日期格式
# now_date_2 =datetime.combine(start_date,dt.time()) # 将’datetime.date’转换成’datetime.datetime
# print(type(now_date_2))
start_date = end_date - timedelta(days=360)
# date_180str_1 = datetime.strptime(date_180, "%Y-%m-%d")
# print(type(start_date), type(end_date))
# print(start_date, end_date)
#判断是星期几
k = end_date.isoweekday()
if k == 5:
print('今天是规定交易日')
else:
print('今天不是规定交易日,请遵守纪律!!!')
fund_df= get_fund(ele0.text, start_date=start_date, end_date=end_date)
i = len(fund_df['单位净值']) - 1
# print(i)
fund_now = fund_df.iloc[[i], [0]].values[0][0] # 今日基金净值
cri = 200 # 单次买入金额
withdraw = (fund_df.单位净值.max() - fund_now) / fund_df.单位净值.max()
# print(fund_now)
print('360天内距离最高点已经下跌:%.2f' % withdraw)
# print('180天内最大净值:' % np.quantile(fund_df['单位净值'],0.25))
# print('180天内最小净值:%.4f' % fund_df.单位净值.min())
# Dif =fund_df.单位净值.max()-fund_df.单位净值.min
Dif_17 = fund_df.单位净值.quantile(q=0.17) #
Dif_34 = fund_df.单位净值.quantile(q=0.34) #
Dif_51 = fund_df.单位净值.quantile(q=0.51) # > 51分位 1个基准买入
Dif_68 = fund_df.单位净值.quantile(q=0.68) #
Dif_84 = fund_df.单位净值.quantile(q=0.84) #
#仓位
fre =int(float(ele2.text.replace(',','')))
if fund_now < Dif_17:
buy_17 = cri * 3
if buy_17 < 300: # 单次买入不超过300元
print('当前处于360天内17分位以下,建议买入%d元' % buy_17)
buy_c(buy_17)
elif buy_17 > 300:
buy_17_0 = 300
print('当前处于360天内17分位以下,建议买入%d元' % buy_17_0)
buy_c(buy_17_0)
elif Dif_17 < fund_now < Dif_34:
buy_34 = cri * 2 # 单次买入不超过300元
print('当前处于360天内17-34分位,建议买入%d元' % buy_34)
buy_c(buy_34)
elif Dif_34 < fund_now < Dif_51:
buy_51 = cri * 1 # 单次买入不超过300元
print('当前处于360天内34-51分位,建议买入%d元' % buy_51)
buy_c(buy_51)
elif Dif_51 < fund_now < Dif_68:
buy_68 = cri * 0.5 # 单次买入不超过300元
print('当前处于360天内51-68分位,建议买入%d元' % buy_68)
elif Dif_68 < fund_now < Dif_84:
print('当前处于360天内68-84分位,建议卖出仓位的20%')
sell_c(int(0.2*fre))
elif fund_now > Dif_84:
print('当前处于360天内84分位以上,建议卖出仓位的50%')
sell_c(int(0.5*fre))
# print(fund_df)# 获取数据
# driver.find_element(By.XPATH,'//android.widget.TextView[@content-desc="返回"]').click()
# time.sleep(2)
# swipeDown(5000)
# return ele0.text
def get_html(code, start_date, end_date, page=1, per=20):
url = 'http://fund.eastmoney.com/f10/F10DataApi.aspx?type=lsjz&code={0}&page={1}&sdate={2}&edate={3}&per={4}'.format(
code, page, start_date, end_date, per)
rsp = requests.get(url)
html = rsp.text
return html
def buy_c(self):
# print(self)
choice = input('请确认是否买入%s元n'%self)
if choice == '1':
pass
# print('程序继续执行')
else:
return
Bai = self // 100
Shi = (self % 100) // 10
Ge = (self % 100) % 10
# 买入
# TouchAction(driver).press(x=925, y=2270).release().perform()
# time.sleep(1)
# swipeUp(4000)
# time.sleep(1)
# swipeUp(4000)
# driver.find_element(By.XPATH, '//android.view.View[@text="买入"]').click()
# time.sleep(2)
TouchAction(driver).press(x=925, y=2255).release().perform() #
time.sleep(1)
# 买入页面
driver.find_element(By.XPATH, '//android.view.View[3]/android.view.View[5]/android.view.View/android.view.View/android.view.View').click()
# box.send_keys('88')
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="%d"]'%Bai).click()
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="%d"]'%Shi).click()
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="%d"]'%Ge).click()
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="确定"]').click()
time.sleep(1)
try:
#check box
driver.find_element(By.XPATH, '//android.widget.CheckBox').click()
time.sleep(1)
except NoSuchElementException:
pass
#第二个确定键
TouchAction(driver).press(x=600, y=2220).release().perform()
time.sleep(1)
# driver.find_element(By.XPATH, '//android.view.View[9]/android.widget.Button').click()
# time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="继续操作"]').click()
time.sleep(2)
driver.find_element(By.ID, 'com.alipay.android.phone.seauthenticator.iotauth:id/btn').click()
time.sleep(1)
driver.keyevent(30) # KEYCODE_B 按键’B’ 30
driver.keyevent(32) # KEYCODE_D 按键’D’ 32
driver.keyevent(8) # KEYCODE_1 按键’1’ 8
driver.keyevent(16) # KEYCODE_9 按键’9’ 16
driver.keyevent(16) # KEYCODE_9 按键’9’ 16
driver.keyevent(12) # KEYCODE_5 按键’5’ 12
driver.keyevent(7) # KEYCODE_0 按键’0’ 7
driver.keyevent(12) # KEYCODE_5 按键’5’ 12
driver.keyevent(8) # KEYCODE_1 按键’1’ 8
driver.keyevent(11) # KEYCODE_4 按键’4’ 11
#确认
TouchAction(driver).press(x=545, y=1045).release().perform()
time.sleep(1)
driver.find_element(By.XPATH, '//android.widget.TextView[@content-desc="完成"]').click()
time.sleep(2)
print('已完成买入交易')
def sell_c(self):
# print(self)
choice = input('请确认是否卖出%s元n'%self)
if choice == '1':
pass
# print('程序继续执行')
else:
return
# 卖出
Bai = self // 100
Shi = (self % 100) // 10
Ge = (self % 100) % 10
TouchAction(driver).press(x=420, y=2255).release().perform() #
time.sleep(1)
#立即卖出
TouchAction(driver).press(x=315, y=1455).release().perform() #
time.sleep(1)
# 买入页面
driver.find_element(By.XPATH,'//android.view.View/android.widget.EditText').click()
# box.send_keys('88')
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="%d"]'%Bai).click()
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="%d"]'%Shi).click()
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="%d"]'%Ge).click()
time.sleep(1)
driver.find_element(By.XPATH, '//android.view.View[@text="确定"]').click()
time.sleep(1)
try:
# check box
driver.find_element(By.XPATH, '//android.widget.CheckBox').click()
time.sleep(1)
except NoSuchElementException:
pass
# 第二个确定键
TouchAction(driver).press(x=600, y=2220).release().perform()
time.sleep(1)
driver.find_element(By.ID, 'com.alipay.android.phone.seauthenticator.iotauth:id/btn').click()
time.sleep(1)
driver.keyevent(30) # KEYCODE_B 按键’B’ 30
driver.keyevent(32) # KEYCODE_D 按键’D’ 32
driver.keyevent(8) # KEYCODE_1 按键’1’ 8
driver.keyevent(16) # KEYCODE_9 按键’9’ 16
driver.keyevent(16) # KEYCODE_9 按键’9’ 16
driver.keyevent(12) # KEYCODE_5 按键’5’ 12
driver.keyevent(7) # KEYCODE_0 按键’0’ 7
driver.keyevent(12) # KEYCODE_5 按键’5’ 12
driver.keyevent(8) # KEYCODE_1 按键’1’ 8
driver.keyevent(11) # KEYCODE_4 按键’4’ 11
# 确认
TouchAction(driver).press(x=545, y=1045).release().perform()
time.sleep(1)
driver.find_element(By.XPATH, '//android.widget.TextView[@content-desc="完成"]').click()
time.sleep(2)
print('已完成卖出交易')
def get_fund(code, start_date, end_date, page=1, per=20):
# 获取html
html = get_html(code, start_date, end_date, page, per)
soup = BeautifulSoup(html, 'html.parser')
# 获取总页数
pattern = re.compile('pages:(.*),')
result = re.search(pattern, html).group(1)
total_page = int(result)
# 获取表头信息
heads = []
for head in soup.findAll("th"):
heads.append(head.contents[0])
# 数据存取列表
records = []
# 获取每一页的数据
current_page = 1
while current_page <= total_page:
html = get_html(code, start_date, end_date, current_page, per)
soup = BeautifulSoup(html, 'html.parser')
# 获取数据
for row in soup.findAll("tbody")[0].findAll("tr"):
row_records = []
for record in row.findAll('td'):
val = record.contents
# 处理空值
if val == []:
row_records.append(np.nan)
else:
row_records.append(val[0])
# 记录数据
records.append(row_records)
# 下一页
current_page = current_page + 1
# 将数据转换为Dataframe对象
np_records = np.array(records)
fund_df = pd.DataFrame()
for col, col_name in enumerate(heads):
fund_df[col_name] = np_records[:, col]
# 按照日期排序
fund_df['净值日期'] = pd.to_datetime(fund_df['净值日期'], format='%Y/%m/%d')
fund_df = fund_df.sort_values(by='净值日期', axis=0, ascending=True).reset_index(drop=True)
fund_df = fund_df.set_index('净值日期')
# 数据类型处理
fund_df['单位净值'] = fund_df['单位净值'].astype(float)
fund_df['累计净值'] = fund_df['累计净值'].astype(float)
fund_df['日增长率'] = fund_df['日增长率'].str.strip('%').astype(float)
return fund_df
def getSize(): #获取当前的width和height的x、y的值
x = driver.get_window_size()['width'] #width为x坐标
y = driver.get_window_size()['height'] #height为y坐标
# print(x,y)
return (x, y)
def swipeUp(t): #当前向上滑动swipeup
l = getSize()
x1 = int(l[0] * 0.5)
y1 = int(l[1] * 0.75)
y2 = int(l[1] * 0.25)
driver.swipe(x1, y1, x1, y2,500) #设置时间为500
# swipeUp(9000) #向上滑动9000
def swipLeft(t): #当前向左进行滑动swipleft
l=getSize()
x1=int(l[0]*0.75)
y1=int(l[1]*0.5)
x2=int(l[0]*0.05)
driver.swipe(x1,y1,x2,y1,500)
# swipLeft(3000) #向左滑行3000
def swipeDown(t): #向下滑动swipedown
l = getSize()
# print(l)
x1 = int(l[0] * 0.5)
y1 = int(l[1] * 0.25)
y2 = int(l[1] * 0.75)
driver.swipe(x1, y1, x1, y2,500)
def swipRight(t): #向右滑行swipright
l=getSize()
x1=int(l[0]*0.05)
y1=int(l[1]*0.5)
x2=int(l[0]*0.75)
driver.swipe(x1,y1,x2,y1,500)
# swipRight(3000) #向右滑行3000,回到初始位置
def fund(self):
width = driver.get_window_size()['width']
height = driver.get_window_size()['height']
i = 0
while i < 5:
try:
driver.find_element(By.XPATH,self).click()
time.sleep(2) # 尝试点击元素
data()
break
except NoSuchElementException:
driver.swipe(width / 2, height * 0.8, width / 2, height * 0.2) # 滑动屏幕
i = i + 1
#
def main():
# 首页
eles_1 = driver.find_elements(By.ID, 'com.alipay.android.tablauncher:id/tab_description')
eles_1[0].click()
time.sleep(2)
# 基金页
eles_2 = driver.find_elements(By.ID, 'com.alipay.android.widget.fortunehome:id/category_item_container')
eles_2[2].click()
time.sleep(2)
# 持有
driver.find_element(By.XPATH, '//android.widget.Button[@text="持有"]').click()
time.sleep(2)
# 基金名称
# self ='//android.view.View[@text="华夏恒生ETF联接(QDII)A"]'
# fund(self)
self2 = '//android.view.View[@text="交银海外中国互联网指数"]'
fund(self2)
self3 = '//android.view.View[@text="广发纳斯达克100ETF联接(QDII)A"]'
fund(self3)
# self1 ='//android.view.View[@text="华宝标普石油天然气上游股票指数(QDII-LOF)C"]'
# fund(self1)
if __name__ == '__main__':
main()