Surely the number of ply is not a big issue on the number of lines since the code will be recursive? 150 lines sounds remarkably few though.
Why is my chess engine source code so huge?

I'm not a programmer, but yeah, 150 lines of code sounds awfully small. TSCP is a small tutorial engine, and even it has over 2200 lines of code.
http://www.tckerrigan.com/Chess/TSCP/
A good meta site for chess engine programming is:
https://adamsccpages.blogspot.com/p/chess-programming-resources.html

Perhaps you're not comparing apples with apples? You say your code includes a GUI. Do the others, or are they engines that need an external GUI? Do they play at equivalent strength? Are you using the same language? For some usecases it makes a huge difference to code size.

There a chess engine written in Python called Sunfish which has only 111 lines in its source code. The code is also readable and very neat, it is gold if you want to learn efficient chess programming.
I played a few games against it and it does play fairly well, it doesn't make random moves like some of the other really weak engines.
https://github.com/thomasahle/sunfish
This is what Tord Romstad (One of the main developers of Stockfish) had to say about Sunfish - "Remarkably readable, too. Not at all what I expected. Good job!"

I'm not a programmer, but yeah, 150 lines of code sounds awfully small. TSCP is a small tutorial engine, and even it has over 2200 lines of code.
TSCP is big because first, it is written in C. From experience I can say that what can be achieved by 20 lines of code in C can be achieved in less than 4 lines using higher level languages like Python. Even C++ with its STL library can reduce the number of lines drastically.
Secondly it is a tutorial engine, so it is heavily commented which obviously increases the number of lines.

Engines should be written in Assembly ...that's the ideal.
Actually there is something called asmfish, which is a complete rewrite of Stockfish in assembly. It is seen that asmfish is slightly faster (because it is written in assembly) and thus stronger than Stockfish.
https://github.com/lantonov/asmFish

Yeah, I'm not sure why they don't use that in TCEC, but I assume it's because changing the engine on the fly between games like they do would take too long.

Yeah, I'm not sure why they don't use that in TCEC, but I assume it's because changing the engine on the fly between games like they do would take too long.
I'm not sure, but I think it's because asmfish is a completely independent project from Stockfish and the SF developers have no relation to asmfish.
I also heard somewhere that Mohammed, the developer of asmfish was joining the development team of Komodo. Not sure if the news was real or just a hoax.

Also if you want to quickly contact other developers with any queries, I recommend you to visit the 24/7 TCEC chat here - http://chatwing.com/tcec. It's a live chat where you can ask questions and get answers almost instantly. I've seen Mohammed, Robert Houdart, Tom Romstad etc. on the chat there.

My chess self-made chess engine has well over 2000 lines of code and only a two-ply search depth. (It has GUI and notation code and fully supports threefold repetition, 50-move and insufficient material draw, but even so.) So why do some engines (which are probably much stronger) have well under 150 lines? What did I do wrong?
I don't know your programming background so can't comment on whether you are doing anything wrong. If you give some more info, maybe I can help more. Like language? framework?
As a comparison, I recently started writing a chess program, it is geared for 2-person play. so the engine doesn't play chess, but it does know checkmate, stalemate, chess clock, and legal moves (en passant, castling, promotion, 3-repeat, king safety). The engine is complete and tested, currently finishing up the GUI part.
Here's my engine's overall line count:
[internet2@localhost chess]$ wc -l *.java
62 Bishop.java
287 Board.java
11 ChessColor.java
75 Chessman.java
80 Clock.java
26 ClockSelfDriven.java
276 Game.java
274 King.java
71 Knight.java
158 Location.java
209 Pawn.java
66 Queen.java
71 Rook.java
1666 total
Comments is probably 40-50% of the lines, so code line count is probably 850 lines.
To add some intelligence to play a nearly-random-move game of chess, it'll probably take 50 lines. The search depths should not affect the line count too much, i.e. search 2 moves ahead vs 100 moves ahead should be the same line count. The trouble is, for a simple minded program, it may have pruned a useful board position too early causing deep searches useless. So, in that case, the line count may increase (to give it more intelligence). Also, in the beginning, I'd use a database of openings to play; this can give the program the appearance of being strong w/o much coding. Plus, later searches with fewer pieces can be more thorough as the fewer pieces shouldn't make the search take as long.
Overall, I think a program that can beat me (which isn't all that hard to do, something like chess.com's computer level 3), is probably another 1000 lines. So a total of 1800 lines for a level 3 engine.

Surely the number of ply is not a big issue on the number of lines since the code will be recursive? 150 lines sounds remarkably few though.
Unfortunately It's not yet recursive.

Perhaps you're not comparing apples with apples? You say your code includes a GUI. Do the others, or are they engines that need an external GUI? Do they play at equivalent strength? Are you using the same language? For some usecases it makes a huge difference to code size.
The engine with under 150 is python, mine is HTML / JavaScript.

There a chess engine written in Python called Sunfish which has only 111 lines in its source code. The code is also readable and very neat, it is gold if you want to learn efficient chess programming.
I played a few games against it and it does play fairly well, it doesn't make random moves like some of the other really weak engines.
https://github.com/thomasahle/sunfish
This is what Tord Romstad (One of the main developers of Stockfish) had to say about Sunfish - "Remarkably readable, too. Not at all what I expected. Good job!"
Actually, it was sunfish I was referring too. The fact that we both saw this probably implies that such small engines are, in fact, a rarity.

this guy wrote a javascript engine in 2000 characters
http://nanochess.org/chess4.html
He gives the source code as well. I think it held some kind of world record for being the smallest working chess program for a while. Not sure if it still does.
Boot chess is however only 487 bytes.
http://www.pouet.net/prod.php?which=64962

this guy wrote a javascript engine in 2000 characters
2000 characters and 30 lines, very impressive. But not very readable.

You can buy his book where he breaks everything down
https://www.amazon.com/Toledo-Nanochess-commented-source-code/dp/1304864375
My chess self-made chess engine has well over 2000 lines of code and only a two-ply search depth. (It has GUI and notation code and fully supports threefold repetition, 50-move and insufficient material draw, but even so.) So why do some engines (which are probably much stronger) have well under 150 lines? What did I do wrong?