自用策略初始提交
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import division, print_function, unicode_literals
|
||||
from datetime import datetime
|
||||
from follower import BaseFollower
|
||||
from log import logger
|
||||
from misc import parse_cookies_str
|
||||
import pandas as pd
|
||||
|
||||
class XueQiuFollower(BaseFollower):
|
||||
LOGIN_PAGE = "https://www.xueqiu.com"
|
||||
LOGIN_API = "https://xueqiu.com/snowman/login"
|
||||
TRANSACTION_API = "https://xueqiu.com/cubes/rebalancing/history.json"
|
||||
PORTFOLIO_URL = "https://xueqiu.com/p/"
|
||||
WEB_REFERER = "https://www.xueqiu.com"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._adjust_sell = None
|
||||
self._users = None
|
||||
|
||||
def login(self, user=None, password=None, **kwargs):
|
||||
"""
|
||||
雪球登陆, 需要设置 cookies
|
||||
:param cookies: 雪球登陆需要设置 cookies, 具体见
|
||||
https://smalltool.github.io/2016/08/02/cookie/
|
||||
:return:
|
||||
"""
|
||||
cookies = kwargs.get("cookies")
|
||||
|
||||
if cookies is None:
|
||||
raise TypeError(
|
||||
"雪球登陆需要设置 cookies, 具体见" "https://smalltool.github.io/2016/08/02/cookie/"
|
||||
)
|
||||
headers = self._generate_headers()
|
||||
self.s.headers.update(headers)
|
||||
|
||||
self.s.get(self.LOGIN_PAGE)
|
||||
|
||||
cookie_dict = parse_cookies_str(cookies)
|
||||
self.s.cookies.update(cookie_dict)
|
||||
#extract_strategy_name(self, 'ZH1332574')
|
||||
logger.info("登录成功")
|
||||
|
||||
|
||||
|
||||
def extract_strategy_name(self, strategy_url):
|
||||
|
||||
base_url = "https://xueqiu.com/cubes/nav_daily/all.json?cube_symbol={}"
|
||||
url = base_url.format(strategy_url)
|
||||
rep = self.s.get(url)
|
||||
|
||||
info_index = 0
|
||||
return rep.json()[info_index]["name"]
|
||||
|
||||
|
||||
def extract_transactions(self, history):
|
||||
|
||||
if history["count"] <= 0:
|
||||
return []
|
||||
rebalancing_index = 0
|
||||
raw_transactions = history["list"][rebalancing_index]["rebalancing_histories"]
|
||||
transactions = []
|
||||
for transaction in raw_transactions:
|
||||
if transaction["price"] is None:
|
||||
logger.info("该笔交易无法获取价格,疑似未成交,跳过。交易详情: %s", transaction)
|
||||
continue
|
||||
transactions.append(transaction)
|
||||
|
||||
|
||||
return transactions
|
||||
|
||||
def create_query_transaction_params(self, strategy):
|
||||
params = {"cube_symbol": strategy, "page": 1, "count": 1}
|
||||
return params
|
||||
|
||||
# noinspection PyMethodOverriding
|
||||
def none_to_zero(self, data):
|
||||
if data is None:
|
||||
return 0
|
||||
return data
|
||||
|
||||
# noinspection PyMethodOverriding
|
||||
def project_transactions(self, transactions, assets):
|
||||
|
||||
pa = pd.DataFrame(index=[],columns=[])
|
||||
for transaction in transactions:
|
||||
weight_diff = self.none_to_zero(transaction["weight"]) - self.none_to_zero(
|
||||
transaction["prev_weight"]
|
||||
)
|
||||
#print(33333,weight_diff,assets,transaction["price"])
|
||||
initial_amount = abs(weight_diff) / 100 * assets / transaction["price"]
|
||||
|
||||
transaction["datetime"] = datetime.fromtimestamp(
|
||||
transaction["created_at"] // 1000
|
||||
)
|
||||
|
||||
transaction["stock_code"] = transaction["stock_symbol"].lower()
|
||||
|
||||
transaction["action"] = "buy" if weight_diff > 0 else "sell"
|
||||
|
||||
if str(transaction["stock_code"][2:4])=='11' or str(transaction["stock_code"][2:4])=='12':
|
||||
shou=1
|
||||
else:
|
||||
shou=2
|
||||
transaction["amount"] = int(round(initial_amount, -shou))
|
||||
|
||||
pa.loc[transaction["stock_code"],"price"]=transaction["price"]
|
||||
pa.loc[transaction["stock_code"],"amount"]=transaction["amount"]
|
||||
pa.loc[transaction["stock_code"],"datetime"]=transaction["datetime"]
|
||||
pa.loc[transaction["stock_code"],"action"]=transaction["action"]
|
||||
current_time = datetime.now()
|
||||
diff = (current_time - transaction["datetime"]).total_seconds()
|
||||
if int(diff)<20:
|
||||
return pa
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user