建立股票观察 Agent,在真实市场场景下分配资金并应对交易成本与非正态分布

配资网 阅读: 2024-10-15
后台-插件-广告管理-内容页头部广告(手机)

投资圈里头,大家老琢磨怎么搭出最牛的投资组合,这事儿投资者和学问家们老挂在嘴边。现在科技这玩意儿一发展,强化学习这新式机器学习手法慢慢也进了投资组合优化的门。这篇东西就要聊聊强化学习怎么在搭最牛投资组合里头发挥作用,还有碰上的一些难题和想法。

优合集团ceo_合优投资管理有限公司_合优投资

强化学习的基本概念

强化学习,就是机器通过不断尝试和错误来找到最牛策略的学问。它,就像和人打交道一样,一边互动一边调整自己的招数,为了能多拿奖励。在咱们炒股的时候,强化学习就能模仿咱们投资者的动作,通过买卖股票来提高投资组合的表现。

强化学习的精髓就是智能体和环境之间的互动。环境给出当下的市场情况,智能体据此作出选择,随后环境会依据智能体的选择调整状况并发给奖励。这一过程反复进行,智能体通过总结过往经验来优化未来的判断。

%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')

投资组合优化的挑战

合优投资_合优投资管理有限公司_优合集团ceo

优化投资组合可不容易,得挑好多股票,还得分清楚它们各自的比重。以前咱们常用的那些优化法儿,多半是靠过去的数据和统计模型来算,可这玩意儿在市场老是不按套路出牌,变化又快,往往就不够用了。

强化学习这玩意儿给咱们带来了新点子,就是能像玩游戏一样模拟市场,看投资者怎么操作,这样就能更灵活地对付市场的那些变来变去的。不过,用强化学习来优化投资组合的时候,也得小心不少难题。比如,得好好想想怎么设计奖励机制,怎么应对市场的那些不确定因素,还有怎么防止过度拟合,这些问题都得好好琢磨琢磨。

奖励函数的定义

优合集团ceo_合优投资_合优投资管理有限公司

合优投资_优合集团ceo_合优投资管理有限公司

在强化学习这块,奖励函数的设定那可是关键中的关键,直接关系到学习效果和最后定的投资招数。说到投资组合的优化,奖励函数一般会和收益挂钩,但怎么算收益,这可是一门大学问。

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])

多股票环境中的挑战

在咱们这多股乱窜的市场里,要弄好投资组合那可真是个技术活儿。得把每只股票的涨跌、彼此间的联系还有买卖的费用这些方方面面都盘算清楚。再说,怎么给这些股票分轻重缓急,这事儿也得好好琢磨。

在股市里搞多股操作,老式的优化套路多半靠过去的数据和那些统计模型,可这玩意儿碰到市场那点不确定性和变化多端,效果往往不给力。再说,强化学习在多股市场里使起来也不轻松,得解决怎么对付那些高维数据、怎么防止过度拟合这类难题。

测试与验证的重要性

强化学习这块,测试和检验那可是关键。因为训练强化学习模型时,得不断试错和来回调整,所以很容易就过度拟合了。要想保证模型够稳、适用面广,得好好测试和检验一番。

优合集团ceo_合优投资_合优投资管理有限公司

搞投资组合优化那玩意儿,得好好儿测试和检查,这事儿挺关键的。咱这市场变化多端,说不准啥时候来个意外,模型表现受影响那是常有的事。所以,得多跑跑模拟,多做做实验,得确保这模型靠谱,能抗打。

未来的展望

虽然强化学习在组合优化这块儿挺多难题要克服,但它潜力大得很。随着技术日新月异,算法也在持续进化,强化学习在投资界的作用肯定会越来越显著。

合优投资管理有限公司_优合集团ceo_合优投资

咱们接下来得把研究重点放在几个关键点上:怎么弄出更科学的奖励机制、怎么应对市场的各种不确定性、怎么增强模型的稳定性和适应性等等。咱们得继续探索和动手实践,强化学习这东西说不定能给投资组合的优化带来更给力的解决办法。

研究强化学习在投资组合优化上的运用,你觉得有哪些要素最为关键?快来评论区聊聊你的观点!给这篇文章点个赞,转发一下,咱们一块儿聊聊这个挺有意思的话题!

优合集团ceo_合优投资_合优投资管理有限公司

本文 融资融券杠杆炒股 原创,转载保留链接!网址:http://www.long360.cn/zmt/368.html

声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索