建立股票观察 Agent,在真实市场场景下分配资金并应对交易成本与非正态分布
后台-插件-广告管理-内容页头部广告(手机) |
投资圈里头,大家老琢磨怎么搭出最牛的投资组合,这事儿投资者和学问家们老挂在嘴边。现在科技这玩意儿一发展,强化学习这新式机器学习手法慢慢也进了投资组合优化的门。这篇东西就要聊聊强化学习怎么在搭最牛投资组合里头发挥作用,还有碰上的一些难题和想法。
强化学习的基本概念
强化学习,就是机器通过不断尝试和错误来找到最牛策略的学问。它,就像和人打交道一样,一边互动一边调整自己的招数,为了能多拿奖励。在咱们炒股的时候,强化学习就能模仿咱们投资者的动作,通过买卖股票来提高投资组合的表现。
强化学习的精髓就是智能体和环境之间的互动。环境给出当下的市场情况,智能体据此作出选择,随后环境会依据智能体的选择调整状况并发给奖励。这一过程反复进行,智能体通过总结过往经验来优化未来的判断。
%load_ext autoreload
%autoreload 2
cd ../acfl/
from env.Env import Env
from env.priceGenerator import make_stock
from learners.a2c import PolicyEstimator,ValueEstimator, reinforce
import tensorflow as tf
def sin_func(num_stocks,length):
a = np.array(range(length+1))
a.shape= [length+1,1]
a = a/(2*np.pi)
a = np.sin(a)
return a+5.0001
D = pd.DataFrame(make_stock(1000,10)*np.random.uniform(2,4,10))
plt.xkcd()
D.plot(figsize=(20,10),title='My make beleive market for 10 stocks')
投资组合优化的挑战
优化投资组合可不容易,得挑好多股票,还得分清楚它们各自的比重。以前咱们常用的那些优化法儿,多半是靠过去的数据和统计模型来算,可这玩意儿在市场老是不按套路出牌,变化又快,往往就不够用了。
强化学习这玩意儿给咱们带来了新点子,就是能像玩游戏一样模拟市场,看投资者怎么操作,这样就能更灵活地对付市场的那些变来变去的。不过,用强化学习来优化投资组合的时候,也得小心不少难题。比如,得好好想想怎么设计奖励机制,怎么应对市场的那些不确定因素,还有怎么防止过度拟合,这些问题都得好好琢磨琢磨。
奖励函数的定义
在强化学习这块,奖励函数的设定那可是关键中的关键,直接关系到学习效果和最后定的投资招数。说到投资组合的优化,奖励函数一般会和收益挂钩,但怎么算收益,这可是一门大学问。
import numpy as np
def make_stock(length=100, num_stocks=2):
alpha = 0.9
k = 2
cov = np.random.normal(0, 5, [num_stocks, num_stocks])
cov = cov.dot(cov.T) # This is a positive semidefinite matrix, e.g. a covariance matrix
A = np.random.multivariate_normal(np.zeros(num_stocks), cov, size=[length]) # sample noise, with covariance
B = np.random.multivariate_normal(np.zeros(num_stocks), cov, size=[length]) # sample another noise, with covariance
bs = [np.zeros(shape=num_stocks)] #
ps = [np.zeros(shape=num_stocks)] # The prices
for a, b in zip(A, B):
bv = alpha * bs[-1] + b # calculate some trend
bs.append(bv)
pv = ps[-1] + bs[-2] + k * a # Previosu price + previous trend factor, plus some noise
ps.append(pv)
# ps = [0]
# for a,b,common in zip(A,BB,commonNoise):
# ps.append(ps[-1]+b+k*a+2*common)
# P = np.array(ps)
# P = np.exp(P/(P.max()-P.min()))
ps = np.array(ps).T # reshape it so that its [length,stocks]
R = ps.max(1) - ps.min(1) # Scale factor
prices = np.exp(ps.T / (R)) *np.random.uniform(10,250,num_stocks) # Normalize, exponantiate then make the prices more varied
return prices
咱们一般会拿风险调整后的收益来当奖励,这更能显出投资组合的实际表现。但这个法子也有点麻烦,比如说怎么准确算风险、怎么应对市场的变数这些。所以,弄出一个合适的奖励机制,对强化学习在投资组合调优里头用得上,那可是挺关键的。
市场模拟与环境设计
咱们要培养强化学习模型,一般得弄个像真的市场那样的模拟环境。这环境得能复制出股市那些真事儿,比如股价的起伏、买卖的费用,还有市场那点不确定的玩意儿。
在设计市场环境的方案里,咱们可以拿点简单的模型出来预测股价,比如那个正弦波模型。这样咱们就能更快地发现模型里的漏洞,然后一步一步地往里加料,增加点随机和不定的因素。这么一来,咱们的模型就能一点一点变得更坚强、更能适应变化了。
Actor-Critic方法的应用
演员-评论家算法,就是强化学习里头一种,它把策略的进步和价值的预测给合在一起。在咱们搞投资组合优化这事儿上,它就能帮我们大概估算出状态的价值,这样就能更精准地调整策略。
但是,用演员-评论家这种办法在遇到复杂多变的市面情况时,也会遇到点麻烦。比如,要是市场变得越复杂越难预测,那演员-评论家这办法就可能让策略太适应特定情况,弄不好会拖累模型的表现。所以,用这个方法的时候可得小心调整参数,别让它过度适应,得注意防止过拟合的问题。
import numpy as np
from collections import defaultdict
from env.priceGenerator import make_stock
costPerShare = 0 # 0.01
class Env:
'''
A simple environemnt for our agent,
the action our agent gives is weighting over the stocks + cash
the env calcutes that into stock and figures out the returns
'''
def __init__(self,price_fn,num_stocks=2,length=2,starting_value=1000,lookback=10):
'''
:param price_fn: A function that returns a numpy array of prices
:param num_stocks: How many stocks in our univerese
:param length: The length of an episode
'''
self.num_stocks = num_stocks
self.lookback = lookback
self.length = length
self.oprices= price_fn(num_stocks=num_stocks,length=length)
self.prices = np.concatenate([self.oprices,np.ones([length+1,1])],axis=1) #attach the value of cash
self.portfolio = np.zeros([num_stocks+1]) #2k and 2k+1 are te long and short of a stock. portfolio[-1] is cash
self.portfolio[-1] = 1
self.time =0
self.__account_value = starting_value
self.__shares=np.array([0]*num_stocks +[starting_value])
self.hist = defaultdict(list)
@property
def shares(self):
return self.__shares
@property
def account_value(self):
return self.__account_value
@shares.setter
def shares(self,new_shares):
self.__shares = new_shares
self.hist['shares'].append(self.shares)
@account_value.setter
def account_value(self,new_act_val):
self.__account_value = new_act_val
try:
act_returns = self.account_value / self.hist['act_val'][-1]
except:
act_returns =1
self.hist['act_val'].append(self.account_value)
self.hist['act_returns'].append(act_returns)
def step(self,new_portfolio):
'''
Get the next prices. Then transition the value of the account into the desired portfolio
:param new_portfolio:
:return:
'''
self.time +=1
self.update_acount_value(new_portfolio)
reward = np.log(self.hist['act_returns'][-1]) #already includes transaction costs
state = {
"prices":self.prices[self.time-self.lookback+1:self.time+1,:-1], # All prices upto now inclusive but no cash
"portfolio":self.portfolio,
}
done = self.time >=len(self.prices)-2
return state,reward,done
def update_acount_value(self,new_portfolio):
currentShareValues = self.shares * self.prices[self.time]
currentAccountValue = sum(currentShareValues)
currentPortfolioProportions = currentShareValues / currentAccountValue
desiredCashChange = (new_portfolio -currentPortfolioProportions )* currentAccountValue
desiredChangeInShares = np.floor(desiredCashChange / self.prices[self.time])
self.shares = self.shares + desiredChangeInShares
newAccountValue = np.sum(self.shares*self.prices[self.time])
#becuse we take the floor, sometimes we lose cash for no reason. This is a fix
missingCash = currentAccountValue - newAccountValue
transactionCost = sum(np.abs(desiredChangeInShares[:-1])*costPerShare)
self.shares[-1] += missingCash - transactionCost
transactionCost = sum(np.abs(desiredChangeInShares[:-1])*costPerShare)
self.hist["changeInShares"].append(desiredChangeInShares)
self.hist["transactionCosts"].append(transactionCost)
self.account_value =np.sum(self.shares*self.prices[self.time])
多股票环境中的挑战
在咱们这多股乱窜的市场里,要弄好投资组合那可真是个技术活儿。得把每只股票的涨跌、彼此间的联系还有买卖的费用这些方方面面都盘算清楚。再说,怎么给这些股票分轻重缓急,这事儿也得好好琢磨。
在股市里搞多股操作,老式的优化套路多半靠过去的数据和那些统计模型,可这玩意儿碰到市场那点不确定性和变化多端,效果往往不给力。再说,强化学习在多股市场里使起来也不轻松,得解决怎么对付那些高维数据、怎么防止过度拟合这类难题。
测试与验证的重要性
强化学习这块,测试和检验那可是关键。因为训练强化学习模型时,得不断试错和来回调整,所以很容易就过度拟合了。要想保证模型够稳、适用面广,得好好测试和检验一番。
搞投资组合优化那玩意儿,得好好儿测试和检查,这事儿挺关键的。咱这市场变化多端,说不准啥时候来个意外,模型表现受影响那是常有的事。所以,得多跑跑模拟,多做做实验,得确保这模型靠谱,能抗打。
未来的展望
虽然强化学习在组合优化这块儿挺多难题要克服,但它潜力大得很。随着技术日新月异,算法也在持续进化,强化学习在投资界的作用肯定会越来越显著。
咱们接下来得把研究重点放在几个关键点上:怎么弄出更科学的奖励机制、怎么应对市场的各种不确定性、怎么增强模型的稳定性和适应性等等。咱们得继续探索和动手实践,强化学习这东西说不定能给投资组合的优化带来更给力的解决办法。
研究强化学习在投资组合优化上的运用,你觉得有哪些要素最为关键?快来评论区聊聊你的观点!给这篇文章点个赞,转发一下,咱们一块儿聊聊这个挺有意思的话题!
本文 融资融券杠杆炒股 原创,转载保留链接!网址:http://www.long360.cn/zmt/368.html
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
后台-插件-广告管理-内容页尾部广告(手机) |