YouTube2Text

Pairs-trading strategy from scratch in Python — Transcript

by Algo-trading with Saleh · 6,924 words · 911 segments · language en · Watch on YouTube

Full transcript

  1. 0:00today I'm going to write a Paris trading
  2. 0:02strategy which is the basic strategy
  3. 0:04that Edward thorb used to make his 800
  4. 0:07million Fortune I've been obsessed with
  5. 0:09this strategy ever since I read his book
  6. 0:11called A man for all markets a few years
  7. 0:13ago and realizing that not only this guy
  8. 0:16beat the casino by inventing card
  9. 0:18counting but he also beat the stock
  10. 0:20market with the strategy not only his
  11. 0:22fund was profitable almost every single
  12. 0:24month but his worst monthly loss was
  13. 0:26less than 1% it's a market neutal
  14. 0:29strategy which means potentially we can
  15. 0:31make money whether if the price is in an
  16. 0:33uptrend A downtrend or even in a Range
  17. 0:35I'm going to show it on a chart in a
  18. 0:36second but then I will also show the
  19. 0:38basic math behind it in a Jupiter
  20. 0:40notebook and then we will write it
  21. 0:42inside Jesse so we can run some back
  22. 0:44test and see some actual results so if
  23. 0:46that sounds interesting let's get right
  24. 0:48into
  25. 0:49it all right let's begin with a very
  26. 0:51simple example ethereum versus ethereum
  27. 0:54classic they have different price ranges
  28. 0:56ethereum is in matter of thousands of
  29. 0:59dollars but ethereum classic is I think
  30. 1:01in hundreds but we know their prices are
  31. 1:04highly correlated and that's really what
  32. 1:06we care about so for example on this
  33. 1:08chart I have both their prizes and I've
  34. 1:11set it to be on the same priz scale just
  35. 1:13so that we can see them easier and you
  36. 1:16can see for example in here the price of
  37. 1:18ethereum is actually lower than the
  38. 1:20price of ethereum classic but it becomes
  39. 1:23the opposite in here the price of
  40. 1:25ethereum is actually more than the price
  41. 1:27of ethereum classic so what does it mean
  42. 1:29it means that if we open the long
  43. 1:31position for ethereum at this point in
  44. 1:33time and at the same time open the short
  45. 1:36position for ethereum classic here and
  46. 1:38hold that position when we reach this
  47. 1:40point in time you can see that it's the
  48. 1:43opposite now the price of ethereum
  49. 1:45classic is lower than the price of
  50. 1:47ethereum so what does it mean it means
  51. 1:48that yes both the prices are lower than
  52. 1:51what it was at this point in time but if
  53. 1:53we opened two opposite side positions
  54. 1:56one long and the other one short at this
  55. 1:59point we would have made money why
  56. 2:01because our short position would have
  57. 2:03made more money than the amount that our
  58. 2:06long position lost so the difference
  59. 2:08between the panl of both positions would
  60. 2:11be our profit now if I go back in time
  61. 2:13you can find so many positions where
  62. 2:15this opportunity existed I'm going to
  63. 2:17explain the math behind this strategy in
  64. 2:19a second with some code but I want to
  65. 2:21mention that this video right here by
  66. 2:23copian is very initially learned about
  67. 2:26the math behind it and in my video I
  68. 2:28won't go to as much detail as they did
  69. 2:31so definitely check out their video if
  70. 2:33you want to learn about this topic in
  71. 2:35more details all right so first I'm
  72. 2:37going to show you the basics of parist
  73. 2:39trading in a Jupiter notebooks which is
  74. 2:40great for a presentation and in case you
  75. 2:42didn't know if you want to use jupyter
  76. 2:44notebooks with Jesse all you need to do
  77. 2:46is to make sure they are inside your
  78. 2:48Jesse project all right so my project is
  79. 2:50named but I have multiple Jupiter
  80. 2:53notebooks and this one is the one I'm
  81. 2:55going to use all right so first we need
  82. 2:57to select the kernel and I'm going to to
  83. 2:59select one which already has Jessi
  84. 3:02installed in it all right let's add a
  85. 3:04code block and first I'm going to import
  86. 3:06all the necessary packages so I'm going
  87. 3:08to say from Jesse import utils and the
  88. 3:12research module now the utils will give
  89. 3:15us some utility functions and the
  90. 3:16research module is used for importing
  91. 3:19data from the database or even running
  92. 3:20back test but I'm not going to use that
  93. 3:22in jupyter notebooks in this video but
  94. 3:24you can if you like to all right so next
  95. 3:27I'm going to import JC helpers as JH
  96. 3:30which will give me some helpers that
  97. 3:32aren't really used in most of the
  98. 3:34strategies but I'm going to use it in
  99. 3:36here next I will import numpy as MP from
  100. 3:40daytime I'm going to import daytime and
  101. 3:43lastly I'm going to import the Matt plot
  102. 3:46Li library because I'm going to show you
  103. 3:49some charts all right next I want to
  104. 3:50import some data and I'm going to use
  105. 3:52the research modules get candles
  106. 3:54function and first it will ask me the
  107. 3:57name of the exchange all right so let's
  108. 3:59def find the exchange variable here I'm
  109. 4:02going to use binance Perpetual Futures
  110. 4:05and here I will pass the exchange the
  111. 4:08second one is the symbol and I want to
  112. 4:10use eth and Etc which is ethereum
  113. 4:13classic all right so the first one is
  114. 4:15going to be e us and the time frame I
  115. 4:18want it to be 15 minutes and then we
  116. 4:21have the assort now the assort date that
  117. 4:24is accepted here has to be in time stamp
  118. 4:26format and to convert that I'm going to
  119. 4:29use use the helper function from Jesse
  120. 4:31so I'm going to say this start date
  121. 4:34equals and I'm going to use date to Tim
  122. 4:36stamp and in it I will pass the date
  123. 4:40since
  124. 4:422024 the month could be the 10th month
  125. 4:45and since the first day and for my
  126. 4:48finished date I'm going to give it again
  127. 4:51date to timestamp again 2024 10th month
  128. 4:55and the third day so I only want data
  129. 4:58for 2 days B basically all right so now
  130. 5:01I have the start date right and the
  131. 5:04Finish date all right so and I can leave
  132. 5:07the other ones all right now this
  133. 5:08function will return two values the
  134. 5:10warm-up candles and the actual candles
  135. 5:12that I want and because I don't intend
  136. 5:14to run back test with it in this Jupiter
  137. 5:17notebook I don't care about the value
  138. 5:19for the V candles right so I don't want
  139. 5:21the first one and that's why I'm using
  140. 5:23this underline value here but the second
  141. 5:25one I will call it C1 or candle one and
  142. 5:28there we go now for the second one we're
  143. 5:31going to do the same thing right except
  144. 5:34instead of eth we want it to be Etc all
  145. 5:36right let's run this and it's all good
  146. 5:38now next because I want to show you a
  147. 5:40chart of these values I'm going to need
  148. 5:42time stamps so I'm going to create an
  149. 5:45empty list called times and I'm going to
  150. 5:48Loop through the first set of candles
  151. 5:51right and in it I will simply say times
  152. 5:53do pend and date time do from time stamp
  153. 5:57and then I will pass the time stamp of
  154. 5:59each candle and that would be the first
  155. 6:01index but because this function expects
  156. 6:03the time samps to be in seconds but
  157. 6:05Jess's times samps are in milliseconds
  158. 6:08I'm going to have to divide this by
  159. 6:111,000 all right there's one more thing I
  160. 6:12need to do just like this chart that I
  161. 6:14just showed you which both prices were
  162. 6:16on the same price scale because they
  163. 6:18weren't absolute values of prices they
  164. 6:20were price changes in matter of
  165. 6:23percentage right so we need to do the
  166. 6:25same in our python code so I'm going to
  167. 6:27say C1 equals use
  168. 6:30do prizes to returns and this is an
  169. 6:33already built-in function in Jesse so I
  170. 6:35don't have to Define it from scratch
  171. 6:37which is really nice so in it I'm going
  172. 6:39to have to pass all the candles but I
  173. 6:42only want the closing prizes and that
  174. 6:44would be C1 and I'm going to select all
  175. 6:47the candles but then I'm going to select
  176. 6:49only the closing candles and that would
  177. 6:51be the index of two so in case you
  178. 6:53didn't know the zero index in Jesse is
  179. 6:55timestamp and then we have the open
  180. 6:58close high low and then volume so the
  181. 7:00close would have an index of two and
  182. 7:02then I'm going to do the same thing for
  183. 7:04the second price data or ethereum
  184. 7:06classic right and we should also change
  185. 7:08this all right now we can run this one
  186. 7:10okay we're getting an error all right
  187. 7:12this shouldn't have been there it should
  188. 7:14have been inside here all right so now
  189. 7:15we can finally plot the actual price
  190. 7:17data and for that I'm going to say PLT
  191. 7:20figure which is used to set the size of
  192. 7:22the chart and in it I'm going to say fix
  193. 7:24size equals 15x 6 now this Size Doesn't
  194. 7:27Really Matter much it's just for
  195. 7:29presentation you can set whatever value
  196. 7:31you like next I'm going to say PLT do
  197. 7:33plot and I'm going to pass the time
  198. 7:36stamps and then the actual price data
  199. 7:39and for color I'm going to say blue and
  200. 7:42the label is going to be e next I will
  201. 7:45do the same thing for ethereum classic
  202. 7:47and I'm going to set the color as red
  203. 7:49and this should be TC and finally I can
  204. 7:52do pl. Legend to show me everything all
  205. 7:55right so now we can see the price data
  206. 7:57for both the assets on the same chart
  207. 8:00which is really cool now if you pay
  208. 8:02close attention you can see that our
  209. 8:04Theory very much sounds right in here
  210. 8:07for example the price of eth was lower
  211. 8:09than Etc but in here it was higher than
  212. 8:13that so in other words if we open the
  213. 8:15long position here and shorted the price
  214. 8:18of Etc and did the opposite in here we
  215. 8:21would have made money and the same goes
  216. 8:23for so many other places it goes here it
  217. 8:26goes here here here so it just continues
  218. 8:29right which is very promising all right
  219. 8:30so now that we have both of them on the
  220. 8:33same chart we should begin writing the
  221. 8:35actual code based on math that we can
  222. 8:37actually use to trade it right because
  223. 8:40we're not going to have the chart when
  224. 8:42we are trading this with a bot right now
  225. 8:44we're looking at this chart with our
  226. 8:46eyes that's how we know this happening
  227. 8:48so we need to use statistics to come up
  228. 8:50with a good strategy the first step is
  229. 8:52that we need the spread in other words
  230. 8:55we need the difference between the two
  231. 8:56price data so I'm going to define a
  232. 8:59spread as C1 and then I'm going to
  233. 9:02select since the first candle up until
  234. 9:04the end and the reason I'm doing this is
  235. 9:06how we defined this C1 variable we
  236. 9:09defined it in here we converted the
  237. 9:11candles into returns and when we did
  238. 9:14that the First Data actually became a
  239. 9:16nan value and that's why I'm doing this
  240. 9:18and if you don't believe me I can print
  241. 9:20this data so you can see it so let's
  242. 9:22print the first value and you see it is
  243. 9:25Nan right and we cannot really have that
  244. 9:27in our strategy so that's why I'm going
  245. 9:30to select since the first data and when
  246. 9:33I say first I mean the index of one
  247. 9:35because the actual first value would
  248. 9:37have the index of zero so we're going to
  249. 9:39select this one until the end minus C2
  250. 9:43and again selecting since the first
  251. 9:45index up until the end right so this is
  252. 9:47going to be our spread which is the
  253. 9:49difference between the two price data
  254. 9:51now to actually take advantage of this
  255. 9:53data having the spread alone isn't
  256. 9:55enough we need the zcore of it now what
  257. 9:58is zcore the Z score is the price
  258. 10:00difference or the spread that we just
  259. 10:02defined compared to the mean of the
  260. 10:04price data and that's what we really
  261. 10:05care about so we're going to define the
  262. 10:07zscore now Jesse already has a utility
  263. 10:10function which will calculate the zscore
  264. 10:12for me so I'm going to use that one it's
  265. 10:14called zscore and it takes the series
  266. 10:17data or in this case it would be our
  267. 10:19spread now I'm going to also Define the
  268. 10:21mean now by the way the zcore function
  269. 10:24it will use the mean itself if you're
  270. 10:26curious to know how it works is it's
  271. 10:28basically this price series minus the
  272. 10:31mean of that price series divided by its
  273. 10:34standard deviation right now you don't
  274. 10:36have to know about the exact math behind
  275. 10:38it you could just use it but knowing it
  276. 10:40certainly helps all right so I am also
  277. 10:43going to define the mean of it myself
  278. 10:45because I want to print it on the chart
  279. 10:47and for that we can use numpy and we
  280. 10:49will just pass the zscore and now we can
  281. 10:52plot them right so first I'm going to
  282. 10:55say PLT
  283. 10:57figure and then pass the fix size just
  284. 11:00like before 15 and six next I'm going to
  285. 11:03say PLT plot and I'm going to pass the
  286. 11:07times again selecting since since the
  287. 11:09index of one to SK skip that Nan value
  288. 11:12and then I'm going to pass the zcore I'm
  289. 11:14going to set the color to Blue and the
  290. 11:17label could also be Z score next we're
  291. 11:19going to plot a horizontal line using
  292. 11:21this index and I'm going to pass the
  293. 11:23mean that we just defined here I'm going
  294. 11:26to use the color black and set the line
  295. 11:28Style to Dash and the label is going to
  296. 11:32be mean and then I'll do it two more
  297. 11:34times for the values of 1.2 and minus
  298. 11:381.2 with colors of red and green all
  299. 11:41right so let's see how this looks like
  300. 11:43and there we go so now we have the zore
  301. 11:45of the two price series and we can see
  302. 11:48how their correlation or the related
  303. 11:52price is actually moving so for example
  304. 11:54in here we can long the first asset and
  305. 11:56short the other one and when it reaches
  306. 11:59the mean we will just close the
  307. 12:01positions and we can do the opposite
  308. 12:03when the zscore goes above this line we
  309. 12:05can short the first asset and long the
  310. 12:08second one and again when it reaches the
  311. 12:10mean we can just close it right and and
  312. 12:13as you can see we had opportunities for
  313. 12:15this type of trade in more than once we
  314. 12:17had it here we had it here here here
  315. 12:21here here and so much more right so it
  316. 12:24looks very promising but here's the
  317. 12:26thing though right now we have this data
  318. 12:29honest beautiful chart which is only
  319. 12:31showing us the price data for two days
  320. 12:33but in reality we're not going to have
  321. 12:35charts we're going to trade this with a
  322. 12:37butt right so we need a statistical way
  323. 12:40to write all of these things but not
  324. 12:42only that we need to make sure these
  325. 12:44prizes are actually cointegrated now
  326. 12:46what is congration well again this video
  327. 12:49will describe it so much better but I'm
  328. 12:51also going to try my best you see to
  329. 12:53trade any mean verion strategy we need
  330. 12:55that price data to be stationary and
  331. 12:57what is a stationary well it means that
  332. 13:00the mean of that price data or data
  333. 13:03series is not moving now what is a
  334. 13:04stationary it means that the mean of the
  335. 13:07price data or data series is stable it's
  336. 13:11not changing because right now in this
  337. 13:13picture we know the mean is this but
  338. 13:16that's because we already have the price
  339. 13:18data for 2 days right so for example at
  340. 13:21this point in time the mean wouldn't
  341. 13:24exactly have been this value or at this
  342. 13:26point in time it wouldn't exactly have
  343. 13:28been that because we would would have
  344. 13:29calculated based on this much data right
  345. 13:31but now that we have all of it we
  346. 13:33already know what the mean of it is
  347. 13:35right so if I try to calculate the mean
  348. 13:38of this data series is going to change
  349. 13:40now we don't want it to be like stable
  350. 13:43100% to be able to trade but the thing
  351. 13:45is if we try to trade a mean verion
  352. 13:47strategy on let's say just one asset we
  353. 13:50know for sure that it is not going to be
  354. 13:52a stationary however we can still trade
  355. 13:54them if they are conr and what does
  356. 13:57congration mean it means that yes these
  357. 14:00two price data even though individually
  358. 14:02they're not stationary some kind of
  359. 14:04combination of their price data which in
  360. 14:07this case would be the zcore that we
  361. 14:09just calculated that series is a
  362. 14:11stationary so that's what it means right
  363. 14:14and if that's the case then we can trade
  364. 14:16them against each other but if they're
  365. 14:18not we just can't now there are some
  366. 14:20statistical ways to calculate this but
  367. 14:22again Jesse gives us a utility function
  368. 14:24which will take care of this so I'm
  369. 14:26going to use that one so let's define a
  370. 14:28new variable called is cointegrated and
  371. 14:32in it we're going to use the r
  372. 14:34cointegrated utility function and first
  373. 14:37we will pass the first priz data and
  374. 14:38then the second now let's print this and
  375. 14:41it is returning true so now we know they
  376. 14:44are qur now if you're curious to know
  377. 14:46the source code of this well here it is
  378. 14:48we're using the set model module of
  379. 14:51python and then we use the P value and
  380. 14:54if it is below the cut of value we say
  381. 14:56it is cointegrated otherwise it's not
  382. 14:59now I know this sounds confusing but
  383. 15:01again watch that video of copian and
  384. 15:04hopefully it should make it clearer
  385. 15:06right now let's move on to Jesse so we
  386. 15:08can write the code in it so we can run
  387. 15:10some backst and see some actual numbers
  388. 15:12all right I'm going to start by
  389. 15:13generating a new strategy and I'm going
  390. 15:15to call it P
  391. 15:18trading all right so now I'm going to
  392. 15:20copy this and I will open my CER editor
  393. 15:24which uses Ai and is so much smarter and
  394. 15:26faster to use and I'm going to look for
  395. 15:29for this all right so this is the
  396. 15:30generated code now the real challenge
  397. 15:32for this strategy is that we cannot only
  398. 15:35Define it inside one strategy file
  399. 15:38because if I try to run a back test you
  400. 15:41see we have these routes and right now
  401. 15:43it is set to BC so let's change this to
  402. 15:46East UCC and the time frame to 15
  403. 15:50minutes and this one to P trading all
  404. 15:54right and the duration is since
  405. 15:56beginning of this year until just if you
  406. 15:59days ago now here's the thing though we
  407. 16:00need to trade this for both eth and
  408. 16:03ethereum classic so I need to add
  409. 16:05another trading route and for this one
  410. 16:07I'm going to choose Etc and the same
  411. 16:11time frame but now we need to also pick
  412. 16:13another strategy so picking this one
  413. 16:16alone won't work so how do we do this
  414. 16:19now I need to generate another strategy
  415. 16:21and I can pick whichever name I like but
  416. 16:23I'm going to go with Paris trading two
  417. 16:28all right so I'm also going to open this
  418. 16:31one all right so now we're going to deal
  419. 16:34with two strategy files now I know you
  420. 16:36guys have some questions like how do we
  421. 16:38communicate between the two strategies
  422. 16:40how do we connect them to each other and
  423. 16:42I'm going to take care of the heavy
  424. 16:43lifting right now so let's connect these
  425. 16:45two strategies together so inside my
  426. 16:48first route I'm going to define the
  427. 16:51before function and in it I'm going to
  428. 16:53say if the current index is zero which
  429. 16:56means it's the beginning of the
  430. 16:57execution of the Strat
  431. 16:59I'm going to initiate two variables and
  432. 17:03I'm using this special dictionary
  433. 17:05variable inside Jesse called shared
  434. 17:07wordss now why is it called that it's
  435. 17:10called shared wordss as in whichever
  436. 17:11variable that you define in this
  437. 17:13dictionary is going to be shared among
  438. 17:16all the trading routes that you have and
  439. 17:17I'm calling the first one S1 position
  440. 17:20and I'm setting it to zero and then I
  441. 17:22Define another one for the second one
  442. 17:24and my shoot long is going to be very
  443. 17:27simple I'm going to say return true if
  444. 17:30the S1 position value equals one that's
  445. 17:32it and we're choosing one as in a long
  446. 17:35position so that means for a short
  447. 17:38position we need to do the opposite so
  448. 17:40that would be this right if the S1
  449. 17:43position equals minus1 next I will take
  450. 17:46care of closing these positions and
  451. 17:48that's going to be using the update
  452. 17:50position method and in it I'm going to
  453. 17:53say if the value of S1 position equals
  454. 17:55zero I'm going to use the self.
  455. 17:58liquidate method to liquidate the
  456. 18:00current position for this trading route
  457. 18:02next I'm going to go to the second
  458. 18:03strategy and inside this shoong I'm
  459. 18:06going to say return if the shared vs
  460. 18:10S2 position equals 1 and we're going to
  461. 18:13do the opposite for a short position and
  462. 18:15again be careful with the key here it
  463. 18:17needs to be S2 because we're inside the
  464. 18:19second strategy and then I'm going to
  465. 18:23define the update position and do the
  466. 18:26opposite of what I did for the first
  467. 18:28strategy so I'm saying if the S2
  468. 18:30position equals zero that means we need
  469. 18:32it to be closed so we will liquidate the
  470. 18:34current position right so next we have
  471. 18:37the position sizing so I'm going to back
  472. 18:39to the first route and inside the goong
  473. 18:42method I'm going to say this the
  474. 18:44quantity of my position is going to be
  475. 18:46the margin one which is this value that
  476. 18:49I'm going to Define for the the size of
  477. 18:52the position of the first position and
  478. 18:54I'm using this utility function called
  479. 18:56size to quantity which will take this as
  480. 18:59the first parameter and then the current
  481. 19:01price because I want to open the
  482. 19:03position with the market order and then
  483. 19:04I'm setting the trading fees and then
  484. 19:06all I need to do is to say self. buy
  485. 19:08equals quantity and then the current
  486. 19:10price to open a position using the
  487. 19:12current price and for the short position
  488. 19:14I'm going to do the opposite so again
  489. 19:17quantity equals
  490. 19:19this but instead of self. buy I'm
  491. 19:22passing self. sell equals quantity and
  492. 19:25then the current price all right so
  493. 19:27let's go to the second route
  494. 19:29and do the same thing here so I'm going
  495. 19:31to say Quantity equals this except that
  496. 19:35instead of margin one it needs to be
  497. 19:36margin two and then I will say s. buy
  498. 19:40equals quantity and then the current
  499. 19:41price and then for the go short position
  500. 19:45we'll do the same thing again ensure
  501. 19:47that this one is margin two and then
  502. 19:49instead of self. buy we have self. sell
  503. 19:52all right I don't know what you're
  504. 19:53thinking right now but if it's not clear
  505. 19:55yet don't worry cuz it's going to be in
  506. 19:57a second but all you need to know is
  507. 19:59that at this point these two strategy
  508. 20:01files are connected to each other so
  509. 20:04wherever we change these four variables
  510. 20:06the S1 position S2 position and S1
  511. 20:09margin and S2 margin is going to take
  512. 20:11effect everywhere but now we need to
  513. 20:13define the logic of our strategy the one
  514. 20:16we just implemented inside this Jupiter
  515. 20:18notebook inside our first strategy so in
  516. 20:21fact I'm not going to touch the second
  517. 20:23strategy file at all anymore I'm
  518. 20:25completely done with it but for the
  519. 20:26first one let's begin all right so let's
  520. 20:28let's go back to the Jupiter notebook
  521. 20:31and here we were getting the candles
  522. 20:33like this using the research module but
  523. 20:35if I do it like this during a back test
  524. 20:38there's a good chance I'm going to use
  525. 20:39data from the future and we don't want
  526. 20:42that right because that would produce
  527. 20:43unrealistic results so instead I want to
  528. 20:46use Jess's built-in features for fishing
  529. 20:48the candles which insures we don't
  530. 20:50accidentally cause the liad bias in our
  531. 20:52strategy all right so I'm going to go
  532. 20:54back to the first strategy and I will
  533. 20:56Define a new property called C1 and in
  534. 20:59it I'm going to pass self. getet candles
  535. 21:02which is that built-in method for
  536. 21:04fishing the candles and again this one
  537. 21:06in Short you don't fish candles from the
  538. 21:08future Jesse will take care of it behind
  539. 21:10the scenes to only give you candles that
  540. 21:12you had at that point in time and the
  541. 21:14first parameter is the exchange and
  542. 21:16we're passing the current exchange and
  543. 21:18then the symbol now this one it could
  544. 21:21have Simply Be ET us right but because I
  545. 21:25wanted to Define it dynamically instead
  546. 21:27I I can use this self. rout and then I'm
  547. 21:30selecting the index of zero and then I'm
  548. 21:33selecting its symbol so this way no
  549. 21:35matter in back testing whichever symbol
  550. 21:38I choose here it will work here and I
  551. 21:40don't have to change anything so it's
  552. 21:42better now I'm also doing the same thing
  553. 21:44for time frame so I'm passing self. time
  554. 21:46frame which will give it whichever time
  555. 21:48frame that I pick here so instead of
  556. 21:50simply saying 15 minutes I'm using self.
  557. 21:54time frame and because I want only the
  558. 21:57closing price I as I showed you earlier
  559. 21:59in the jupyter notebooks I'm selecting
  560. 22:02all of them but only the closing prices
  561. 22:04which has the index of two but I'm also
  562. 22:06selecting only the last 200 candles and
  563. 22:09why is that well in the jupyter notebook
  564. 22:11we only had candles for 2 days right but
  565. 22:15when we are back testing let's say we
  566. 22:17want to back test it on multiple months
  567. 22:18if you give it so much data the mean of
  568. 22:21this data series is going to change a
  569. 22:23lot and it's not going to even be
  570. 22:25remotely what we need it to be so I want
  571. 22:27to make sure that we we catch the
  572. 22:29pattern of only the most recent data and
  573. 22:32that could be the last 2 days 3 days
  574. 22:34whatever but the point is it has to be a
  575. 22:38static number and I chose 200 you can
  576. 22:41try any other number and see whichever
  577. 22:43works best for you all right so now
  578. 22:46let's define another one and call it C2
  579. 22:50which is going to be very similar except
  580. 22:52we're selecting the second route by
  581. 22:54using the index one and everything else
  582. 22:56is the rest so you see inside my first
  583. 22:59strategy file I have access to the data
  584. 23:02or everything from even the second
  585. 23:04strategy so that's why I said I'm not
  586. 23:06going to touch the second strategy file
  587. 23:08at all all right now let's define the
  588. 23:11zcore right so first we need the
  589. 23:15spread and that is going to be self. C1
  590. 23:19minus self. C2 and again we're selecting
  591. 23:22from the index of one until the end
  592. 23:25which again is what I just did inside
  593. 23:26the Jupiter notebook and then I'm we
  594. 23:28going to say zscore equals utils zscore
  595. 23:32and I'm passing the spread and in the
  596. 23:34end I'm returning zscore minus one which
  597. 23:37will give me the last item inside this
  598. 23:40array and that's going to be the only
  599. 23:41one that I care about cuz it's not like
  600. 23:43I want to paint a chart with it right
  601. 23:45right so where do we Define the logic of
  602. 23:46the strategy or the rest of it now
  603. 23:48everything else will happen inside the
  604. 23:51before function now by the way in case
  605. 23:53you didn't know the before function is
  606. 23:55the first method inside the strategy
  607. 23:57cycle of J that we get called so
  608. 24:00whichever value that we set inside the
  609. 24:03before function is going to be
  610. 24:04accessible inside everything else inside
  611. 24:07the shoot long the go long the update
  612. 24:09position everything so that's why I'm
  613. 24:11doing all the decision makings inside
  614. 24:13this one and then setting the decisions
  615. 24:15inside these variables and then I'm
  616. 24:17checking for the result of those
  617. 24:19variables like for example in here all
  618. 24:21right now let's continue so once every
  619. 24:2424 hours or one day I want to
  620. 24:26recalculate everything like I want to
  621. 24:28see if the pairs are still Co integrated
  622. 24:30or things like that so I'm going to say
  623. 24:32this if self index equals 0 which means
  624. 24:37in the beginning or if the remainder of
  625. 24:40self. index divided by one day worth of
  626. 24:44one minute candles and we can get that
  627. 24:46by saying 24 multiped by 60 divided by
  628. 24:51this number here right now what is this
  629. 24:53number because we're using the 15
  630. 24:55minutes this is basically 15 but as it
  631. 24:59was the case with whichever whatever I
  632. 25:02did here so instead of hard coding I was
  633. 25:04using Dynamic values so that if we
  634. 25:06change something inside the js's
  635. 25:08dashboard it will take effect here right
  636. 25:11so because of that instead of Simply
  637. 25:13dividing it by 15 I'm going to divide it
  638. 25:16by this value I'm using the utility
  639. 25:17module again and the function time frame
  640. 25:20to 1 minute and then I'm passing the
  641. 25:22current time frame which is 15 minutes
  642. 25:24and it is returning 15 now I'm saying if
  643. 25:27the remainder of this division is zero
  644. 25:30that means it has passed 24 hours then I
  645. 25:34want to check for qution is qug grated
  646. 25:37equals utils do R cointegrated and then
  647. 25:40I'm passing the first set of price
  648. 25:41returns and then I'm passing the second
  649. 25:43one and if they are not going integrated
  650. 25:45anymore I want to close all the
  651. 25:47positions and I can do that by setting
  652. 25:49both these values S1 position and S2
  653. 25:52position to zero all right now let's
  654. 25:54move on next we're going to define the
  655. 25:56zscore and we can simply get that using
  656. 25:59the self. Z score which we defined in
  657. 26:01here right so let's get that one now I'm
  658. 26:04going to say if the current position is
  659. 26:06closed and we can simply get that using
  660. 26:09this and the
  661. 26:11zcore is below the threshold that we
  662. 26:15Define in here you remember these two
  663. 26:17lines it was
  664. 26:201.2 and minus 1.2 so I'm going to use
  665. 26:22that here so if the zcore is below minus
  666. 26:271 2 then I'm going to say go long with
  667. 26:31the first position by simply setting it
  668. 26:33to one and go short the second position
  669. 26:37by simply setting it to minus one now
  670. 26:39next I'm going to say let's remove this
  671. 26:43next I'm going to say else if it is
  672. 26:45already long but the Z score is above
  673. 26:48zero now in other words so you remember
  674. 26:51this we went long here but once it
  675. 26:54reaches the mean we want to close the
  676. 26:55position so I'm going to say if the Z is
  677. 26:58is now above zero set this one to zero
  678. 27:02and also this one all right so both
  679. 27:04positions need to be zero or closed and
  680. 27:08next I'm going to say if it's a short
  681. 27:09position and the Z score is below zero
  682. 27:12and that would be this case so if we
  683. 27:14went short but the mean is now below the
  684. 27:17mean then again close both positions and
  685. 27:20lastly I'm going to say else if it is
  686. 27:22closed but the zcore is above 1.2 which
  687. 27:26would be this case I want to short the
  688. 27:29first position and long the second
  689. 27:31position all right now we have the
  690. 27:32decision- making of our strategy we know
  691. 27:34when exactly it's going to go long and
  692. 27:37when is going to go short however we're
  693. 27:39still missing one variable and that is
  694. 27:41the size of the position and this is
  695. 27:43really important because the bigger the
  696. 27:45size of the market cap of an asset the
  697. 27:47less volatile it will be so in our case
  698. 27:50we already know that the price of
  699. 27:52ethereum will move less than the price
  700. 27:54of ethereum classic so let's say they
  701. 27:56are moving exactly at the same time if
  702. 27:58only the size of the positions are
  703. 28:00exactly the same for example if we long
  704. 28:02one of them with $1,000 and short the
  705. 28:04other one with $1,000 when they move
  706. 28:07let's say they both go up it's still the
  707. 28:09one with the lower market cap which
  708. 28:10would be ethereum classic in this case
  709. 28:12and that means if it was the long
  710. 28:14position we're going to be in profit but
  711. 28:16if it was the short position we would
  712. 28:17lose money right and that's not what we
  713. 28:19want so we need to make sure the size of
  714. 28:21these positions are not exactly the same
  715. 28:23value but they are somehow equal in
  716. 28:26matter of like how much money money we
  717. 28:28would make or lose between them right
  718. 28:30now how do we do that so first I'm going
  719. 28:32to define a new function and I'm going
  720. 28:35to call it set proper margin per
  721. 28:39route all right and I'm going to call
  722. 28:43this firstly in here and second in here
  723. 28:48so again this is where we opened the
  724. 28:51first long position and the second short
  725. 28:53position and this is where we did the
  726. 28:55opposite right and these two were we
  727. 28:57were just closing an already open
  728. 28:59position now this is incorrect going to
  729. 29:01remove it now to calculate this I'm
  730. 29:04going to use a formula which again
  731. 29:06luckily Jesse provides us so we're going
  732. 29:08to get the alpha but I'm not going to
  733. 29:10use the alpha so I'm just going to pass
  734. 29:11an underline and then the beta and is
  735. 29:15going to equal utils do calculate Alpha
  736. 29:18Beta And this is this formula so we're
  737. 29:20using the assets model again right and
  738. 29:25this is the formula so the x equals add
  739. 29:27constant then we're passing the second
  740. 29:29returns and we're using a model to do
  741. 29:32linear regression I think and then that
  742. 29:34will give us the Alpha and the beta and
  743. 29:36then we are passing them I'm not going
  744. 29:38to go through the exact math behind it
  745. 29:40again if you want to just watch that
  746. 29:42video from quantopian which they do
  747. 29:44explain this better now this is giving
  748. 29:46us both the Alpha and the beta to
  749. 29:49calculate the margin I'm using the
  750. 29:52current available margin multiplied by 1
  751. 29:55ided by 1 + beta and for the second
  752. 29:59margin or the margin of the second
  753. 30:01position or the second strategy I'm
  754. 30:03using it like this now to be honest with
  755. 30:05you I'm not a math wizard myself and I
  756. 30:08use chat GPT heavily for writing this
  757. 30:10part but because I did a lot of testing
  758. 30:12I know it's actually working so sorry if
  759. 30:14I cannot explain this any better all
  760. 30:16right so that's it now we have the
  761. 30:18margin one the margin 2 and the values
  762. 30:20for S1 position and S2 position and now
  763. 30:23we're ready to execute our first
  764. 30:24practice so let's go back to Jesse and
  765. 30:28we have both the trading routes eth Etc
  766. 30:32the 15 minutes time frame P trading is
  767. 30:35selected but the second one also needs
  768. 30:37to be press rating two and the duration
  769. 30:41make sure the fast mode is off because
  770. 30:43it actually cannot work with multiple
  771. 30:45routes yet so if I try to start it here
  772. 30:47I'm going to get an error so let's turn
  773. 30:49this off and I'm going to leave the
  774. 30:52actually let's turn off The Benchmark
  775. 30:54first and let's run it all right so this
  776. 30:58result isn't right and I went back and
  777. 31:01found the issue the issue is that we are
  778. 31:03passing the current candles but as it
  779. 31:05was the case in here we later converted
  780. 31:08the current candles into price returns
  781. 31:10so we need to do the same thing in here
  782. 31:12so I'm going to select this and instead
  783. 31:15return prizes to returns and then pass
  784. 31:18this and this all right and I'm also
  785. 31:21going to do it here all right so again
  786. 31:24we are converting the current candles
  787. 31:25into price returns and and that's the
  788. 31:28correct format for the calculations that
  789. 31:30we did with zcore and everything else
  790. 31:32all right so let's go back and run this
  791. 31:34one more
  792. 31:35time there we go this Equity curve looks
  793. 31:38unbelievably good and is for the last 12
  794. 31:42months the profit was 69% the Maxon isus
  795. 31:485% the M rate is 53% the sharp is
  796. 31:522.94 and the calmer is
  797. 31:5513.77 all right so let's go back and
  798. 31:58turn on The Benchmark feature too and
  799. 32:00run it one more time so while that's
  800. 32:03going I want to quickly remind you guys
  801. 32:04that I recently added support for Apex
  802. 32:06Omni which is a DEX which means you will
  803. 32:08keep the custody of your funds and
  804. 32:10there's no kyc you just connect your
  805. 32:12metamask wallet and you're good to go if
  806. 32:14you want to get started with Apex please
  807. 32:15consider using our link which will give
  808. 32:17you trading fee discounts and you'll
  809. 32:19also be supporting making these videos
  810. 32:21all right so check this out while the
  811. 32:23price was going up we made money while
  812. 32:26the price was going down we made money
  813. 32:29when it was in a Range we also made
  814. 32:31money so that's why we call this
  815. 32:33strategy a market neutral strategy cuz
  816. 32:35no matter if it's going up or down or in
  817. 32:38range you're going to make money as long
  818. 32:40as the bet that these two prize assets
  819. 32:43are going to Great is true right so
  820. 32:45that's why it's really fantastic so guys
  821. 32:48this result is actually too good to be
  822. 32:50true so I'm just going to buy a Lambo
  823. 32:52and make videos about how rich I am all
  824. 32:53right see you in the next video but hold
  825. 32:55on a second there's a catch multiple
  826. 32:57love them you see unlike my other videos
  827. 33:00or back test that I run I actually
  828. 33:03disable the trading fees in this case
  829. 33:05that's why we are not paying any trading
  830. 33:07fees and this is really important
  831. 33:09because it is taking
  832. 33:137,818 trades over a year that's simply
  833. 33:17too many trades and it's not like we own
  834. 33:19the exchange or are friends with them we
  835. 33:21are going to have to pay for trading
  836. 33:23fees and we're not even in hedge fund
  837. 33:25because hedge funds and I'm guessing
  838. 33:27Edward torb two they paid very little
  839. 33:29fees because they had special contracts
  840. 33:31but we don't so if we set the trading
  841. 33:33fee to what it actually would be on
  842. 33:35bance features and run this one more
  843. 33:39time let's disable the Benchmark
  844. 33:42feature now the result actually looks
  845. 33:45awful so we started by 10,000 and we
  846. 33:48ended with
  847. 33:50$343 now why is this is because again
  848. 33:53we're taking too many trades and we are
  849. 33:54paying just too much in trading fees
  850. 33:56we're paying 11 $1,000 in trading fees
  851. 33:59now it actually gets worse in reality
  852. 34:02not only we would have to pay this much
  853. 34:03trading fees but we're also going to
  854. 34:05have slippage and because in this
  855. 34:07strategy at least at the current state
  856. 34:10of it we're even counting on trades with
  857. 34:12very small margin of profit so that
  858. 34:14means if there's going to be slippage
  859. 34:16which there will be the results will
  860. 34:18look even worse than this so to get the
  861. 34:20real estate results we need to set this
  862. 34:23to a higher number such as this or maybe
  863. 34:25this one so what does this mean it means
  864. 34:27that if you're a H fund you can probably
  865. 34:28already trade this if you can get some
  866. 34:30kind of special contract or trade it on
  867. 34:32an exchange that has very little fees
  868. 34:34but for most of us that's not the case
  869. 34:36so what we can do is to implement as
  870. 34:40many filters as possible to make sure
  871. 34:42that we only take the trades that are
  872. 34:44worth it now the other thing that we can
  873. 34:46do is to trade only assets that are more
  874. 34:49volatile for example mem coins we know
  875. 34:51they are correlated with each other but
  876. 34:53they move much more and that means our
  877. 34:55trades probably won't have as little
  878. 34:57profit margin which would make it worth
  879. 35:00it for us I'm going to share the source
  880. 35:01code of this strategy on a GitHub
  881. 35:03repository and link to it down in the
  882. 35:05description it's going to be your
  883. 35:06homework to keep doing research and
  884. 35:09implementing filters to improve the
  885. 35:11results of this strategy and make it
  886. 35:13actually production ready you can also
  887. 35:15try it on other markets with different
  888. 35:16trading assets and see if it works there
  889. 35:18or preferably with exchanges that have
  890. 35:20lower trading fees I would love to see
  891. 35:22you guys on our Discord and share with
  892. 35:24me your experience with this strategy
  893. 35:26and let me know what works for you and
  894. 35:28what doesn't so that hopefully we can
  895. 35:30improve it if many of you guys want me
  896. 35:32to make a follow-up video about this
  897. 35:33strategy I might do it so just let me
  898. 35:35know about it now as always we're going
  899. 35:37to have a giveaway the random person who
  900. 35:38likes this video posts a comment and
  901. 35:40subscribes to the channel is going to
  902. 35:42win 1 million bunk token all right let's
  903. 35:43pick the winner for the previous
  904. 35:46video and the winner is rames thank you
  905. 35:49so much for your comment please reach
  906. 35:50out to me so that I can send you your
  907. 35:52bunk tokens thanks for watching and I'll
  908. 35:53see you in the next one
  909. 35:56[Music]
  910. 35:58oh
  911. 36:01[Music]

About this transcript

This page contains the full transcript of Pairs-trading strategy from scratch in Python by Algo-trading with Saleh, generated from the public captions YouTube serves with the video. The transcript has 6,924 words across 911 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.