{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# -*- coding: utf-8 -*-\n", "\"\"\"\n", "Created on Thu Mar 21 17:01:08 2019\n", "\n", "@author: Costantini L., Mazza M., Sabbatini G.\n", "\"\"\"\n", "\n", "\n", "\n", "\n", "import random as rd\n", "import matplotlib.pylab as plt\n", "import pandas as pd\n", "import numpy as np\n", "from xcs import XCSAlgorithm\n", "from xcs.scenarios import ScenarioObserver\n", "from xcs.scenarios import Scenario\n", "from xcs.bitstrings import BitString\n", "import datetime\n", "\n", "#function which compute the moving avarage of a certain serie of data\n", "def MA(data,T):\n", " ma=[]\n", " for i in range(len(data)):\n", " S=0\n", " if(i 0\n", " \n", " def sense(self):\n", " haystack = BitString(self.p[self.remaining_cycles])\n", " return haystack\n", " \n", " def execute(self, action):\n", " self.remaining_cycles -= 1\n", " return action == self.t[self.remaining_cycles]\n", "\n", "\n", "\n", "#ARBITRAJEUR \n", "class Arbitrajeur:\n", " \n", " def __init__(self,id):\n", " self.id=id\n", " self.gain=0 #guadagno\n", " self.cash=0 \n", " self.stock=0\n", " \n", " \n", " def Action(self, data, price ): \n", " if(data>price):\n", " decision = 'Buy'\n", " else:\n", " decision ='Sell'\n", " return decision\n", " \n", " def PriceBuy(self, priceS):\n", " link=[]\n", " link.append(priceS+(priceS*0.001))\n", " link.append(self.id)\n", " return link\n", " \n", " def PriceSell(self, priceB):\n", " link=[]\n", " link.append(priceB-(priceB*0.001))\n", " link.append(self.id)\n", " return link\n", "\n", "\n", "#XCS\n", "class XCS:\n", " \n", " def __init__(self,id):\n", " self.id=id\n", " self.gain=0 #guadagno\n", " self.cash=0 \n", " self.stock=0\n", " \n", " def PriceBuy(self, priceS):\n", " link=[]\n", " link.append(priceS+0.1)\n", " link.append(self.id)\n", " return link\n", " \n", " def PriceSell(self, priceB):\n", " link=[]\n", " link.append(priceB-0.1)\n", " link.append(self.id)\n", " return link\n", "\n", " def Train(self,data, vol):\n", " ma5=MA(data,5)\n", " ma10=MA(data,10)\n", " environment=[]\n", " for i in range(10,len(data)-5):\n", " l=[]\n", " #prima regola\n", " if(data[i]>=ma5[i]):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #seconda regola\n", " if(data[i]>=ma10[i]):\n", " l.append('1')\n", " else:\n", " l.append('0') \n", " \n", " #terza regola\n", " if(data[i]/data[i-2]>1.02):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #quarta regola\n", " if(data[i]/data[i-2]<(1/1.02)):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #quinta regola\n", " if(ma10[i]-ma10[i-5]>0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #sesta regola\n", " if(ma5[i]-ma5[i-5]<0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #settima regola\n", " if(data[i]-data[i-10]>0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #ottava regola\n", " if(data[i]-data[i-5]>0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #REGOLE SUI VOLUMI\n", " devvol=DevSTD(vol)\n", " volmedio=Media(vol)\n", " if (vol[i]==0):\n", " vol[i]=volmedio\n", " if((vol[i]-volmedio) > devvol):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " if((volmedio-vol[i]) > devvol):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #AZIONE\n", " if(data[i+5]/data[i]>1.015):\n", " l.append('Buy') \n", " elif(data[i+5]/data[i]<1/1.015):\n", " l.append('Sell')\n", " else:\n", " l.append('Pass')\n", " \n", " environment.append(l)\n", " \n", " \n", " \n", " p=[]\n", " f='' \n", " for i in range (len(environment)):\n", " f=''\n", " for j in range (len(environment[1])-1):\n", " f+=environment[i][j]\n", " p.append(f)\n", " \n", " t=[] \n", " for i in range (len(environment)):\n", " t.append(environment[i][len(environment[0])-1])\n", " \n", "\n", " \n", " problem= HaystackProblem(p,t)\n", " scenario = ScenarioObserver(problem)\n", " algorithm = XCSAlgorithm()\n", " \n", " #xcs' parameters settings\n", " algorithm.exploration_probability = .001\n", " algorithm.ga_threshold = 100 \n", " algorithm.crossover_probability = .4 \n", " algorithm.do_action_set_subsumption = False\n", " algorithm.do_ga_subsumption = False\n", " algorithm.wildcard_probability = .1\n", " algorithm.deletion_threshold = 0 \n", " algorithm.mutation_probability = .0001\n", " \n", " model = algorithm.new_model(scenario)\n", " model.run(scenario, learn=True)\n", " \n", " self.model=model\n", " \n", " #function which create the environment from the closing prices of the market \n", " def environment(self, i, close, closevol):\n", " \n", " ma5=MA(close,5)\n", " ma10=MA(close,10)\n", " \n", " l=[]\n", " #I rule\n", " if(close[i]>=ma5[i]):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #II rule\n", " if(close[i]>=ma10[i]):\n", " l.append('1')\n", " else:\n", " l.append('0') \n", " \n", " #III rule\n", " if(close[i]/close[i-2]>1.02):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #IV rule\n", " if(close[i]/close[i-2]<(1/1.02)):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #V rule\n", " if(ma10[i]-ma10[i-5]>0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #VI rule\n", " if(ma5[i]-ma5[i-5]<0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #VII rule\n", " if(close[i]-close[i-10]>0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #VIII rule\n", " if(close[i]-close[i-5]>0):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " #vuolumes' rules\n", " devvol=DevSTD(closevol)\n", " volmedio=Media(closevol)\n", " if (closevol[i]==0):\n", " closevol[i]=volmedio\n", " if((closevol[i]-volmedio) > devvol):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " if((volmedio-closevol[i]) > devvol):\n", " l.append('1')\n", " else:\n", " l.append('0')\n", " \n", " return (l)\n", "\n", "\n", "\n", " def Action(self,statomerc):\n", " countS=0\n", " countB=0\n", " countP=0\n", " for rule in self.model:\n", " if (rule.fitness>0.5 and rule.experience>15):\n", " perf=0\n", " canc=0\n", " for j in range (10):\n", " \n", " if (statomerc[j]==str(rule.condition[j])):\n", " perf+=1\n", " if (rule.condition[j]==None):\n", " canc+=1 \n", " if ((canc+perf)==10 and canc<9):\n", " if(rule.action=='Buy'):\n", " countB+=rule.fitness*rule.numerosity\n", " \n", " elif (rule.action=='Sell'):\n", " countS+=rule.fitness*rule.numerosity\n", " else:\n", " countP+=rule.fitness*rule.numerosity\n", " if (countB==0 and countS==0 and countP==0):\n", " countP=1\n", " \n", " if (countB>countS and countB>countP):\n", " return('Buy')\n", " elif (countS>countB and countS>countP):\n", " return('Sell')\n", " else:\n", " return('Pass')\n", "\n", "\n", "\n", "#RANDOM AGENT\n", "class RandomAgent: \n", " def __init__(self,id):\n", " self.id=id\n", " self.gain=0 \n", " self.cash=0 \n", " self.stock=0\n", " \n", " def Action(self):\n", " decision= rd.random()\n", " if(decision<=0.45):\n", " decision='Buy'\n", " elif(decision<0.9):\n", " decision='Sell'\n", " else:\n", " decision='Pass'\n", " return decision\n", " \n", " def Price(self, price):\n", " link=[]\n", " link.append(float(price)+rd.gauss(0, price/100))\n", " link.append(self.id)\n", " return link\n", " \n", " \n", " \n", " \n", " \n", "#reading inputs \n", "INPUT = pd.read_csv('input.csv', sep=\",\")\n", "\n", "\n", "#upload and prepare historical serie used for the xcs test \n", "dati2 = pd.read_csv(INPUT.TestSeries[0], sep=\",\") \n", "data=[]\n", "vol=[]\n", "CompleteCalendar(dati2)\n", "train2=[] \n", "for i in range(len(data)):\n", " train2.append(data[i])\n", "trainvol2=[] \n", "for i in range(len(data)):\n", " trainvol2.append(vol[i])\n", " \n", "\n", "\n", "\n", " #upload and prepare historical serie used for xcs traning\n", "dati = pd.read_csv(INPUT.TrainSeries[0], sep=\",\") \n", "data=[]\n", "vol=[]\n", "CompleteCalendar(dati)\n", "train=[] \n", "for i in range(int(len(data)*0.7)):\n", " train.append(data[i])\n", "close=[] \n", "for i in range(0,len(data)):\n", " close.append(data[i])\n", "trainvol=[] \n", "for i in range(int(len(data)*0.7)):\n", " trainvol.append(vol[i])\n", "closevol=[]\n", "for i in range(0,len(data)):\n", " closevol.append(vol[i])\n", "plt.plot(data[int(len(data)*0.7):]) \n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "#Agents creation\n", "\n", "N_random=INPUT.RandomNumber[0] \n", "N_arbitrajeur=INPUT.ArbitrajeurNumber[0] \n", "N_XCS=INPUT.LCSNumber[0] \n", "agents=[]\n", "for i in range(N_random): \n", " A=RandomAgent(i)\n", " agents.append(A)\n", "for i in range(N_arbitrajeur):\n", " A=Arbitrajeur(i+N_random)\n", " agents.append(A)\n", "for i in range (N_XCS):\n", " A=XCS(i+N_arbitrajeur+N_random)\n", " A.Train(train2,trainvol2)\n", " agents.insert(rd.randint(0,N_random),A)\n", " \n", "\n", "\n", "\n", "#Market\n", "initial_price=close[int(len(close)*0.7)]\n", "price=initial_price\n", "final_price=0\n", "andamento=[]\n", "andamento.append(initial_price)\n", "nday=len(data)-len(train)\n", "for k in range(int(len(data)*0.7),len(data)):\n", " queueB=[]\n", " queueS=[]\n", " for i in range(len(agents)):\n", " \n", " if(type(agents[i])==RandomAgent):\n", " if(agents[i].Action()=='Buy'):\n", " queueB.append(agents[i].Price(price))\n", " queueB.sort()\n", " elif(agents[i].Action()=='Sell'):\n", " queueS.append(agents[i].Price(price))\n", " queueS.sort()\n", " \n", " \n", " if(type(agents[i])== Arbitrajeur):\n", " if(agents[i].Action(close[k],price)== 'Buy'):\n", " if(len(queueS)!=0):\n", " queueB.append(agents[i].PriceBuy(queueS[0][0]))\n", " else:\n", " queueB.append(agents[i].PriceBuy(price))\n", " queueB.sort()\n", " else:\n", " if(len(queueB)!=0):\n", " queueS.append(agents[i].PriceSell(queueB[-1][0]))\n", " else:\n", " queueS.append(agents[i].PriceSell(price))\n", " queueS.sort()\n", " \n", " if(type(agents[i])== XCS):\n", " if(agents[i].Action(agents[i].environment(k,close,closevol))=='Buy'):\n", " if(len(queueS)!=0):\n", " queueB.append(agents[i].PriceBuy(queueS[0][0]))\n", " else:\n", " queueB.append(agents[i].PriceBuy(price))\n", " queueB.sort()\n", " elif(agents[i].Action(agents[i].environment(k,close,closevol))=='Sell'):\n", " if(len(queueB)!=0):\n", " queueS.append(agents[i].PriceSell(queueB[-1][0]))\n", " else:\n", " queueS.append(agents[i].PriceSell(price))\n", " queueS.sort()\n", " \n", " \n", " \n", " \n", " if(len(queueB)!=0 and len(queueS)!=0):\n", " if(queueB[-1][0]>queueS[0][0]):\n", " for j in range(len(agents)):\n", " if(queueB[-1][1]==agents[j].id):\n", " agents[j].cash-=queueS[0][0]\n", " agents[j].stock += 1\n", " if(queueS[0][1]==agents[j].id):\n", " agents[j].cash+=queueS[0][0]\n", " agents[j].stock -= 1\n", " final_price = queueS[0][0]\n", " queueB.remove(queueB[-1])\n", " queueS.remove(queueS[0])\n", " \n", " price=final_price\n", " train.append(final_price)\n", " andamento.append(price)\n", " \n", "for i in range(len(agents)):\n", " agents[i].gain= agents[i].cash + (final_price * agents[i].stock) \n", " \n", "plt.plot(andamento) \n", "plt.xlabel('time (days)')\n", "plt.ylabel('closing price ($)')\n", "plt.show()\n", "\n", "\n", "media=0\n", "for i in range (len(agents)):\n", "\n", " if (type(agents[i])==XCS):\n", " print('Agent of type: '+str(type(agents[i]))+' earned: '+ str(agents[i].gain))\n", " media+=agents[i].gain\n", "\n", "print('In avarage the LCSs earned: '+ str(media/N_XCS))\n", " \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.1" } }, "nbformat": 4, "nbformat_minor": 2 }