FinMind 1.2.8__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- finmind-2.0.0/FinMind/__init__.py +2 -0
- {FinMind-1.2.8 → finmind-2.0.0}/FinMind/_version.py +0 -1
- finmind-2.0.0/FinMind/crawler/__init__.py +2 -0
- FinMind-1.2.8/FinMind/Crawler/BasedClass.py → finmind-2.0.0/FinMind/crawler/base.py +18 -7
- FinMind-1.2.8/FinMind/Crawler/RawMaterialFuturesPrices.py → finmind-2.0.0/FinMind/crawler/commodities.py +37 -37
- finmind-2.0.0/FinMind/crawler/demo.py +32 -0
- FinMind-1.2.8/FinMind/Crawler/GovernmentBonds.py → finmind-2.0.0/FinMind/crawler/government_bonds.py +49 -50
- finmind-2.0.0/FinMind/data/__init__.py +5 -0
- finmind-2.0.0/FinMind/data/data_loader.py +2971 -0
- finmind-2.0.0/FinMind/data/data_subscriber.py +116 -0
- finmind-2.0.0/FinMind/data/finmind_api.py +425 -0
- finmind-2.0.0/FinMind/indicators/__init__.py +29 -0
- finmind-2.0.0/FinMind/indicators/bias.py +30 -0
- finmind-2.0.0/FinMind/indicators/continue_holding.py +14 -0
- finmind-2.0.0/FinMind/indicators/institutional_investors_follower.py +76 -0
- finmind-2.0.0/FinMind/indicators/institutional_investors_over_buy.py +56 -0
- finmind-2.0.0/FinMind/indicators/kd.py +34 -0
- finmind-2.0.0/FinMind/indicators/kd_crossover.py +62 -0
- finmind-2.0.0/FinMind/indicators/ma_cross_orver.py +69 -0
- finmind-2.0.0/FinMind/indicators/short_sale_margin_purchase_ratio.py +51 -0
- finmind-2.0.0/FinMind/plotting/__init__.py +4 -0
- finmind-2.0.0/FinMind/plotting/bar.py +65 -0
- finmind-2.0.0/FinMind/plotting/kline.py +402 -0
- finmind-2.0.0/FinMind/plotting/line.py +64 -0
- finmind-2.0.0/FinMind/plotting/pie.py +53 -0
- finmind-2.0.0/FinMind/schema/__init__.py +6 -0
- finmind-2.0.0/FinMind/schema/data.py +170 -0
- finmind-2.0.0/FinMind/schema/indicators.py +94 -0
- FinMind-1.2.8/FinMind/Schema/output.py → finmind-2.0.0/FinMind/schema/info.py +16 -5
- finmind-2.0.0/FinMind/schema/plot.py +56 -0
- finmind-2.0.0/FinMind/schema/rule.py +7 -0
- finmind-2.0.0/FinMind/strategies/__init__.py +29 -0
- finmind-2.0.0/FinMind/strategies/base.py +791 -0
- finmind-2.0.0/FinMind/strategies/bias.py +39 -0
- finmind-2.0.0/FinMind/strategies/continue_holding.py +22 -0
- finmind-2.0.0/FinMind/strategies/institutional_investors_follower.py +85 -0
- finmind-2.0.0/FinMind/strategies/kd.py +32 -0
- finmind-2.0.0/FinMind/strategies/kd_crossover.py +26 -0
- finmind-2.0.0/FinMind/strategies/ma_crossover.py +35 -0
- finmind-2.0.0/FinMind/strategies/macd_crossover.py +51 -0
- finmind-2.0.0/FinMind/strategies/max_min_period_bias.py +62 -0
- finmind-2.0.0/FinMind/strategies/naive_kd.py +39 -0
- finmind-2.0.0/FinMind/strategies/short_sale_margin_purchase_ratio.py +111 -0
- finmind-2.0.0/FinMind/strategies/utils.py +50 -0
- finmind-2.0.0/FinMind/templates/post.html +27 -0
- finmind-2.0.0/FinMind/utility/request.py +156 -0
- finmind-2.0.0/FinMind/utility/rule.py +20 -0
- finmind-2.0.0/LICENSE +201 -0
- finmind-2.0.0/PKG-INFO +399 -0
- finmind-2.0.0/README.md +158 -0
- finmind-2.0.0/finmind.egg-info/PKG-INFO +399 -0
- finmind-2.0.0/finmind.egg-info/SOURCES.txt +57 -0
- finmind-2.0.0/finmind.egg-info/requires.txt +19 -0
- finmind-2.0.0/finmind.egg-info/top_level.txt +4 -0
- finmind-2.0.0/pyproject.toml +64 -0
- finmind-2.0.0/setup.py +5 -0
- FinMind-1.2.8/FinMind/BackTestSystem/BaseClass.py +0 -420
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/Bias.py +0 -44
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/ContinueHolding.py +0 -11
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/InstitutionalInvestorsFollower.py +0 -88
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/Kd.py +0 -49
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/KdCrossOver.py +0 -69
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/MaCrossOver.py +0 -65
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/MacdCrossOver.py +0 -49
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/MaxMinPeriodBias.py +0 -65
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/NaiveKd.py +0 -38
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/ShortSaleMarginPurchaseRatio.py +0 -93
- FinMind-1.2.8/FinMind/BackTestSystem/Strategies/__init__.py +0 -14
- FinMind-1.2.8/FinMind/BackTestSystem/__init__.py +0 -3
- FinMind-1.2.8/FinMind/BackTestSystem/utils.py +0 -30
- FinMind-1.2.8/FinMind/Crawler/__init__.py +0 -11
- FinMind-1.2.8/FinMind/Crawler/demo.py +0 -33
- FinMind-1.2.8/FinMind/Data/Load.py +0 -104
- FinMind-1.2.8/FinMind/Data/__init__.py +0 -9
- FinMind-1.2.8/FinMind/__init__.py +0 -2
- FinMind-1.2.8/FinMind/config.py +0 -1
- FinMind-1.2.8/FinMind.egg-info/PKG-INFO +0 -103
- FinMind-1.2.8/FinMind.egg-info/SOURCES.txt +0 -33
- FinMind-1.2.8/FinMind.egg-info/requires.txt +0 -5
- FinMind-1.2.8/FinMind.egg-info/top_level.txt +0 -1
- FinMind-1.2.8/PKG-INFO +0 -103
- FinMind-1.2.8/README.md +0 -84
- FinMind-1.2.8/setup.py +0 -40
- {FinMind-1.2.8/FinMind/Schema → finmind-2.0.0/FinMind/utility}/__init__.py +0 -0
- {FinMind-1.2.8/FinMind.egg-info → finmind-2.0.0/finmind.egg-info}/dependency_links.txt +0 -0
- {FinMind-1.2.8 → finmind-2.0.0}/setup.cfg +0 -0
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import datetime
|
|
2
|
+
import time
|
|
3
|
+
|
|
2
4
|
import numpy as np
|
|
3
5
|
import requests
|
|
4
|
-
|
|
6
|
+
|
|
7
|
+
USER_AGENT = (
|
|
8
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
9
|
+
"Chrome/68.0.3440.84 Safari/537.36"
|
|
10
|
+
)
|
|
5
11
|
|
|
6
12
|
|
|
7
13
|
def requests_get(url, header):
|
|
@@ -29,15 +35,17 @@ def get_time():
|
|
|
29
35
|
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
|
30
36
|
|
|
31
37
|
|
|
32
|
-
class
|
|
33
|
-
|
|
38
|
+
class BaseCrawler:
|
|
39
|
+
@staticmethod
|
|
40
|
+
def date2days(date):
|
|
34
41
|
# date = '2018-08-03'
|
|
35
42
|
date = datetime.datetime.strptime(date, "%Y-%m-%d").date()
|
|
36
43
|
value = (date - datetime.date(1970, 1, 1)).days
|
|
37
44
|
value = value * 60 * 60 * 24 * 1000
|
|
38
45
|
return value
|
|
39
46
|
|
|
40
|
-
|
|
47
|
+
@staticmethod
|
|
48
|
+
def days2date(day):
|
|
41
49
|
# day = 631497600000
|
|
42
50
|
# 60s = 1min
|
|
43
51
|
# 60min = 1hr
|
|
@@ -103,7 +111,8 @@ class Crawler:
|
|
|
103
111
|
value = "{} {}:{}:{}".format(date, hour, minute, second)
|
|
104
112
|
return value
|
|
105
113
|
|
|
106
|
-
|
|
114
|
+
@staticmethod
|
|
115
|
+
def date2millisecond(date):
|
|
107
116
|
# date = '2019-06-02 15:30:00'
|
|
108
117
|
date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
|
|
109
118
|
date = date + datetime.timedelta(minutes=1)
|
|
@@ -114,7 +123,8 @@ class Crawler:
|
|
|
114
123
|
|
|
115
124
|
return second
|
|
116
125
|
|
|
117
|
-
|
|
126
|
+
@staticmethod
|
|
127
|
+
def create_date(start, today=False): # start = '2018-07-31'
|
|
118
128
|
start = datetime.datetime.strptime(
|
|
119
129
|
start, "%Y-%m-%d"
|
|
120
130
|
).date() + datetime.timedelta(days=1)
|
|
@@ -128,7 +138,8 @@ class Crawler:
|
|
|
128
138
|
]
|
|
129
139
|
return date
|
|
130
140
|
|
|
131
|
-
|
|
141
|
+
@staticmethod
|
|
142
|
+
def remove_outlier(data, var_name):
|
|
132
143
|
|
|
133
144
|
value = list(data[var_name])
|
|
134
145
|
mean = np.mean(value, axis=0)
|
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import datetime
|
|
3
2
|
import os
|
|
4
|
-
import
|
|
3
|
+
import re
|
|
5
4
|
import sys
|
|
5
|
+
|
|
6
6
|
import pandas as pd
|
|
7
|
-
import
|
|
8
|
-
import re
|
|
7
|
+
import requests
|
|
9
8
|
from lxml import etree
|
|
10
9
|
|
|
10
|
+
from FinMind.crawler.base import BaseCrawler, USER_AGENT
|
|
11
|
+
|
|
11
12
|
PATH = "/".join(os.path.abspath(__file__).split("/")[:-2])
|
|
12
13
|
sys.path.append(PATH)
|
|
13
|
-
import Crawler.BasedClass as cbaseclass
|
|
14
|
-
|
|
15
|
-
"""
|
|
16
|
-
self = Crawler()
|
|
17
|
-
"""
|
|
18
14
|
|
|
19
15
|
|
|
20
|
-
class
|
|
16
|
+
class CommoditiesCrawler(BaseCrawler):
|
|
21
17
|
def __init__(self):
|
|
22
|
-
super(
|
|
18
|
+
super(CommoditiesCrawler, self).__init__()
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
@staticmethod
|
|
21
|
+
def create_loop_list():
|
|
25
22
|
# self.based_url = 'https://www.investing.com/commodities/'
|
|
26
23
|
kind_list = ["meats", "grains", "energies", "softs", "metals"]
|
|
27
24
|
loop_list = []
|
|
@@ -36,7 +33,7 @@ class Crawler(cbaseclass.Crawler):
|
|
|
36
33
|
"Connection": "keep-alive",
|
|
37
34
|
"Host": "www.investing.com",
|
|
38
35
|
"Upgrade-Insecure-Requests": "1",
|
|
39
|
-
"User-Agent":
|
|
36
|
+
"User-Agent": USER_AGENT,
|
|
40
37
|
}
|
|
41
38
|
res = requests.get(index_url, verify=True, headers=headers)
|
|
42
39
|
|
|
@@ -53,11 +50,8 @@ class Crawler(cbaseclass.Crawler):
|
|
|
53
50
|
]
|
|
54
51
|
return loop_list
|
|
55
52
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
# return '01/01/2018'
|
|
59
|
-
|
|
60
|
-
def get_end_date(self):
|
|
53
|
+
@staticmethod
|
|
54
|
+
def get_end_date():
|
|
61
55
|
end_date = datetime.datetime.now().date()
|
|
62
56
|
end_date = end_date + datetime.timedelta(-1)
|
|
63
57
|
y = str(end_date.year)
|
|
@@ -71,30 +65,36 @@ class Crawler(cbaseclass.Crawler):
|
|
|
71
65
|
return m + "/" + d + "/" + y
|
|
72
66
|
|
|
73
67
|
def crawler(self, loop): # loop = ['49769', 'Brent Oil Futures']
|
|
74
|
-
def get_value(
|
|
68
|
+
def get_value(template):
|
|
75
69
|
|
|
76
|
-
date = int(
|
|
70
|
+
date = int(template[0].attrib["data-real-value"])
|
|
77
71
|
date = int(date / 60 / 60 / 24)
|
|
78
72
|
date = str(
|
|
79
73
|
datetime.date(1970, 1, 1) + datetime.timedelta(days=date)
|
|
80
74
|
)
|
|
81
75
|
v = [
|
|
82
|
-
float(
|
|
83
|
-
|
|
76
|
+
float(
|
|
77
|
+
template[template_index]
|
|
78
|
+
.attrib["data-real-value"]
|
|
79
|
+
.replace(",", "")
|
|
80
|
+
)
|
|
81
|
+
for template_index in range(1, 6)
|
|
84
82
|
]
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Change = float(tem[6].text.replace("%", "").replace(",", "")) / 100
|
|
83
|
+
_price, _open, _high, _low, _vol = v
|
|
88
84
|
|
|
89
|
-
|
|
85
|
+
change = (
|
|
86
|
+
float(template[6].text.replace("%", "").replace(",", "")) / 100
|
|
87
|
+
)
|
|
90
88
|
|
|
91
|
-
return
|
|
89
|
+
return pd.DataFrame(
|
|
90
|
+
[date, _price, _open, _high, _low, _vol, change]
|
|
91
|
+
).T
|
|
92
92
|
|
|
93
93
|
# -------------------------------------------------------------------
|
|
94
94
|
futures_id, data_name = loop
|
|
95
|
-
header = data_name + " Historical
|
|
95
|
+
header = data_name + " Historical data"
|
|
96
96
|
st_date, end_date = (
|
|
97
|
-
|
|
97
|
+
"01/01/1970",
|
|
98
98
|
self.get_end_date(),
|
|
99
99
|
)
|
|
100
100
|
|
|
@@ -120,7 +120,7 @@ class Crawler(cbaseclass.Crawler):
|
|
|
120
120
|
"Host": "www.investing.com",
|
|
121
121
|
"Origin": "https://www.investing.com",
|
|
122
122
|
"Referer": "https://www.investing.com/commodities/brent-oil-historical-data",
|
|
123
|
-
"User-Agent":
|
|
123
|
+
"User-Agent": USER_AGENT,
|
|
124
124
|
"X-Requested-With": "XMLHttpRequest",
|
|
125
125
|
}
|
|
126
126
|
print("requests post")
|
|
@@ -129,22 +129,22 @@ class Crawler(cbaseclass.Crawler):
|
|
|
129
129
|
)
|
|
130
130
|
print("data clean")
|
|
131
131
|
page = etree.HTML(res.text)
|
|
132
|
-
|
|
132
|
+
col_name = page.xpath("//tr//th")
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
c.text.replace(" %", "Percent").replace(".", "") for c in
|
|
134
|
+
col_name = [
|
|
135
|
+
c.text.replace(" %", "Percent").replace(".", "") for c in col_name
|
|
136
136
|
]
|
|
137
|
-
|
|
137
|
+
col_name = ["date" if c == "Date" else c for c in col_name]
|
|
138
138
|
|
|
139
139
|
data = pd.DataFrame()
|
|
140
140
|
td_path = page.xpath("//tr//td")
|
|
141
141
|
for i in range(0, len(td_path) - 7, 7):
|
|
142
142
|
tem = td_path[i : i + 7]
|
|
143
143
|
value = get_value(tem)
|
|
144
|
-
data =
|
|
144
|
+
data = pd.concat([data, value])
|
|
145
145
|
|
|
146
146
|
if len(data) > 0:
|
|
147
|
-
data.columns =
|
|
147
|
+
data.columns = col_name
|
|
148
148
|
data["name"] = data_name
|
|
149
149
|
# data['data_id'] = futures_id
|
|
150
150
|
data = data.sort_values("date")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
from FinMind.crawler import GovernmentBondsCrawler, CommoditiesCrawler
|
|
4
|
+
|
|
5
|
+
# -------------------------------------------------------------------
|
|
6
|
+
commodities_crawler = CommoditiesCrawler()
|
|
7
|
+
# get futures list
|
|
8
|
+
loop_list = commodities_crawler.create_loop_list()
|
|
9
|
+
|
|
10
|
+
# get one futures data
|
|
11
|
+
commodities_df = commodities_crawler.crawler(loop_list[0])
|
|
12
|
+
|
|
13
|
+
# or get all futures data
|
|
14
|
+
commodities_df = pd.DataFrame()
|
|
15
|
+
for loop in loop_list:
|
|
16
|
+
print(loop)
|
|
17
|
+
value = commodities_crawler.crawler(loop)
|
|
18
|
+
commodities_df = pd.concat([commodities_df, value])
|
|
19
|
+
# -------------------------------------------------------------------
|
|
20
|
+
gb_crawler = GovernmentBondsCrawler()
|
|
21
|
+
# get futures list
|
|
22
|
+
loop_list = gb_crawler.create_loop_list()
|
|
23
|
+
|
|
24
|
+
# get one futures data
|
|
25
|
+
gd_df = gb_crawler.crawler(loop_list[0])
|
|
26
|
+
|
|
27
|
+
# or get all futures data
|
|
28
|
+
gd_df = pd.DataFrame()
|
|
29
|
+
for loop in loop_list:
|
|
30
|
+
print(loop)
|
|
31
|
+
value = gb_crawler.crawler(loop)
|
|
32
|
+
gd_df = pd.concat([gd_df, value])
|
FinMind-1.2.8/FinMind/Crawler/GovernmentBonds.py → finmind-2.0.0/FinMind/crawler/government_bonds.py
RENAMED
|
@@ -1,30 +1,27 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
政府債券
|
|
3
|
+
G8-俄羅斯、美國、加拿大、英國、法國、德國、義大利及日本
|
|
4
4
|
"""
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
import datetime
|
|
6
7
|
import os
|
|
7
|
-
import
|
|
8
|
+
import re
|
|
8
9
|
import sys
|
|
10
|
+
|
|
9
11
|
import pandas as pd
|
|
10
|
-
import
|
|
11
|
-
import datetime
|
|
12
|
+
import requests
|
|
12
13
|
from lxml import etree
|
|
13
14
|
|
|
15
|
+
from FinMind.crawler.base import BaseCrawler, USER_AGENT
|
|
16
|
+
|
|
14
17
|
PATH = "/".join(os.path.abspath(__file__).split("/")[:-2])
|
|
15
18
|
sys.path.append(PATH)
|
|
16
|
-
import Crawler.BasedClass as cbaseclass
|
|
17
19
|
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class Crawler(cbaseclass.Crawler):
|
|
26
|
-
def create_loop_list(self):
|
|
27
|
-
def get_data_id_name(curl):
|
|
21
|
+
class GovernmentBondsCrawler(BaseCrawler):
|
|
22
|
+
@staticmethod
|
|
23
|
+
def create_loop_list():
|
|
24
|
+
def get_data_id_name(url):
|
|
28
25
|
|
|
29
26
|
headers = {
|
|
30
27
|
"Accept": "*/*",
|
|
@@ -32,24 +29,24 @@ class Crawler(cbaseclass.Crawler):
|
|
|
32
29
|
"Accept-Language": "zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7",
|
|
33
30
|
"Connection": "keep-alive",
|
|
34
31
|
"Host": "www.investing.com",
|
|
35
|
-
"Referer":
|
|
36
|
-
"User-Agent":
|
|
32
|
+
"Referer": url,
|
|
33
|
+
"User-Agent": USER_AGENT,
|
|
37
34
|
"X-Requested-With": "XMLHttpRequest",
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
res = requests.get(
|
|
37
|
+
res = requests.get(url, verify=True, headers=headers)
|
|
41
38
|
tem_data_id = re.findall('data-id="[0-9]+"', res.text)
|
|
42
39
|
tem_data_id = [di.replace("data-id=", "") for di in tem_data_id]
|
|
43
40
|
page = etree.HTML(res.text)
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
_data_id = []
|
|
42
|
+
_data_name = []
|
|
46
43
|
for di in tem_data_id:
|
|
47
44
|
tem = page.xpath("//span[@data-id={}]".format(di))
|
|
48
45
|
if len(tem) > 0:
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
_data_id.append(tem[0].attrib["data-id"])
|
|
47
|
+
_data_name.append(tem[0].attrib["data-name"])
|
|
51
48
|
|
|
52
|
-
return
|
|
49
|
+
return _data_id, _data_name
|
|
53
50
|
|
|
54
51
|
def get_country_url():
|
|
55
52
|
index_url = "https://www.investing.com/rates-bonds/"
|
|
@@ -61,7 +58,7 @@ class Crawler(cbaseclass.Crawler):
|
|
|
61
58
|
"Connection": "keep-alive",
|
|
62
59
|
"Host": "www.investing.com",
|
|
63
60
|
"Upgrade-Insecure-Requests": "1",
|
|
64
|
-
"User-Agent":
|
|
61
|
+
"User-Agent": USER_AGENT,
|
|
65
62
|
}
|
|
66
63
|
res = requests.get(index_url, verify=True, headers=headers)
|
|
67
64
|
|
|
@@ -91,15 +88,15 @@ class Crawler(cbaseclass.Crawler):
|
|
|
91
88
|
"usa",
|
|
92
89
|
"italy",
|
|
93
90
|
]
|
|
94
|
-
|
|
95
|
-
for
|
|
96
|
-
tem = url[
|
|
91
|
+
countries_url = []
|
|
92
|
+
for url_index in range(len(url)):
|
|
93
|
+
tem = url[url_index].replace(
|
|
97
94
|
"https://www.investing.com/rates-bonds/", ""
|
|
98
95
|
)
|
|
99
96
|
tem = tem.replace("-government-bonds", "")
|
|
100
97
|
if tem in select:
|
|
101
|
-
|
|
102
|
-
return
|
|
98
|
+
countries_url.append(url[url_index])
|
|
99
|
+
return countries_url
|
|
103
100
|
|
|
104
101
|
# main
|
|
105
102
|
country_url = get_country_url()
|
|
@@ -112,10 +109,8 @@ class Crawler(cbaseclass.Crawler):
|
|
|
112
109
|
|
|
113
110
|
return loop_list
|
|
114
111
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def get_end_date(self):
|
|
112
|
+
@staticmethod
|
|
113
|
+
def get_end_date():
|
|
119
114
|
|
|
120
115
|
end_date = datetime.datetime.now().date()
|
|
121
116
|
end_date = end_date + datetime.timedelta(-1)
|
|
@@ -130,27 +125,31 @@ class Crawler(cbaseclass.Crawler):
|
|
|
130
125
|
return "{}/{}/{}".format(m, d, y)
|
|
131
126
|
|
|
132
127
|
def crawler(self, loop): # loop = ['23681', 'Germany 3 Month']
|
|
133
|
-
def get_value(
|
|
128
|
+
def get_value(template):
|
|
134
129
|
|
|
135
|
-
date = int(
|
|
130
|
+
date = int(template[0].attrib["data-real-value"])
|
|
136
131
|
date = int(date / 60 / 60 / 24)
|
|
137
132
|
date = str(
|
|
138
133
|
datetime.date(1970, 1, 1) + datetime.timedelta(days=date)
|
|
139
134
|
)
|
|
140
|
-
v = [
|
|
135
|
+
v = [
|
|
136
|
+
float(template[template_index].text)
|
|
137
|
+
for template_index in range(1, 5)
|
|
138
|
+
if template[template_index].text is not None
|
|
139
|
+
]
|
|
141
140
|
if len(v) == 0:
|
|
142
141
|
return pd.DataFrame()
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
_price, _open, _high, _low = v
|
|
143
|
+
change = (
|
|
144
|
+
float(template[5].text.replace("%", "").replace(",", "")) / 100
|
|
145
|
+
)
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
return data
|
|
147
|
+
return pd.DataFrame([date, _price, _open, _high, _low, change]).T
|
|
149
148
|
|
|
150
149
|
cid, data_name = loop
|
|
151
|
-
header = data_name + " Bond Yield Historical
|
|
150
|
+
header = data_name + " Bond Yield Historical data"
|
|
152
151
|
st_date, end_date = (
|
|
153
|
-
|
|
152
|
+
"01/01/1970",
|
|
154
153
|
self.get_end_date(),
|
|
155
154
|
)
|
|
156
155
|
bonds_url = "https://www.investing.com/instruments/HistoricalDataAjax"
|
|
@@ -176,7 +175,7 @@ class Crawler(cbaseclass.Crawler):
|
|
|
176
175
|
"Host": "www.investing.com",
|
|
177
176
|
"Origin": "https://www.investing.com",
|
|
178
177
|
"Referer": "https://www.investing.com/rates-bonds/france-1-month-bond-yield-historical-data",
|
|
179
|
-
"User-Agent":
|
|
178
|
+
"User-Agent": USER_AGENT,
|
|
180
179
|
"X-Requested-With": "XMLHttpRequest",
|
|
181
180
|
}
|
|
182
181
|
print("requests post")
|
|
@@ -187,19 +186,19 @@ class Crawler(cbaseclass.Crawler):
|
|
|
187
186
|
page = etree.HTML(res.text)
|
|
188
187
|
tr_path = page.xpath("//tr")
|
|
189
188
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
col_name = [col.text for col in tr_path[0].xpath("//th")]
|
|
190
|
+
col_name = [c.replace(" %", "Percent") for c in col_name]
|
|
191
|
+
col_name = ["date" if c == "Date" else c for c in col_name]
|
|
193
192
|
data = pd.DataFrame()
|
|
194
193
|
td_path = page.xpath("//tr//td")
|
|
195
194
|
for i in range(0, len(td_path) - 6, 6):
|
|
196
195
|
tem = td_path[i : i + 6]
|
|
197
196
|
value = get_value(tem)
|
|
198
197
|
if len(value) > 0:
|
|
199
|
-
data =
|
|
198
|
+
data = pd.concat([data, value])
|
|
200
199
|
|
|
201
200
|
if len(data) > 0:
|
|
202
|
-
data.columns =
|
|
201
|
+
data.columns = col_name
|
|
203
202
|
data["name"] = "{}".format(data_name)
|
|
204
203
|
# data['data_id'] = cid
|
|
205
204
|
data = data.sort_values("date")
|