From 76885399524f32d372d4ecbb3113580f9603ac96 Mon Sep 17 00:00:00 2001 From: Silviu VLASCEANU Date: Sat, 8 Feb 2014 18:05:55 +0100 Subject: [PATCH] Level 3 Simulation for smart order routing v.1.0 --- agent/SORAgent.py | 40 ++++++ agent/SORAgent.pyc | Bin 0 -> 1960 bytes agent/ZeroIntelligenceAgent.py | 32 +++++ agent/ZeroIntelligenceAgent.pyc | Bin 0 -> 1809 bytes bus/Bus.py | 1 + bus/ZIBus.py | 97 +++++++++++++++ bus/ZIBus.pyc | Bin 0 -> 3217 bytes events/signals.py | 1 + events/signals.pyc | Bin 579 -> 605 bytes injecter/ZIInjecter.py | 16 +++ injecter/ZIInjecter.pyc | Bin 0 -> 937 bytes .../ZeroIntelligenceMatchingEngine.py | 30 +++++ .../ZeroIntelligenceMatchingEngine.pyc | Bin 0 -> 1695 bytes objects/AgentFactory.py | 22 ++++ objects/AgentFactory.pyc | Bin 0 -> 1314 bytes objects/Order.py | 16 ++- objects/Order.pyc | Bin 2619 -> 2780 bytes rulebook/ZIRulebook.py | 103 ++++++++++++++++ rulebook/ZIRulebook.pyc | Bin 0 -> 2590 bytes scheduler/SchedulerSOR.py | 69 +++++++++++ utils/__init__.py | 0 utils/__init__.pyc | Bin 0 -> 124 bytes utils/generate_snapshots_SOR.py | 116 ++++++++++++++++++ utils/generate_snapshots_SOR.pyc | Bin 0 -> 2601 bytes 24 files changed, 538 insertions(+), 5 deletions(-) create mode 100644 agent/SORAgent.py create mode 100644 agent/SORAgent.pyc create mode 100644 agent/ZeroIntelligenceAgent.py create mode 100644 agent/ZeroIntelligenceAgent.pyc create mode 100644 bus/ZIBus.py create mode 100644 bus/ZIBus.pyc create mode 100644 injecter/ZIInjecter.py create mode 100644 injecter/ZIInjecter.pyc create mode 100644 matching_engine/ZeroIntelligenceMatchingEngine.py create mode 100644 matching_engine/ZeroIntelligenceMatchingEngine.pyc create mode 100644 objects/AgentFactory.py create mode 100644 objects/AgentFactory.pyc create mode 100644 rulebook/ZIRulebook.py create mode 100644 rulebook/ZIRulebook.pyc create mode 100644 scheduler/SchedulerSOR.py create mode 100644 utils/__init__.py create mode 100644 utils/__init__.pyc create mode 100644 utils/generate_snapshots_SOR.py create mode 100644 utils/generate_snapshots_SOR.pyc diff --git a/agent/SORAgent.py b/agent/SORAgent.py new file mode 100644 index 0000000..e001d7d --- /dev/null +++ b/agent/SORAgent.py @@ -0,0 +1,40 @@ +''' +Created on Feb 8, 2014 + +@author: Silver +''' + +from objects.Order import * + +class SORAgent(): + def __init__(self, service_locator, agent_id): + self.services = service_locator + self.agent_id = agent_id + + def process(self, symbol): + data = self.services.bus.get_market_data() + self.services.logger.info("Market data received %s" % (data)) + + self.services.logger.info("Sending Order Now:") + o = Order() + o.side = 1 + o.price = data["Euronext"]["ask-1"]["price"] + o.size = 1000000 + o.leaves = o.size + o.symbol = "Euronext" + o.id = "MyOrder" + o.timeinforce = "ioc" + o.parent = self.agent_id + + self.services.order_dispatcher.new_order(o) + + def process_report(self, id): + execs = self.services.bus.get_executions()[id] + self.services.logger.info("execution!!!!!!!!!!!!" + str(id) + " number: " + str(len(execs))) + for e in execs: + self.services.logger.info( e) + + + def process_reject(self, order_id): + reject = self.services.bus.get_rejects()[order_id] + self.services.logger.info("reject: %s. RemainingQty: %d" % (order_id, reject.leaves)) \ No newline at end of file diff --git a/agent/SORAgent.pyc b/agent/SORAgent.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf68febb1948aaee6f25581290831374dccf3f8c GIT binary patch literal 1960 zcmb_c-ESL35T84Lq;{L8A2g8xiOWOaKqVrG2V@}>T0WlYigP7I6|_3vZrpY4TeG`P z6O=xcH~t^~F(h8$H*;=?;H8SNymPZNJG1lg+iCr=+5hdypG8IMUkl$utndMdCVC2* zkWOiy&=cJv-6h?oUx{83{rEH`-Jx;5!3H0K^dEXtMx!%VXWyDh_WAwn(@zdQ>-P`K zRea|BFdN(XiSd2=7k+sHlgQ+wcnx&?xcF*n>Ua?hs~%v5`yd9vAQIxs`Qk(vM3f5C zCPc@o4i)3P4TFkv;gw=N#0uLW=Lww?DKM!p;&LpZjB-9Hp#KpzWd8Fxko8m+o)6@ zR)Mdfq?c426K~kHWbr!~q%gxjp;^kEcqzHCq(w7S0y(C%{VJhkeXtSZEJU#*Ca7GC z&Re9qd|0<>fL;#J-vJ9ZNN;OiJ2~AnR!zgdjiz#g>VPDv8lDKr`cn#jn78z#n1{;7$e`TysOP= z3>|FB@ciQgq(ijy=$1Wvutkx<_~=Y*BiGEjD!+|yA_Rtp z)2Z>&WLqCQao+fnzFTby4x>SV{lzp!raS>w*gl*sCT<@2F012pK57?+UHQrgJmlE2 z^uScS1-;`em9}A7#_AdF?m<|a7fKX@_pojVhi`g;KQ6Q2&w=?D{_v;<|HUAR2L+nHgEzW^9a0C>AYd7T;&hh< zU;i|qm%w6!X@Tk*G(V5%2LTSZZ4~Z-np0D)qILD|rC;EhW%X(?F_b!9wdQrM9Fq?kZd-u zoRj4KN|lFT-l)nv&{CRp=y?6)rC42(D7A2U zHOID)B;J9n*k!T@@=qYbz4;(6_+2rYq&?lF*Y4f!ZHyX!+#s1RN@-Ui5QdSPaL8d_ Yri7SZ`Etqfizcrx8F^BKZrV@(2Hk9mGXMYp literal 0 HcmV?d00001 diff --git a/agent/ZeroIntelligenceAgent.py b/agent/ZeroIntelligenceAgent.py new file mode 100644 index 0000000..1ae4645 --- /dev/null +++ b/agent/ZeroIntelligenceAgent.py @@ -0,0 +1,32 @@ +''' +Created on Jan 29, 2014 + +@author: Silver +''' +from objects.Order import * +from utils.generate_snapshots_SOR import generate_snapshot + +class ZeroIntelligenceAgent(): + def __init__(self, service_locator, agent_id): + self.services = service_locator + self.orderbooks = generate_snapshot(1, 0) + self.agent_id = agent_id + + self.sent_orders = False + + def process(self, symbol): + if not self.sent_orders: + self.sent_orders = True + for venue in self.orderbooks: + for price in self.orderbooks[venue]: + for o in self.orderbooks[venue][price]: + o.parent = self.agent_id + self.services.order_dispatcher.new_order(o) + + def process_report(self, order_id): + executions = self.services.bus.get_executions()[order_id] + for e in executions: + self.services.publisher.publish("Execution", {"venue": e.symbol, "price": e.price, "size": e.size}) + + def process_reject(self, order_id): + pass \ No newline at end of file diff --git a/agent/ZeroIntelligenceAgent.pyc b/agent/ZeroIntelligenceAgent.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c811b048a20d77bb0ed3989d1322d3c54a8dc2ec GIT binary patch literal 1809 zcmb`H-)|E~5XWclYzLdB1ZYt~1pI=qA{0S{Xd9s_Kb)(%CQOziYhw_bf7^0ZT<$ zM1`VP&|)eg8pkw-5I(IJaPx@8 zOwo+UNPsnx(?~2VYbB=85K9xc^?Pu!kt3Fz7xh{!g0QjGVV+vACEpI4U6t8t=-eAG z8xmw=@+>s@e?KRMx8X8t9#+}v#W`OGWAQp%5kY8dtX~a72!4gt`v%;80ym5w7*2s?b z#2C@~?lzr7bo9sBH z>);`;+q6|m%l4&rHlz#n9LFP=UR6`8!ArOV)MAoU3{;~`VS$B^HCgT_Nl5o?720ep z?VmOB9&*&kUJm=?@z51gphH_ut!R^q%PI}*&QBhpPb$ZK;xPyQYZd_CRtxGI^_}`k z34Y{+Yy>~Ir%>byC>lkWO77d6K>i$Uy1u&#)^&v#>xjEwQO*|DxosnQ0KoJsXVubj*vF$#huc z9=s*v`b(pu#iPc!%Uss*QGvQrJRj)DFWh0C?D@$f&@=L;vJ+Q@TWs;5OzMW3ufe1D zaiM@m6@(5f8+8cSATetkzv!?=HVt>#ug5i{KEE!;l*!l{BXEovyKGwUrv@v19bysU z4vWt*iS|F=2#p9ZEAlq9RC})7Za2>$pj)J{#$+z#sOH(=hKSxTZ{pbtx7osNRQTn8 gz4hMoH?=&Ia>>QSD{tD5iS4$egsRjODkFh#tG1L10#p%HO@VR~!3HTJN?F<7ZL^NO>+Fov z1jSe7k_X_H3&b@%0`CB?!37ex<@?Th9hV=`#P%GYIlD9GJHIofKh89M`}|M8C(};} z|F<#h4UkY|6VyoP$-v0a$fgk!mL&4z0iZ^BHXMJ9VH7AR+XtqxS&j3!kRJ-3G2$75`Vqj zprRK*8ZCT!gO0Uf+OzqLNH{!tt))ri=#C(X9tCL@MwvUsX`F;{uLEE<4x_WF>(O6*(+Pzp6Wy#Vz0^Gbzh{!t!x-IV^J-es}M0$^>s?r;0Qu$TWCM>tGqt zdi!T}WxmM9x$dl!Jd8AX2Y|-i?0BfC z>~{Jn@mY6m?w@BldxK3nBRq8Z<_E)WI&e%>*vLu%^gu1Lj__mu9H_FXK8GpO=f|xO zb`^jPhMjB&e=NXD5ZTv2#5-#mrI*d3Ib$xErfHblX35jJx1{rXUXOT+vC5T?_TOh}c7t<r}EcAC3!tcdjOll+%@f9dhXf;cblPP#>f)1VRr6PJgFj#eTI#66TYmvX2W6)K literal 0 HcmV?d00001 diff --git a/events/signals.py b/events/signals.py index 1a30122..0d99b42 100644 --- a/events/signals.py +++ b/events/signals.py @@ -10,6 +10,7 @@ "AckNew" : Event("AckNew"), "NackNew" : Event("NackNew"), "Execution" : Event("Execution"), + "Reject" : Event("Reject"), "SnapshotInject" : Event("SimulatorInject"), "ValidNewOrder" : Event("ValidNewOrder"), "ValidModifyOrder" : Event("ValidModifyOrder"), diff --git a/events/signals.pyc b/events/signals.pyc index 55599f7ba75a8f2d04bbedaddd3ebc030d9983d3..83d2960aa0fe7b8138002cf6379d6df31d2d7583 100644 GIT binary patch delta 122 zcmX@ia+gJ#`7kTiDvd3>fjd4D}?tg{@lX5jem#;?N&}5Fj|9N~nj~6VXbekW9C;ntUkZR;pBqL;H^_ zafN4Rmla1Ki5+`9w%_wi{&0Nw{p5$OY5U~(e}JU-Pz^pqk*G9kXB0DPb1HK(+t`fC z88taIb82REPjpB0wS;46Ssb87_=)GdFfjQE)Y6aFq4r<;y5fH1LoAhNXWhov?8o0Q zWcx=*dI9Bk08qZnq_h}0*=3O-TnlCqaXvxPE2vvTw?qy`rUn>HD<}XInt9IBrz#|w zA4}#0E~#@7qVKBKv(QL4?YBNoJ7>BxUhva>ii;B=E5QOXsq`Aw=QpdwE`@dlxr)Mj z6}F65d-A8ljrMgebb*~yK+>Dc0&gw!cA_+2VgVdC_>|rAjZ)p@bZ7K{b}V)7T{Wc3 zo~Kb40@EsQ>EN$@$BAXpw}I^(hEB*zlowD#HOegf`0wPTOk0Hxv+9RqI7#S`Q7~KT zGH~bgS~%DC%~gbJWfWF2_RZD$%kf${?njU$Ob^UrKGjo_qK2w#s>A|oX!x1ztS`NQ n7*GGaxE3*DsTKS6I&^ET{eSRu1aBwO@8oQfU^+4<<|z9GG1bJv literal 0 HcmV?d00001 diff --git a/matching_engine/ZeroIntelligenceMatchingEngine.py b/matching_engine/ZeroIntelligenceMatchingEngine.py new file mode 100644 index 0000000..5103aa3 --- /dev/null +++ b/matching_engine/ZeroIntelligenceMatchingEngine.py @@ -0,0 +1,30 @@ +''' +Created on Feb 8, 2014 + +@author: Silver +''' + +from matching_engine.MatchingEngine import MatchingEngine + +class ZeroIntelligenceMatchingEngine(MatchingEngine): + def __init__(self, service_locator): + MatchingEngine.__init__(self, service_locator) + + def on_inject(self, symbol): + #self.services.bus.push_public_update(symbol) + #matching goes here + self.services.events['MarketData'].emit(symbol) + + def on_new_order(self, id): + self.services.events['AckNew'].emit(id) + + # push order on the market + self.services.bus.push_private_update(id) + + + def inject_modify_order(self, symbol, id, order): + pass + + def inject_cancel_order(self, symbol, id): + pass + \ No newline at end of file diff --git a/matching_engine/ZeroIntelligenceMatchingEngine.pyc b/matching_engine/ZeroIntelligenceMatchingEngine.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e91abebf0137a1ae5cbe9316eeb130d103bc1cc6 GIT binary patch literal 1695 zcmcIk-)j>=5T3hBQWLDdL5d=IJW)z33Q|O>wTchT!}iG#Sgv>5cGLS2ZYL>$zSaL& z@KK#_6C3M~KAD4=o1NR;`@U~xH~O;L`S#?iN@@N?^4=D68{#sezW9K$kn(_vkoqA7 zSwtqJL&-MiGtoKGr+!3PllJ2lRz4Qj*{My!ChJyZ_q{pjzI@t!wz2uV)7ehOd|cIA z-F=%+Ox>~H<%t7X!Z*b2C7d4H@@Tg_vZdiilIokf`dG5bb9-dU)Lfo&0UTSr6>~4d z8CfRy2>1lDFhC$6LmxCqI3UxUbLh87?Z-`7nTFzE5MoEn-4n+|!+_3+&H_4z1SDkf z$6k!NN{slLIIV4IS!hGd+{5Ba7K>WNK_&Z{)xs*WW^-nm_gK5PvfYiEmr*f__G zK`|FY8?VOTY9-c3Qw1;`F^7PH3o;mbG7lsW8bi-VWLX=Ao>MUAgo!=I7JEs3V)$Lc zNen4GJ7+uv$EdTJn3A36XbQ_SA^cR|1=Hf7%9lZs+w$|O6rqPEgCa0S(1w zh0{fq*~94!`x@aDg{QTg=aXnG{BAe|$9fjdL0L zL#c426s`ev8xF-<0QS*;yapg0D(djpR?v>x&Gt$=>iL2*0BfC9sX)aA``b0Me))p+ ZcbmeFOT+8cdo|PRHTuuDaVxwP{s3ACiSz&f literal 0 HcmV?d00001 diff --git a/objects/AgentFactory.py b/objects/AgentFactory.py new file mode 100644 index 0000000..60ced8b --- /dev/null +++ b/objects/AgentFactory.py @@ -0,0 +1,22 @@ +''' +Created on Feb 8, 2014 + +@author: Silver +''' + +class AgentFactory(): + def __init__(self, service_locator): + self.services = service_locator + self.agents = {} + + def add_agent(self, agent_id, agent): + self.agents[agent_id] = agent + + def process_report(self, order_id): + parent = self.services.bus.get_executions()[order_id][0].parent + self.agents[parent].process_report(order_id) + + def process_reject(self, order_id): + parent = self.services.bus.get_rejects()[order_id].parent + self.agents[parent].process_reject(order_id) + \ No newline at end of file diff --git a/objects/AgentFactory.pyc b/objects/AgentFactory.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a2fc391fa7b8c8cf0b25fb73e9ba8ac6156534f GIT binary patch literal 1314 zcmbtUQEL-H5T3nDqB*T1f{=$o9#1S{ML|j_)k1yC!{*5lST1*Ky(7tm-A%EOKGlCL z_^R{GrHx2HG=ZI)y`BBO`DW%4f8R@f>K{6%^)Keu_`tJ_kKf@*sK(-hzwE5 zK05+AOhGkB5gqO$)Vj+uw?1@ulOZ?X90J(e>F4lx6J@4#o^j$SzalaI1$!Tl#y%Kd z&c?i!Q$&pGNoDik$G^*cxwsNeW6F6Mj1hkDkm{-&rN3Pw;t9W4MaaDpHOB>U*_-@f zHAJMiqG1GD6qvFI=#Ff5$h8ZMqA-Gk-gz*Rl6r#@TS@gTJ58RIqAJ3iaQS=Ox?UC2 zbt9q$HNC2hqZ>s^$oEN0fYU2F*NkcC^QY*-%^D`4%t$Lzf_=U=$&|tss|(s<<80& zN%GqS<8&if@A0)=g+k<0UcM39Q_`6A;Lfv|H6|o{Zp^GMmQ&tp44cL@OO-SbHkB6d vU%wO05Oj~12W&@mTiv+Z8Z@YwnSeuMiaKY0c6TKdeaDTW6ZvZcODFmTak>X# literal 0 HcmV?d00001 diff --git a/objects/Order.py b/objects/Order.py index 55d3d46..e5e5145 100644 --- a/objects/Order.py +++ b/objects/Order.py @@ -11,16 +11,19 @@ def __init__(self): self.size = 0 self.price = 0 self.symbol = "" - self.leaves = "unset" - self.timeinforce = "" + self.leaves = 0 + self.timeinforce = "day" self.id = "" self.executed = 0 self.side = 0 + self.shown = 0 + self.decay = 1 + self.parent = "" def __str__(self): side = "U" - if self.side == 1: side = "B" - if self.side == -1: side = "S" + if self.side == 1: side = "Buy" + if self.side == -1: side = "Sell" return "%s :: %s (%d / %d @ %f | %s) - %s" % (self.id, side, self.leaves, self.size, self.price, self.symbol, self.timeinforce) class ExecutionReport(): @@ -29,7 +32,8 @@ def __init__(self): self.price = 0 self.symbol = "" self.leaves = self.size - self.id = "" + self.id = "" + self.parent = "" def __str__(self): return "Exec %s :: (%d @ %f | %s)" % (self.id, self.size, self.price, self.symbol) @@ -42,7 +46,9 @@ def new_order(self, order): if order.size == 0 : logging.warning("Order [%s]: size equals zero, unable to send order!" % order); return if order.id == "": logging.warning("Order [%s]: has no id, unable to send order!" % order); return if order.symbol == "": logging.warning("Order [%s]: has no symbol, unable to send order!" % order); return + order.leaves = order.size + logging.debug("Inserting Order [%s]" % order) self.services.bus.insert_new_order(order) self.services.events["ValidNewOrder"].emit(order.id) diff --git a/objects/Order.pyc b/objects/Order.pyc index fcd4372d24711451e6d557404c9df0e13b180627..a55347c03cdfa4179c6bf27c40891f077a823db8 100644 GIT binary patch delta 663 zcmZuuO>5Lp6umd!Ni%JS%$K$^9W0f!GTVyUZrq77#f%72G(=w*6Na%&Qp%L>+=-jv z?%cT2jsAj)3;%~3SFS}6ih|zvMnu7coZNfv$>rpoceRgoTmM?|+PA;W>@PT+ovnEY zCjhYyLZ=J3zB_Ln5QgGi5Sl7H5CDVF1b}|V0Hp$*Q6$q0`5i8hzxa|qCtsz(%^)3(=!160TI443=%v10DQ&Lf zxF{!a+@uHkwzVXO0lm;~VTC^H`?xzh>ri4eI&-_`+^*a{w;L&k7Ckps{iwopD2Zs1 z_g`+wZ5@6Jp8?QSw~sFUFpg14HUb`8loCxzLTNRsNvKQs<7cPZ;J(dIAte^N4t1?( zyycB`)0DC;`fjb_DYfi_J%k+K1R*w| z!>C2CovUp4lheP_<56**0dNVbVElu=R>c7Sdlc&&&5qgR?>6a`+go1YDw1m=c|1{* N$JeOst?0GD{{@O%dFucG delta 511 zcmZutJxjx25Wef1k0w=2+q7sE3qmDQq@q^T{!67nIE`Kx7uVZQ1qucJ&6o3@PVd@;=?V7}G-oVlMPQtxV>19+(K|$S z{etIkLqV3Al7?8+5E<~3%>9(W?*hp*|K~V5;?Y3Mq;unjRg}3kC2iAE8>k%1M?w~? zNdAFZW@{cG)FCt=G@*}hjez|@Dh`1GW1%JKP(_tM44PDmKe^pume@TyX$IBC*-krX zv^|^RRuMB)u~vA6ORKs#BV)1*fFqCu?JvgC_^+|N+^p{MnF4Ltv(6|pUnG1n>$_ZD LrB{1gCDVx?F|kjy diff --git a/rulebook/ZIRulebook.py b/rulebook/ZIRulebook.py new file mode 100644 index 0000000..81f4983 --- /dev/null +++ b/rulebook/ZIRulebook.py @@ -0,0 +1,103 @@ + +from objects.Order import ExecutionReport + + +class ZIRulebook(): + def __init__(self, service_locator): + self.services = service_locator + + + def match_one(self, id): + order = self.services.bus._new_order + order.leaves = order.size + order.executed = 0 + executions = [] + if order.side == 1: # buy + if order.symbol not in self.services.bus._private_data_sell.keys(): + return + ask = self.services.bus._private_data_sell[order.symbol] + prices = sorted(ask.keys()) + i = 0 + current_price = prices[i] + while order.leaves > 0 and current_price <= order.price: + for o in ask[current_price]: + e = ExecutionReport() + e.price = current_price + e.size = min(o.leaves, order.leaves) + e.symbol = order.symbol + e.id = order.id + e.parent = order.parent + executions.append(e) + + e = ExecutionReport() + e.price = current_price + e.size = min(o.leaves, order.leaves) + e.symbol = order.symbol + e.id = o.id + e.parent = o.parent + self.services.bus._last_execution[o.id] = [] + self.services.bus._last_execution[o.id].append(e) + self.services.events['Execution'].emit(o.id) + + order.leaves -= e.size + order.executed += e.size + if order.leaves == 0: + self.services.bus._new_order = None + break + + i = i+1 + current_price = prices[i] + elif order.side == -1: # buy + if order.symbol not in self.services.bus._private_data_buy.keys(): + return + bid = self.services.bus._private_data_buy[order.symbol] + prices = sorted(bid.keys(), reverse = True) + i = 0 + current_price = prices[i] + while order.leaves > 0 and current_price >= order.price: + for o in bid[current_price]: + e = ExecutionReport() + e.price = current_price + e.size = min(o.leaves, order.leaves) + e.symbol = order.symbol + e.id = order.id + e.parent = order.parent + executions.append(e) + + e = ExecutionReport() + e.price = current_price + e.size = min(o.leaves, order.leaves) + e.symbol = order.symbol + e.id = o.id + e.parent = o.parent + self.services.bus._last_execution[o.id] = [] + self.services.bus._last_execution[o.id].append(e) + self.services.events['Execution'].emit(o.id) + + order.leaves -= e.size + order.executed += e.size + if order.leaves == 0: + self.services.bus._new_order = None + break + + i = i+1 + current_price = prices[i] + + + if len(executions) > 0: + self.services.bus._last_execution[order.id] = [] + self.services.bus._last_execution[order.id].extend(executions) + self.services.events['Execution'].emit(order.id) + + if str(order.timeinforce).upper() == 'IOC': + self.services.bus._last_reject[order.id] = order + #self.services.bus._last_reject[order.id].append(order) + self.services.events['Reject'].emit(order.id) + + + + + + + return False + \ No newline at end of file diff --git a/rulebook/ZIRulebook.pyc b/rulebook/ZIRulebook.pyc new file mode 100644 index 0000000000000000000000000000000000000000..281427dfa96680cc4af5b0d969428cd60f2845d7 GIT binary patch literal 2590 zcmeHJ&u<$=6n?W_+p*I$jZxh=jVm}|aVSR+st{`Vpd+XRq+e^b0+xz_d=FNNGyzkA7D}Qb@{|NpHhO~H9 z@cjWE`zAz$kD`=ltmr_Iiad&{6jkU4qBEi|4)EKjy$pETb(}}*IE$UuTnNh$NeS9@XjMFd_IKn5)C3^B2BnisqmXvPQEi z&1&$d)5(t&4lV#jJ{7y(42fV_r;*~HCw+wwFm^ut>Ya8l>0BZO{ye z;3bjHurk=oMU*~e$eUt^gxjX*kQGX9u?~3ZnxT<<85;UUXjF1ll`VmIlODWi>Z|}P z23y?ao#eH}9EJwWKCiIBl)dYLF|nYIVtK~{b>;F=VJ7Vv)3QvaJ^J+M8R4^!!h_d4 zS6Dduh4!<*ISI4wOMqRUf1+~Brn!BI_0PPktlyUG%z9H;Z!UbXV_h4?RWIZIC&{?v ze%oJhU!`K(XYSEK|8xI}+@CW!OWuV0bMNTfdpY+%d;1yA%{#mo&}!U2*ofcz&-X97 z;rad*QzzM8OjR%RuQ+i3a)yrd$POn-?(!y%YSL-Hai=ZeCcEOcN`>8k4&dEzC0Z9p zKc9a67=mIs`y0@fXTRJDt`1XSj!j{Wt3ZGJQX z&Wp$t<*^-qXJk@p!ee9Q&^2XZK!RG@_WO({Hv|H zYR7BAcN6b5uL7kw6vjn-w4>Tw?7Pl46}7dUtu zVpS5+Uh&UFz(wX*mNV8=!|#^?nM&a#AMmEJ_n+|AkcO2x|1GU7?LoPi_qp%oKg_Ml Ezh0E<{r~^~ literal 0 HcmV?d00001 diff --git a/scheduler/SchedulerSOR.py b/scheduler/SchedulerSOR.py new file mode 100644 index 0000000..946f45e --- /dev/null +++ b/scheduler/SchedulerSOR.py @@ -0,0 +1,69 @@ +''' +Created on Feb 8, 2014 + +@author: Silver +''' + +from ServiceLocator import ServiceLocator +from rulebook.ZIRulebook import ZIRulebook +from matching_engine.ZeroIntelligenceMatchingEngine import ZeroIntelligenceMatchingEngine + +from injecter.ZIInjecter import ZIInjecter +from bus.ZIBus import ZIBus +from agent.SORAgent import SORAgent +from events.signals import Events +from tools.Logger import * +from objects.Order import * +from datetime import datetime +from tools.Publisher import Publisher +from agent.ZeroIntelligenceAgent import ZeroIntelligenceAgent +from objects.AgentFactory import AgentFactory + + +if __name__ == "__main__": + start = datetime.now() + + services = ServiceLocator() + services.bus = ZIBus() + services.matching_engine = ZeroIntelligenceMatchingEngine(services) + services.rulebook = ZIRulebook(services) + services.injecter = ZIInjecter(services, "G:/st_sim/simulator/input_files/test_trades.h5") + services.events = Events + services.order_dispatcher = OrderDispatcher(services) + services.logger = get_logger() + services.publisher = Publisher(services, "G:/st_sim/simulator/output_files") + services.factory = AgentFactory(services) + + zi = ZeroIntelligenceAgent(services, "ZIAgent") + sor = SORAgent(services, "SOR") + + # connect the market to the injecter events + Events['SnapshotInject'].connect(services.matching_engine.on_inject) + + # connect the market to the agent events + Events['ValidNewOrder'].connect(services.matching_engine.on_new_order) + Events["AckNew"].connect(services.rulebook.match_one) + + # connect the trader to the market events + Events['MarketData'].connect(zi.process) + Events['MarketData'].connect(sor.process) + #Events['MarketData'].connect(services.rulebook.match_all) + #Events['Execution'].connect(zi.process_report) + #Events['Execution'].connect(sor.process_report) + services.factory.add_agent("ZIAgent", zi) + services.factory.add_agent("SOR", sor) + Events["Execution"].connect(services.factory.process_report) + Events["Reject"].connect(services.factory.process_reject) + + + # connect the injecter to the scheduler events + Events['Start'].connect(services.injecter.main_loop) + Events['Stop'].connect(services.publisher.export) + + services.logger.info("starting the simulation") + services.events["Start"].emit("simulation") + services.events["Stop"].emit("simulation") + + end = datetime.now() + print "Duration of simulation: ", start, end, end-start + \ No newline at end of file diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/utils/__init__.pyc b/utils/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fac0504adf6ea6419cb9e31c8b8f59e0e84fdb6f GIT binary patch literal 124 zcmZSn%*%Dh{$)@y0~9a 0: + orderbook[lit_venues[lv]][price] = [] + for i in range(nb_orders): + size = int(round(normal(100, 30))) # total qty + iceberg = powerlaw.rvs(0.8) # ratio of visible qty + decay = random() + + o = Order() + o.side = side + o.price = price + o.size = size + o.shown = int(iceberg * size) + o.decay = decay + o.id = "Order_%f_%d" %(price, i) + o.symbol = lit_venues[lv] + + orderbook[lit_venues[lv]][price].append(o) + limit += 1 + price -= 1 + + side = -1 + limit = 0 + price = 101 + while (limit < 5): + + nb_orders = int(round(10*powerlaw.rvs(0.6))) + + if nb_orders > 0: + orderbook[lit_venues[lv]][price] = [] + for i in range(nb_orders): + size = int(round(normal(100, 30))) # total qty + iceberg = powerlaw.rvs(0.8) # ratio of visible qty + decay = random() + + o = Order() + o.side = side + o.price = price + o.size = size + o.shown = int(iceberg * size) + o.decay = decay + o.id = "Order_%f_%d" %(price, i) + o.symbol = lit_venues[lv] + + orderbook[lit_venues[lv]][price].append(o) + limit += 1 + price += 1 + + + return orderbook + +def plot_orderbook(orderbook): + prices = orderbook.keys() + prices_buy = [] + prices_sell = [] + sizes_buy = [] + sizes_sell = [] + for k in prices: + if k <= 100: + prices_buy.append(k) + sizes_buy.append(sum([o.size for o in orderbook[k]])) + else: + prices_sell.append(k) + sizes_sell.append(sum([o.size for o in orderbook[k]])) + + plt.bar(prices_buy, sizes_buy) + plt.bar(prices_sell, sizes_sell, color = 'r') + plt.show() + + +if __name__ == "__main__": + ob = generate_snapshot(3, 3) + plot_orderbook(ob["Euronext"]) + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/utils/generate_snapshots_SOR.pyc b/utils/generate_snapshots_SOR.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06930e19422ba55d12983011215a997296868d5c GIT binary patch literal 2601 zcmds2OK)366h1S4BzElBjZ4*tN3*H0fJA*D3ROhfB!GA{m9AT*veI6zeW&iV@58w> zPLs%9r5hwRWk-?Nvga2dv0%rJU%(299THpk&Rmy7DiRN|;@bE4yyncAGv|EH{ZcLe z@W!uBm!?k^ww)j zmo8jFuREEILoRQ6=^)6#vnxTWcsbYxUi}p`0ntR# z{u614#zZL7=G{-_B*%uaBqL~?qs3KR@+8mqJ}K~RPl~kvvKWKU(|{=L2m{|7mlucW zLto@jr}5%DnV~UmS<)a+>21+F8F_JBq}Bazh_|1~w*Q(Yvy{a{4X_*T57#-3ReHL^ ztPNcz11kT2PeJQuk$*D5xbw!HrGPX6_f{E1~Y^=QKj8g+D2m^*KY2a+I=bicI_U^|6lFC z7k^f}D_pyMvAx?sX(eX1f`;7+cmUCuAiyFDcoc#%Nbj>9I$0l<~MzQZe!3~aH-_s7K;qW*) ztg+*(17BJ9VH$MRRCSoC^n>JKY>mF^dIz{}K7gHXeGqk$(6ZiesA9j#6KZN8f28Af zk%2LF=zI)wmg7{(5RfpkbdqFX1BZJKueRHTK@=E=7aDeqJFfNBm}+F;*cvbzAmffo zdrpHr*_Jdx$P#@S+2wA;GrtPBqf zM}Nl3x#*8UNEBs5%*&$SPfeba6|o>1;(1XMC0P>Lr-9#wsLB^b^&j~z*(_z6#HHpv4)=^@X5AE058O#ovcpyE7{ zcH$Q|@7AVJ*U!;CNxS!^m?d^!WfVQJxbWADzc{gYI|EfDfNcSVVk+l|VMj7X9!X)f z$PTr|bhMiM_p)UN#Wq7X36s>`ZrbEaw>>&g2iiHq5_hs5MOjm@Fbs`VcDyueXLNCs zE9xw=KiAdvy0*iUv2JH{V0h@JqE=yOTTcgvN?R*WS|(W|U(>)j2l^kh+&u3bCMIih z9*LX0+Y2BhDz?+O+p6HJ;)1M-i?S}x2>Z9|x{(*euA3nP7sz$}r0cr&Jh~eU4_37C zjLx8d@hBceP-g%1$CzLnKk^JG5(XWN0&`itEbE-dTElambo#1m^ooTjizN;h&+d3U z>e^X?(pg~(*WYzxFH%U1aU|&+*UfVOdR{s7YLxh+P`%B-s?UNHQ6T=*L|rb3v$D2U IYE&To4iPj2#{d8T literal 0 HcmV?d00001