AdvancedCharts – (non) trivial look at the analysis of stock quotes

2021-03-17 DIS - a predetermined level of rebound from above, then an explicit stop correction from below /
2021-03-17 DIS – a predetermined level of rebound from above, then an explicit stop correction from below /

1. Background that you can and can skip

Text

To begin with, back in 2008, on a wave of general interest, I got hooked on Forex through dealing centers and the well-known MT4 platform. Being a very careful person, I wrote a trillion of all indicators and trading strategies that test this or that idea before blindly throwing it into my modest real account. One drain in half an hour of the entire trading account of $ 150 was enough to learn a lesson and not repeat such cases.

I changed about five dealing centers, the last of which was B *** KO. I left there a week or two before the sensational closing, because even then it smelled of kerosene. The instinct did not disappoint. After that, forex was abandoned, as it became clear that the divorce of suckers in the CIS interests DC much more than reputation.

After that, in 2013, no less distant now, I signed up for exchange trading courses organized online via Skype by one of the ideologists of the program for graphical market analysis, the name of which I will not give here. The bottom line was that, supposedly, trading decisions within the day should be made only having an idea of ​​what interest they have today large market players. The program showed this interest prominently – large trades and limit orders were reflected by graphical objects in the history with the ability to filter. The host of the courses himself was engaged in scalping using this platform, and often poured money when he played “to the public”, while claiming that on average his account was growing well and amounted to a couple of hundred thousand dollars. It was also difficult to grasp the reason why he entered the market during online scalping every time because he accumulated a position by making several transactions in one direction, long or short, based on a certain amount of knowledge about yesterday, a week, past large transactions, large orders, etc. Accumulating losses on open positions is like a dubious strategy for people who have much more modest opportunities, in the sense of small account sizes, for those who understand. Then options went into action, an analysis somewhere out there of something said by the head of the IMF or the European Central Bank, what interest rates are now, and so on, and his trading system has grown to a size beyond the control of an inexperienced intraday trader, who also has a normal job. full-time, family, and various other interests. The explanations became more and more extensive, the lectures became longer, it became simply impossible to follow his system, and I jumped off. Surprisingly – with a profit, since he himself had not yet traded in real life, but, being a programmer, I wrote a couple of plug-in indicators for that platform in C # on his order (and barely knocked the payment out of him, because he had decided that I’m doing it for free out of some solidarity with his ideas, but that’s another story).

At some point, I found myself abroad – a programmer in a German company, also with a contract for distance learning for a master’s program. The priorities were set accordingly, and trading moved to the tenth plan.

Nevertheless, the exchange trading course passed, as it turned out, laid down on fertile ground, and I brought from there a certain understanding of the basic principle – small things like private traders, and small investment funds are needed exactly to provide liquidity. This means that the hubbub and cacophony of millions of transactions in the market is still under the control of large players, skillfully guiding the whole herd in the right direction in order to make a profit.

We must pay tribute to those who see global market movements and develop strategies based on annual charts. And also to those who come directly from the opposite end and create companies engaged in high-frequency microsecond trading, with high-speed optics all the way to the exchange, special drivers for network cards, and some kind of mega-brains that stand, judging by the ads on recruiting sites, “450kilo rubles per month plus commissions on profit from strategies” …

Neither the first nor the second is not our method, since no more than a thousand bucks can be deposited into a trading account without harming the family budget, and trading as the aforementioned marginals is fraught with loss of account on wild stops on daily basis, or ruin on commissions for transferring positions. I am generally silent about the high-frequency one, it is not available to a private trader. Well, at least that was the case when I made the decision to develop.

Like now? Now you probably entrust your budgets to the “investment programs” of various Russian banks, or even open “trading accounts” and buy shares in Gazprom and Aeroflot. There are insiders, I do not argue, with financial education, who understand what, where and when to buy. I do not count myself among them.

I look at things from the position of a programmer who really wants to trade within the day, have 20% of the deposit per month, while there is an idea how this can be implemented, which means everything is simple – the idea needs to be tested. It is important not to forget – you need to find something in the junk stream of market data that will indicate the “interest of the big players.” Grail? Yes! That is, it is necessary to repeat the feat of the developers of the graphical analysis platform already mentioned here. At the same time, I will have my own software, which means free, and available for modernization, testing ideas, and all those bonuses that please the heart of a programmer so much – to have power over a money-making program, moreover, developed from and to his own hands.

A prototype of a program that implements my vision of market analysis was written at Delphi in 2016, then postponed for two or three years due to studies and new jobs. The problem with studies was solved in 2019 by defending a master’s degree.

From that moment on, work on the analytical platform continued without interruption. More precisely, it started anew, now in C ++ in QT using OpenGL to display graphs and filtered events. A teaspoon a month.

2. AdvancedCharts market data analysis platform

Now you can move on to what actually happened at the time of publication of this blog.

To begin with, a comparison of the resource consumption of my home PC: when using the terminal of my broker (it reaches 70% CPU) and my modest analytical platform (rarely higher than 10% CPU, despite the fact that I display not just candles, but create a graphical object for each deals, of which hundreds of thousands per day per instrument, plus dozens of changes per second from limit orders at the best price and in the order book). It’s useless to swear with a broker, they pray to their platform and upgrade a teaspoon a year.

Now we are developing a communicator for a data source https://tradernet.ru/tradernet-api/

To connect to API uses socket.io for C ++ programs, taken from here https://github.com/socketio/socket.io-client-cpp , in combination with QNetworkAccessManager.

For example, a SID request looks like this (you must be registered with ffin.ru):

void connectorFFIN::connectAPI()
{
    QUrl url("https://tradernet.ru/api/check-login-password");
    QNetworkRequest request(url);

    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");

    QUrlQuery params;
    params.addQueryItem("login", "your_email@mailserver.com");
    params.addQueryItem("password", "your_password");
    params.addQueryItem("rememberMe", "1");
    params.addQueryItem("mode", "regular");
    params.addQueryItem("userId", "your_userID");

    m_status=requestType::Open;
    m_manager->post(request, params.query().toUtf8());
}

The result of the request comes in the form of a JsonDocument with named fields. The resulting SID is used in some requests that require authorization.

MarketsInfo Request:

void connectorFFIN::requestMarketsInfo()
{
    QUrl url("https://tradernet.ru/api/");
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    QUrlQuery params;
    params.addQueryItem("q", "{"cmd":"getMarketStatus","params":{"market":"*"}}");

    m_status=requestType::MarketsInfo;
    m_manager->post(request, params.query().toUtf8());
}

Request for a list of top instruments:

void connectorFFIN::request_topInstruments()
{    
    QUrl url("https://tradernet.ru/api/");
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    QUrlQuery params;
    FFINPARA map;
    params.addQueryItem("q", m_ffinQueryTops.GetQueryText(map));

    m_status=requestType::getTopSecurities;    
    m_manager->post(request, params.query().toUtf8());
}

Instrument list query with search query and filter:

void connectorFFIN::request_searchInstruments(const QString& keyWord)
{
    QUrl url("https://tradernet.ru/api/search");
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    QUrlQuery params;
    FFINPARA map({{QString("text"),keyWord}});
    params.addQueryItem("q", m_ffinQuerySearch.GetQueryText(map));

    m_status=requestType::searchInstruments;
    m_manager->post(request, params.query().toUtf8());
}

Where GetQueryText for search query “AAP” returns something like:

"{"cmd":"tickerFinder","params":{""text":"AAP"""+"}}"
  //                      -------------------------^

And the result of this request is a JsonDocument, you can get a list of tickers from which you can convert the binary data of the QByteArray of the response:

void cFFINQuerySearch::SetAnswer(const QByteArray& data)
{
    QVector<QString> result;
    QJsonDocument d = QJsonDocument::fromJson(data);
    qInfo() << d;
    auto arr=d["found"].toArray();
    for (auto it = arr.begin(); it !=arr.end(); it++)
    {
        if ((*it).isObject())
        {
            auto item=(*it).toObject();
            if (item.find("t")!=item.end())
                result.push_back(item.value("t").toString());
        }
    }

    emit signalSearchResults(result);
}

And fill the list in the WatchList window:

A parser for tick data subscription results has already been written.

void connectorFFIN::bindEvents()
{
    m_socket->on("q", sio::socket::event_listener_aux([&](std::string const& name, message::ptr const& data, bool isAck, message::list &ack_resp)
        {
            m_lock.lock();
            QByteArray a = QByteArray(socketIOToJson(data,"").toStdString().c_str());
            QJsonParseError p;
            QJsonDocument doc=QJsonDocument::fromJson(a,&p);             

             if(p.error !=  QJsonParseError::NoError)
             {
                 qInfo() << "ERROR: socket.io response parsing failed" << p.errorString();
              
             }
            emit signalTAS(doc);
		        m_lock.unlock();

        }));
    m_socket->on("b", sio::socket::event_listener_aux([&](std::string const& name, message::ptr const& data, bool isAck, message::list &ack_resp)
        {
             m_lock.lock();
             QByteArray a = QByteArray(socketIOToJson(data,"").toStdString().c_str());
             QJsonParseError p;
             QJsonDocument doc=QJsonDocument::fromJson(a,&p);             

             if(p.error !=  QJsonParseError::NoError)
             {
                 qInfo() << "ERROR: socket.io response parsing failed" << p.errorString();
             }             
		         emit signalLVL(doc);
		         m_lock.unlock();
        }));
}

In general, the result of the work looks like this. I publish some screenshots on the channel https://t.me/acharts

(The charts are still being built on another source, not ffin.ru – the work here is not finished yet).

Here are some of them, the most typical:

2021-04-21 MSFT - accumulation before short corrections
2021-04-21 MSFT – accumulation before short corrections
MSFT - short accumulation
MSFT – short accumulation
2021-04-19 AAPL - a narrow corridor of large orders was marked in the morning, the levels were not broken during the day
2021-04-19 AAPL – a narrow corridor of large orders was marked in the morning, the levels were not broken during the day
2021-04-06 AAPL - strong accumulation before turning to short
2021-04-06 AAPL – strong accumulation before turning to short
2021-03-25 AAPL - The trading range is indicated by purchase orders.  Here is a chart without candle contours
2021-03-25 AAPL – The trading range is indicated by purchase orders. Here is a chart without candle contours
2021-08-12 MRNA - clicking on the chart updates the TreeMap indicator with volume-sorted unit trades at that point
2021-08-12 MRNA – clicking on the chart updates the TreeMap indicator with volume-sorted unit trades at that point

I consider the method of composing data for subsequent display on graphs to be my know-how, so I do not consider it within the framework of this article. Although I admit that there are one or two other platforms that have long come to this and, perhaps, have a better result due to the availability of resources for development.

3.Results of preliminary verification on a real account

I will not name my broker. It is important that on a deposit of $ 300 or more, you can work with fractional lots within a day.

When I opened an account for 500 dollars, I lost 25 bucks in commission from the transfer (i.e., I started working with 475 dollars), but as a result of trading in less than a month, I grew it back to 500.

I traded very carefully, taking 10–20 pips per trade, although I knew for sure that I could be more aggressive. But this was the first month of testing. Further it will be easier, although in general I do not plan to trade manually myself.

4. Conclusions

As in a well-known phrase, the more I know, the more questions I come across. Likewise, the further the development of the platform progresses, the more opportunities appear, ideas that need to be tested. So far, everything depends on the lack of time.

Here’s a rough list.

– Connect to a stable low-cost tick data source with its own API, some of it has already been implemented, the list needs to be expanded. Keep an eye http://polygon.io with a similar API. Maybe the next one will be TINKOFF API https://habr.com/ru/post/592093/

– See what you can find on different exchanges, not just New York.

– See what you can find on cryptocurrencies.

– See what you can find in Forex.

– Optimization of the program, memory use (the data itself in binary form for six of my favorite tools per day is more than a gigabyte, plus they need to be parsed, “expanded” into data structures, which automatically increases the amount of memory used several times. Plus memory for graphic objects.

– Refinement of my indicators, namely – TreeMap at any point on the chart or over a period; show Quotes on the chart; there is a groundwork from the first prototype that has not yet been copied into C ++ – analysis of deals in combination with Level2 – detection of the accumulation of large positions.

– The classic NinjaTrader market profile was also in the prototype.

– Adding indicators for classic algorithms (moving averages, etc.)

– Small things on the interface – scrolling charts, scaling, adding types of graphic objects.

– Adaptation to all new data sources (new connectors and parsers).

– Machine learning methods for making trading decisions, or at least helping to identify patterns in my system.

For sim I take my leave. Thanks in advance for your constructive criticism.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *