博客
代码人生:编织技术与生活的博客之旅
远程工作分析
HOW TO GET IDEA
在有幸体会过 996 的生活,早上 8.30 上班,中午休息两个小时,下午 6 点吃晚饭,晚饭后 7.30 上班到 9 点。
说是到九点,其实到了十点十一点还在公司,到宿舍洗漱后,差不多十二点了。
人是有硬性的娱乐时间(人必须有一定的自我放松时间,如果工作对自己来说不轻松的话,忘了那个地方说的了。),人是社会性动物,必须保证至少 4 个小时的社交 (《人类简史》)。996 的工作强度下,人的精神就很容易出问题。
再一个就是,在 996 的工作环境下,就只有周日了,周日是需要补觉的,那么一上午就没了,下午在看看生活必需品,那么连见朋友的时间都没了。
之前看过 广为人知 (che di feng sha) 的大项目 996.ICU,在国内环境确实感受到了严重的 内卷 和员工压榨。
确实也有很多讲述自身经验的方法,比如在 ICU 项目下:
因为家庭因素,我确实可以考虑出国发展,首选加拿大,加拿大最近有个 三年移民计划,对应的 加拿大 IT 人员计划 也有。发出来供大家参考。
HOW TO DO
加拿大,首先,考虑付费移民(如果有钱的话,五十万左右。去加拿大创业开店),相关信息,推荐搜索抖音号 [北美理李察德 (TopTalk)],非 IT 行业的方式都有,印象比较深的是去读加拿大的南翔技校,读个会计啥出来直接就业,逃离国内内卷环境。
直接考虑远程国外上班
IT 行业,我去加拿大的招聘网站看了看:
- Indeed-https://ca.indeed.com/
- Glassdoor-https://www.glassdoor.ca/index.htm
- Monster-https://www.monster.ca/
首先公司是支持完全远程上班的,对应的工资 19k-34k (参考 知乎,可能我搜索方式不对),然后英语其实要求很高。
对我而言,首要考虑把英语过了,雅思没到 7 分,其实大部分做不了。
内销转出口
为啥说大部分做不了呢,因为还有一条路,在中国找一家外企,比如 ThoughtWorks(思特沃克),做半年到一年后申请外调,到国外后,适应环境后在考虑把工作签证换成绿卡。
这种模式还有好处,在国内享受国外的制度,没有加班,年假长,福利好,被开除有很多很多的补偿。
简单搜索了一下,领英是最好的方式。参考 。其次是 glassdoor。
国内支持远程上班
如果几种方式都不行,那么我想到的比较好的方式是,首先在国内支持远程上班的公司工作,然后在通过雅思去国外,这样在接触新环境的时候,不会因为脱产而产生过多的困难。
首先,远程上班的劣势要列一下(来自朋友分享):
- 可能不交社保。
- 老板也认为成本减少,所以工资也给的少。
- 信任问题,老板不信任你,你信任老板,很容易产生问题。
- 缺少心理健康的关心,毕竟没有同事在旁边,人也是社交动物,需要思考如何补救。
远程招聘渠道
- 参考 远程招聘渠道
与常规招聘渠道不太一样,这里有一下渠道共大家选择:
- 电鸭招聘 https://eleduck.com
- remoteok https://remoteok.io
- github job https://jobs.github.com/
- stackoverflow jobs https://stackoverflow.com/jobs
- toptal https://www.toptal.com 需要全局梯,而且并不知道怎么用。..
Another Thing
在疫情下,远程办公和远程面试得到了最大限度的发展。国内外很多公司已经完全支持远程办公,比如 Facebook,有点是 IT 终于摆脱地理限制,对国内而言,慢慢房价不再是一个问题,低成本同时意味着更大的竞争和更低的成本,国内首先考虑同样 10k 的价格,为何不雇一个已经会老家的 n 年经验的老员工,而在深圳雇佣一个 10k 的实习生,更大一点是,10k 的价格可以在印度雇佣三个程序猿。..
再这么一个内卷时代,先跳出来的人,就是第一个占位子的人。
换个地方呆确实是个考虑的方式,但是同时要考虑亲人朋友的感受,也同时要考虑会不会是从这座城进入了另一座城。
当然国家一定会有地方保护的法律 出来,比如 微软允许员工永久在家办公。
Jeff 大佬的观点,如果内卷是个必然趋势,那么看大一点,要内卷就卷全球。其实也是另外一个角度的黑暗森林。
- 关于远程面试,远程面试简历可以考虑找朋友模拟面试,提升自己的水平。
- 其实
先考虑其他收入渠道
也是个很好的方式。为了防止这方面更内卷,我就不多说了。
朋友安利的外企公司
- VMware
- SmartX
- ThoughtWorks
韭菜的股市研究
写在前面的话
- 通过 米筐 网站提供的量化平台进行的测试。
- 做这个研究的初衷是笔者有一点意象投资股市,有几个不同的投资方案(策略),我想先拿 19 年的数据跑一跑我的方案(策略),如果亏钱了,就不玩股市,老老实实玩基金了。
关于如何读这个图
- 首先能看到时间,我的数据是从
2019 年 01 -- 2020 年 01
, - 红色的线代表账户市值(把股票持仓也换算成钱)的变化。
- 蓝色的线代表基准(沪深三百)的市值变化。
- 其次最重要的指标,
回测收益
,表示的是我本金到时间结束,涨了多少,比如我有 5w,那么这个图表示我年末结束涨到了5*(0.09+1) = 5.45(万元)
。 - 然后平均一年能有 13.5%的收益。
- 然后看
基准收益
, 这个我一般设置的是沪深三百,也就是大盘,这个图表示 19 年大盘涨了30+%
,而我的策略只有9+%
,其实是没有跑赢大盘的 (还不如买基金)。 - 然后需要注意下一个指标"MaxDrawdown(最大回测)": 最大回撤是最常用的指标,描述了投资者可能面临的最大亏损。最大回撤的数值越小越好,越大说明风险越大。
- Sharpe(夏普率):夏普比率若为正值,代表基金报酬率大于风险;若为负值,代表基金风险大于报酬率。因此,夏普比率越高,投资组合越佳。
好了,下面开始正文。
检测低于 x 元的 股票 ,购买并持有 3 个礼拜后抛出
这个是一个普遍的购买思路,觉得底价股票一定会长,我短期持有然后等他高于某个价格就出售,我模拟一下这个情况,下面是代码:
#!/usr/bin/python3
# encoding: utf-8
# @Time : 2020/11/18 14:32
# @author : zza
# @Email : 740713651@qq.com
import warnings
import pandas
import rqdatac
__config__ = {
"base": {
"start_date": "20190101",
"end_date": "20191231",
'frequency': '1d',
"accounts": {
"stock": 5000,
}
},
"mod": {
"sys_progress": {
"enabled": True,
"show": True
}, "sys_accounts": {
"enabled": True,
"dividend_reinvestment": True,
},
"sys_analyser": {
"enabled": True,
"plot": True,
'benchmark': '000300.XSHG',
},
}
}
def init(context):
context.lowest = 5
context.highest = 5.9
context.day_count = 0
context.holding_days = 10
def get_ticker(context):
all_ins = rqdatac.all_instruments("Stock").order_book_id.to_list()
price_df = rqdatac.get_price(all_ins, context.now, context.now, expect_df=True, fields=['close'])
price_df = price_df.reset_index(drop=False)
price_df = price_df[(context.lowest <= price_df.close) & (price_df.close <= context.highest)]
start_date = rqdatac.get_previous_trading_date(context.now, 2)
price_df_2 = rqdatac.get_price(price_df.order_book_id.to_list(), start_date, context.now, expect_df=True,
fields=['close']).reset_index(drop=False)
order_ticker = []
for order_book_id, data_df in price_df_2.groupby(price_df_2.order_book_id):
if (data_df.close.shift(fill_value=0) < data_df.close).all():
order_ticker.append(order_book_id)
return order_ticker
def before_trading(context):
context.day_count += 1
if (context.day_count - 1) % context.holding_days == 0:
context.order_ticker = get_ticker(context)
def handle_bar(context, bar_dict):
if (context.day_count - 1) % context.holding_days == 0:
with warnings.catch_warnings():
for item in context.order_ticker:
o = order_target_value(item, 1000)
if o:
print(o)
if (context.day_count - 1) % context.holding_days == (context.holding_days-1):
for item in context.portfolio.positions.keys():
order_target_value(item, 0)
def after_trading(context):
print("total_value {}".format(context.portfolio.total_value))
if (context.day_count - 1) % 15 == 0:
items = []
for k, v in context.portfolio.positions.items():
items.append({"order_book_id": k, "quantity": v.quantity})
print(pandas.DataFrame(items))
if __name__ == '__main__':
import rqalpha
rqalpha.run_func(init=init,
before_trading=before_trading,
handle_bar=handle_bar,
after_trading=after_trading,
config=__config__)
-
持有 3 个交易日
-
持有 10 个交易日
-
持有 15 个交易日
结论:底价股票确实会随着大盘的涨而有一定的波动,但最终都是会赔钱的,且三个交易的日的时候,直接赔钱了。这个图可以给广大读者的保佑侥幸心里的朋友看看,一年忙到头,不如买国运(沪深三百)。
根据公众号 闷声发小财
这个是根据我一个朋友跑的算法跑出来的可能会涨的概率。笔者拿到了他一年的数据(没用爬虫),然后试试能不能涨,这么跑的原因是,我当初确实想按着他的这个公众号来买,不过既然有回放数据测试,我当然先测试一下,本金本来就不多,挥霍不了,不敢随便教学费。
策略如下:
#!/usr/bin/python3
# encoding: utf-8
# @Time : 2020/11/22 16:33
# @author : zza
# @Email : 740713651@qq.com
# @File : 闷声发小财。py
import warnings
import numpy
import pandas
import rqdatac
from rqalpha.apis import *
__config__ = {
"base": {
"start_date": "20190101",
"end_date": "20191231",
'frequency': '1d',
"accounts": {
"stock": 5000,
},
"data_bundle_path": r"E:\data\bundle",
},
"extra": {
"log_level": "debug",
},
"mod": {
"sys_progress": {
"enabled": True,
"show": True
}, "sys_accounts": {
"enabled": True,
"dividend_reinvestment": True,
},
"sys_analyser": {
"enabled": True,
"plot": True,
'benchmark': '000300.XSHG',
},
},
}
def init(context):
context.df = pandas.read_csv("发小财。csv", dtype={"股票代码": numpy.str})
context.df['order_book_id'] = rqdatac.id_convert(context.df["股票代码"].to_list())
context.used_df = context.df[context.df["预测结果"] > 0.7]
context.sell_multiple = 1.08
context.holding_days = 1
context.buy_queen = []
context.sell_map = {}
def before_trading(context):
print("当日购买:{}".format(context.buy_queen))
print("当日持仓:{}".format(list(context.sell_map.keys())))
def handle_bar(context, bar_dict):
while context.buy_queen:
order_book_id = context.buy_queen.pop()
if context.stock_account.cash > 1000:
o = order_value(order_book_id, 1000)
if o:
trading_dt = get_next_trading_date(context.now, context.holding_days).to_pydatetime()
context.sell_map[order_book_id] = trading_dt
print("[{}] 购买成功".format(order_book_id))
else:
print("[{}] 资金不足,无法购买".format(order_book_id))
for order_id, dt in context.sell_map.copy().items():
a = dt.date() <= context.now.date()
b = bar_dict[order_id].close > get_position(order_id).avg_price # * context.sell_multiple
if a and b:
o = order_percent(order_id, -1)
if o:
del context.sell_map[order_id]
print("[{}] 卖出成功".format(order_id))
def dt_to_int(dt):
return dt.year * 10000 + dt.month * 100 + dt.day
def after_trading(context):
df = context.used_df[dt_to_int(context.now) == context.used_df.trading_dt]
if df.empty:
return
else:
for _, item in df.iterrows():
context.buy_queen.append(item["order_book_id"])
if __name__ == '__main__':
import rqalpha
rqalpha.run_func(init=init,
before_trading=before_trading,
handle_bar=handle_bar,
after_trading=after_trading,
config=__config__)
-
持有一天就卖出
-
持有 3 天并价格高于持仓价则卖出
结论:还好跑了回放测试,不然得教好多学费。
检测行业因子普遍 (90%) 一周内上涨的低价股票
这个也是我在上班的时候偶尔能想到的,我觉得可能也代表一分部分人的想法,**某个行业市场涨幅的时候,必定是全行业性质的,且会持续一段时间。**于是我就写了这个,根据股票行业暴露度(属于哪个行业),分类行业,如果都涨了,就买进,如果都跌了,就卖出。
- 检测行业因子普遍 (90%) 一周内上涨的低价股票 购买并持有
- 在行业下跌在 30% 左右卖出
代码如下:
#!/usr/bin/python3
# encoding: utf-8
# @Time : 2020/11/22 16:33
# @author : zza
# @Email : 740713651@qq.com
# @File : 闷声发小财。py
from collections import defaultdict
from pprint import pprint
import numpy
import pandas
from rqalpha.apis import *
__config__ = {
"base": {
"start_date": "20190101",
"end_date": "20191231",
'frequency': '1d',
"accounts": {
"stock": 50000,
},
"data_bundle_path": r"E:\data\bundle",
},
"extra": {
"log_level": "debug",
},
"mod": {
"sys_progress": {
"enabled": True,
"show": True
}, "sys_accounts": {
"enabled": True,
"dividend_reinvestment": True,
},
"sys_analyser": {
"enabled": True,
"plot": True,
'benchmark': '000300.XSHG',
},
},
}
def get_holding_ticker():
# 请去米筐购买或申请试用 RQData : www.ricequant.com
rqdatac.init()
df = rqdatac.get_factor_exposure(rqdatac.all_instruments("Stock").order_book_id, "20190101", "20191231")
df.reset_index().sort_values("date").to_csv("factor_exposure.csv", index=False)
def init(context):
df = pandas.read_csv("factor_exposure.csv")
all_order_book_id = all_instruments().order_book_id.to_list()
context.df = df[df["order_book_id"].isin(all_order_book_id)]
context.buy_map = defaultdict(list)
context.holding_map = defaultdict(list)
context.sell_factors = []
context.day_count = 0
context.sell_multiple = 1.2
def before_trading(context):
pprint("当日购买行业:{}".format(context.buy_map))
print("当日持仓:{}".format([i.order_book_id for i in get_positions()]))
print("年化:{}".format(context.portfolio.total_returns))
def handle_bar(context, bar_dict):
# buy
for factors, order_book_ids in context.buy_map.items():
if context.stock_account.cash < 2000:
break
for order_book_id in order_book_ids.copy():
o = order_value(order_book_id, 2000)
if o:
context.holding_map[factors].append(order_book_id)
order_book_ids.remove(order_book_id)
# sell
for factors in context.sell_factors:
for order_book_id in context.holding_map[factors].copy():
# a = bar_dict[order_book_id].close > get_position(order_book_id).avg_price * context.sell_multiple
a = True
if a:
o = order_percent(order_book_id, -1)
if o:
context.holding_map[factors].remove(order_book_id)
def dt_to_str(dt):
return "{}-{}-{}".format(dt.year, dt.month, dt.day)
def is_rise(order_book_id):
a, b = history_bars(order_book_id, 2, frequency="1d", fields='close')
return b > a
def after_trading(context):
context.day_count += 1
if context.day_count % 5 != 1:
return
df = context.df[context.now.date().isoformat() == context.df.date].copy()
df.loc[:, 'rose'] = df["order_book_id"].apply(is_rise)
df.loc[:, 'close'] = df["order_book_id"].apply(lambda x: history_bars(x, 1, frequency="1d", fields='close'))
context.sell_factors = []
context.buy_map = defaultdict(list)
for factors in df.columns[13:-2]:
_df = df[df[factors] == 1]
if _df['rose'].sum() / _df['order_book_id'].size > 0.9:
context.buy_map[factors] = _df[(_df["close"] > 5) & (_df["close"] < 6)].sort_values('close')[
'order_book_id'].to_list()[:2]
elif _df['rose'].sum() / _df['order_book_id'].size < 0.3:
context.sell_factors.append(factors)
del df
if __name__ == '__main__':
import rqalpha
rqalpha.run_func(init=init,
before_trading=before_trading,
handle_bar=handle_bar,
after_trading=after_trading,
config=__config__)
- 各行业两只股票
emmm,不说了,都是磊。