Skip to content

Instantly share code, notes, and snippets.

@silahian
Last active February 2, 2024 03:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save silahian/32186509ec9e0461017d377db0faa48e to your computer and use it in GitHub Desktop.
Save silahian/32186509ec9e0461017d377db0faa48e to your computer and use it in GitHub Desktop.
Observer pattern created by silahian - https://repl.it/HpbL/15
#include <string>
#include <vector>
#include <thread>
#include <iostream>
#include <unistd.h>
using namespace std;
class IObserver
{
public:
virtual void OnNotify() = 0;
};
class Strategy : public IObserver
{
public:
string StrategyName = "";
int StrategyTimeout = 0;
virtual void OnNotify()
{
sleep(StrategyTimeout);
std::cout << StrategyName << " has been notified." << std::endl;
}
};
class ISubject
{
public:
virtual bool RegisterObserver(IObserver* pObserver) = 0;
virtual void Notify() = 0;
};
class OrderBook : public ISubject
{
public:
OrderBook(): m_ObserverCount(0), m_pObservers()
{}
virtual bool RegisterObserver(IObserver* pObserver)
{
m_pObservers[m_ObserverCount++] = pObserver;
return true;
}
virtual void Notify()
{
//Send notification to all observers
for(int i = 0; i < m_ObserverCount; i++)
m_pObservers[i]->OnNotify();
}
private:
static const int ObserverCountMax = 10;
IObserver* m_pObservers[ObserverCountMax];
int m_ObserverCount;
};
int main()
{
OrderBook LOB;
Strategy strategies[10];
int iCount = 1;
for(auto& s : strategies)
{
s.StrategyName = "Strategy " + to_string(iCount++);
s.StrategyTimeout = 150; //let's assume that each strategy will take 150ms to process
LOB.RegisterObserver(&s);
}
LOB.Notify();
return 0;
}
@silahian
Copy link
Author

Showing how the observer pattern is not suitable for high frequency systems or low latency systems

@silahian
Copy link
Author

The idea is to simulate a trading system, where the observer acts as the strategy and the subject as the order book.

The order book will send notifications once any price has changed, so all the strategies can receive it and act on it. If the strategy meets its specific criteria, will trigger orders to the exchange. That process, of asserting if the criteria met, could be more or less complicated, hence could take more or less time.

As you can see, this is a serial process, and if for any reason “strategy 1” takes a couple of milliseconds to do some fancy calculations, then by the time “strategy 2” gets the notification is too late, and so on…. Until we get the notification for the last strategy, which is already making decisions on past information.

@eabase
Copy link

eabase commented Oct 23, 2020

I'm not able to get any output from this...

@georgeha
Copy link

georgeha commented Feb 21, 2023

Nice work!
How about parallelizing the OrderBook::Notify() function?
would that make the pattern usable?

@Physicworld
Copy link

Each strategy should have a separated thread to not stop the notification for each one...
So when a strategy receives a new notification, is ready to start doing fancy calculations on his own thread...
and also i think is good idea to parallelize that notify fun.

great work! i love your content/code on github is very usefull!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment