All you see is "future" and "promise" here is the deal: Code: renko1[lookBack].high; renko1.high(index); e.broken_swing_high(lookBack); // strategy timeline of events with positive lookback //all events come here void Linkers::X(Object &x, EventType &e, Index &begin, Index &end, ObjectType &type) { // begin is beginIndex, end is endIndex in the timeline of historical events // during tick event (any platform) there can be multiple events //it would be foolish for the DLL to call void Linkers::X() on every single event! }
When you approach 3k+ LOC (and it's probably more than you think), then you start getting ideas how to improve the structure, but by then it may be too late! This is for those who constrain their code, For those who regularly produce 10k+ LOC there's simply no hope for you unfortunately.
It depends. For smaller components that just takes days/weeks to finish, this is the cheapest option, and redoing might be very rapid indeed because you know exactly what to do. However, for projects/monoliths that has embedded alot of useful functionality, bugfixes and features over time/multiple iterations, even if warty, they may have a value of their own (to you), and then you'll want to make the code easy to refactor, from the start or else do over! Unfortunately, the more structure the programmers impose on the code, the less likely you are to successfully refactor it. You've already painted yourself in the corner. Though this approach may not work with a larger team or when micromanaged, since the structure is hidden not codified in the sourcecode, thus not restricting future code changes. Such code may be warty, full of long functions, etc., but still serve useful / flexible future purposes, repurposing and be properly scoped inside. What I'm trying to say here: Not everything needs to be defined as a class and instantiated as an object with full retard hierarchical tree, not everything needs to be defined explicitly as a function or procedure and when everything runs DRY, one tends to tangle everything up. The more one strives for perfection in abstract concepts and structures, in the end, the less readable, concise, independent, simple and performant the code tends to evolve. The structure should emerge out of practical necessity. That necessity may vary wildly due to circumstances and progress. You may say the code should've been modularized from the start, but if you don't know exactly how the final result should be, that is too much structure for such projects. For waterfall projects where you've got all requirements from the start and you know there will be no major future requirement changes, you can structure away, and make it all fixed in place. So I think it's a spectrum of two dimensions, of programmer experience and programmer utility. Generally: People putting code on pedestals tend to miss the ephemeral and imperfect nature of code, why it is made, for what purposes and costs. So I tend to use what makes me happy. These days it's golang, used to be ruby, c++, asm, pascal, basic. I could use functional programming for codifying edge itself, and am approaching simple ways of automating different variations of such, but not sure if I'd want to go full retard in regards to functions, or just have very simple calls and adjust the code underneath as I've started to do now. I want simplicity, performance, flexibility and reproducability (versioning). Maybe something to be taken in account for the daydream? Maybe realizing it is a bit more complicated than the vision?
I just ran wc on my code for one of the more complex strategies - it’s about 6k lines I am pretty sure it can be done in half of that now
All valid points. However, if you don't get into the practice of throwing away, your project will never see a refactoring. Regularly throwing away enforces interface-based programming. I love Typescript for this: I can create a compile-time interface, make it as simple as needed and then implement the mess behind it without any runtime "overhead" (it's JavaScript in the end lol)
I got very silly understanding of C++, all im seeing is buffers of <char*> and how it's been done in 80's. Since i don't use std:: containers at all, but rather have my own expandable encrypted containers xVector, xString, xArray, xQueue, xStack, xSeries, written in such a plain C++ that i could easily pin down some memory in C# and compile my LinkersX code in C# Code: //example: struct MqlRates { datetime time; // Period start time double open; // Open price double high; // The highest price of the period double low; // The lowest price of the period doublec lose; // Close price long tick_volume; // Tick volume int spread; // Spread long real_volume; // Trade volume }; xQueue<MqlRates> queue1; // no size since it expands;) quque1.push(queue1);
I had a co-pm that was big into refactoring code. I think he is still re-factoring that engine instead of making money.