// File: /workspace/github_c_makefile_star2_O3/antirez[P]stonky/stonky.c
// Function: scanStocksThread
void *scanStocksThread(void *arg) {
    UNUSED(arg);
    DbHandle = dbInit(0);
    int j = 0;

#if 0 /* Debugging. */
    Symbols[0] = "SE";
    Symbols[1] = "AAPL";
    Symbols[2] = "SHOP";
    Symbols[3] = "AMZN";
    Symbols[4] = "RIOT";
    NumSymbols = 5;
#endif

    while(1) {
        sds symbol = Symbols[j % NumSymbols];
        botStats.scanned++;
        j++;

        /* Fetch 5y of data. Abort if we have less than 253 prices.
         *
         * Set a TTL from 6 to 8 hours, so that things will not expire
         * at the same time, and we'll hit Yahoo servers in a more
         * soft way. Otherwise the background stocks scanner will end
         * caching all the symbols nearly at the same time, and they will
         * expire (and get re-fetched) all about at the same time. */
        int ttl = (3600*6) + (rand() % (3600*2));

        ydata *yd = getYahooData(YDATA_TS,symbol,"5y","1d",ttl);
        if (yd == NULL || yd->ts_len < 253) {
            freeYahooData(yd);
            continue;
        }

        /* Don't handle data with more than 1% of bogus entries. */
        if (checkYahooTimeSeriesValidity(yd,1) == C_ERR) {
            freeYahooData(yd);
            continue;
        }

        /* Compute Montecarlo two times, for the last year, and for
         * the last two months, detecting big changes. */
        mcres mcvl, mclong, mcshort, mcvs, mcday;
        computeMontecarlo(yd,253*5,1000,5,&mcvl);   /* 5y */
        computeMontecarlo(yd,253,1000,5,&mclong);   /* 1y */
        computeMontecarlo(yd,60,1000,5,&mcshort);   /* 3m */
        computeMontecarlo(yd,20,1000,5,&mcvs);      /* 1m */
        computeMontecarlo(yd,10,1000,1,&mcday);     /* 15d */
        yahooDataToPriceChanges(yd,10);
        int vol10_ldays = yd->ldays;
        int vol10_pdays = yd->pdays;
        freeYahooData(yd);

        /* Now get the price info and cache what we plan to use. */
        double price = 0, cap = 0;
        yd = getYahooData(YDATA_QUOTE,symbol,NULL,NULL,ttl);
        if (!yd) continue;
        price = yd->reg;
        cap = yd->cap;
        freeYahooData(yd);

        int showstats = DebugMode ? 1 : 0;
        if (VerboseMode)
            printf(
            "Scanning %s: VL%.2f(+-%.2f%%) -> L%.2f(+-%.2f%%) ->\n"
            "         S%.2f(+-%.2f%%) -> VS%.2f(+-%.2f%%) -> D%.2f(+-%.2f%%)\n"
            "         LD %d PD %d LASTPRICE: %.2f CAP: %.0fM\n"
                ,symbol,
                mcvl.gain, mcvl.absdiffper,
                mclong.gain, mclong.absdiffper,
                mcshort.gain, mcshort.absdiffper,
                mcvs.gain, mcvs.absdiffper,
                mcday.gain, mcday.absdiffper,
                vol10_ldays, vol10_pdays, price, cap/1000000);

        if (mclong.gain < mcshort.gain &&
            /* Tothemoon: stocks that performed poorly in the past, but
             * now are monotonically performing better as we look progressively
             * at nearest periods. They must have a small variability of
             * positive performances in the latest days to get accepted.
             *
             * The idea is to find new trends and stocks that are resurrecting
             * for some reason. Many will be penny stocks. */
            mclong.gain < 3 &&           /* Not too strong historically. */
            mcshort.gain <  mcvs.gain && /* Are getting better. */
            mcshort.gain > 3 &&          /* Very high gains recently. */
            mcvs.gain > 8 &&             /* Very high gains recently. */
            mcday.gain > 1 &&            /* High daily gains last month. */
            mcshort.absdiff < 8)         /* Some consistency. */
        {
            char *listname = price < 15 ? "tothemoon-penny" : "tothemoon";
            if (VerboseMode)
                printf("%s: %d/%d %s\n",listname,j,NumSymbols,symbol);
            dbAddStockToList(listname, symbol);
            showstats=1;
        } else if (
            /* Big cap stocks with a long history of good results that
             * are doing even better now. */
            mcvl.gain < mclong.gain &&      /* Getting better in the long. */
            mclong.gain < mcshort.gain &&   /* Getting better in the short .*/
            mcshort.gain < mcvs.gain &&     /* Getting even better now. */
            mcvl.gain > 0.5 &&              /* Positive in the very long. */
            mclong.gain > 2 &&              /* Quite good in the long. */
            mcshort.gain > 3 &&             /* Good in the short. */
            mcvs.gain > 4 &&                /* Outstanding in the short. */
            mcday.gain > 1)
        {
            char *listname = cap > 3000000000 ? "evenbetter" :
                                                "evenbetter-smallcap";
            if (VerboseMode)
                printf("%s: %d/%d %s\n",listname,j,NumSymbols,symbol);
            dbAddStockToList(listname, symbol);
            showstats=1;
        } else if (
            /* New experiment about stocks that had positive results
             * every single day of the last 10 days of trading. Needs
             * tuning. */
            mclong.gain > 0.5 &&
            mcshort.gain > 3 &&
            mcvs.gain > 3 &&
            vol10_ldays == 0 && vol10_pdays > 0 &&
            price > 10)
        {
            if (VerboseMode)
                printf("unstoppable: %d/%d %s\n",j,NumSymbols,symbol);
            dbAddStockToList("unstoppable", symbol);
            showstats=1;
        } else {
            dbDelStockFromList("tothemoon", symbol, 0);
            dbDelStockFromList("tothemoon-penny", symbol, 0);
            dbDelStockFromList("evenbetter", symbol, 0);
            dbDelStockFromList("evenbetter-smallcap", symbol, 0);
            dbDelStockFromList("unstoppable", symbol, 0);
        }

        if (showstats && VerboseMode) {
            printf("%d/%d %s:\n"
                   "L  %f (+-%f %f%%) [%f/%f] ->\n"
                   "S  %f (+-%f %f%%) [%f/%f] ->\n"
                   "VS %f (+-%f %f%%) [%f/%f]\n"
                   "D  %f (+-%f %f%%) [%f/%f]\n",
                j,NumSymbols,symbol,
                mclong.gain, mclong.absdiff, mclong.absdiffper,
                mclong.mingain, mclong.maxgain, mcshort.gain,
                mcshort.absdiff, mcshort.absdiffper,
                mcshort.mingain, mcshort.maxgain, mcvs.gain,
                mcvs.absdiff, mcvs.absdiffper, mcvs.mingain,
                mcvs.maxgain, mcday.gain, mcday.absdiff, mcday.absdiffper,
                mcday.mingain, mcday.maxgain);
        }
        usleep(ScanPause);
    }
    dbClose();
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x178, %rsp            # imm = 0x178
xorl %edi, %edi
callq 0x90d1
movq %rax, %fs:-0x8
leaq 0x2c95(%rip), %r15      # 0xf542
leaq 0x20da(%rip), %rbp      # 0xe98e
xorl %r12d, %r12d
movq 0x8e42(%rip), %rcx      # 0x15700
movl %r12d, %eax
cltd
idivl 0x8e40(%rip)            # 0x15708
movq (%rcx,%rdx,8), %r13
incq 0x8a1d(%rip)            # 0x152f0
incl %r12d
callq 0x20d0
cltq
imulq $-0x6e5d4c3b, %rax, %rcx # imm = 0x91A2B3C5
shrq $0x20, %rcx
addl %eax, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
sarl $0xc, %ecx
addl %edx, %ecx
imull $0x1c20, %ecx, %ecx     # imm = 0x1C20
negl %ecx
leal (%rax,%rcx), %ebx
addl $0x5460, %ebx           # imm = 0x5460
movl $0x1, %edi
movq %r13, %rsi
movq %r15, %rdx
movq %rbp, %rcx
movl %ebx, %r8d
callq 0x88ec
testq %rax, %rax
je 0xc8b7
movq %rax, %r14
movslq 0x78(%rax), %rax
cmpq $0xfc, %rax
jle 0xc959
movq 0x80(%r14), %rcx
xorl %edx, %edx
xorl %esi, %esi
xorps %xmm1, %xmm1
movss (%rcx,%rdx,4), %xmm0
cmpeqss %xmm1, %xmm0
movd %xmm0, %edi
subl %edi, %esi
incq %rdx
cmpq %rdx, %rax
jne 0xc93d
cmpl %eax, %esi
jle 0xc966
movq %r14, %rdi
callq 0x885a
jmp 0xc8b7
movq %r14, %rdi
movl $0x4f1, %esi            # imm = 0x4F1
movl $0x3e8, %edx            # imm = 0x3E8
movl $0x5, %ecx
leaq 0x148(%rsp), %r8
callq 0x98d2
movq %r14, %rdi
movl $0xfd, %esi
movl $0x3e8, %edx            # imm = 0x3E8
movl $0x5, %ecx
leaq 0xe8(%rsp), %r8
callq 0x98d2
movq %r14, %rdi
movl $0x3c, %esi
movl $0x3e8, %edx            # imm = 0x3E8
movl $0x5, %ecx
leaq 0xb8(%rsp), %r8
callq 0x98d2
movq %r14, %rdi
movl $0x14, %esi
movl $0x3e8, %edx            # imm = 0x3E8
movl $0x5, %ecx
leaq 0x118(%rsp), %r8
callq 0x98d2
movq %r14, %rdi
movl $0xa, %esi
movl $0x3e8, %edx            # imm = 0x3E8
movl $0x1, %ecx
leaq 0x88(%rsp), %r8
callq 0x98d2
movq %r14, %rdi
movl $0xa, %esi
callq 0x8dc0
movl 0x98(%r14), %ebp
movl 0xa0(%r14), %r15d
movq %r14, %rdi
callq 0x885a
xorl %edi, %edi
movq %r13, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movl %ebx, %r8d
callq 0x88ec
testq %rax, %rax
je 0xce11
movss 0x20(%rax), %xmm0
movss %xmm0, 0x6c(%rsp)
movss 0x40(%rax), %xmm0
movss %xmm0, 0x68(%rsp)
movq %rax, %rdi
callq 0x885a
cmpl $0x0, 0x884d(%rip)      # 0x152b0
setne %bl
cmpl $0x0, 0x8847(%rip)      # 0x152b4
movsd 0xe8(%rsp), %xmm2
movsd 0xb8(%rsp), %xmm4
movsd 0x118(%rsp), %xmm6
movsd %xmm4, 0x80(%rsp)
movsd %xmm2, 0x78(%rsp)
movsd %xmm6, 0x70(%rsp)
je 0xcb41
cvtss2sd 0x6c(%rsp), %xmm10
cvtss2sd 0x68(%rsp), %xmm9
movsd 0x148(%rsp), %xmm0
movsd 0x168(%rsp), %xmm1
movsd 0x108(%rsp), %xmm3
movsd 0xd8(%rsp), %xmm5
movsd 0x138(%rsp), %xmm7
movsd 0x88(%rsp), %xmm11
movsd 0xa8(%rsp), %xmm8
divsd 0x1c35(%rip), %xmm9     # 0xe730
movsd %xmm9, 0x18(%rsp)
movsd %xmm10, 0x10(%rsp)
movsd %xmm8, 0x8(%rsp)
movsd %xmm11, (%rsp)
leaq 0x3d1c(%rip), %rdi      # 0x10839
movq %r13, %rsi
movl %r15d, %edx
movl %ebp, %ecx
movb $0x8, %al
callq 0x2030
movsd 0x70(%rsp), %xmm6
movsd 0x78(%rsp), %xmm2
movsd 0x80(%rsp), %xmm4
movss 0x68(%rsp), %xmm5
movss 0x6c(%rsp), %xmm3
movsd 0x1be3(%rip), %xmm1     # 0xe738
ucomisd %xmm2, %xmm1
jbe 0xcbb8
ucomisd %xmm2, %xmm4
jbe 0xcbb8
ucomisd 0x1b3f(%rip), %xmm6     # 0xe6a8
jbe 0xcbb8
ucomisd %xmm1, %xmm4
jbe 0xcbb8
ucomisd %xmm4, %xmm6
jbe 0xcbb8
movsd 0x88(%rsp), %xmm0
ucomisd 0x1ba0(%rip), %xmm0     # 0xe728
jbe 0xcbb8
movsd 0x1b16(%rip), %xmm0     # 0xe6a8
ucomisd 0xd0(%rsp), %xmm0
jbe 0xcbb8
movss 0x1cd3(%rip), %xmm0     # 0xe878
ucomiss %xmm3, %xmm0
leaq 0x3d3f(%rip), %rbx      # 0x108ee
leaq 0x3d28(%rip), %rax      # 0x108de
jmp 0xcc27
ucomisd %xmm2, %xmm4
jbe 0xcc56
movsd 0x148(%rsp), %xmm0
ucomisd %xmm0, %xmm2
jbe 0xcc56
ucomisd 0x1ae3(%rip), %xmm6     # 0xe6c0
jbe 0xcc56
ucomisd %xmm1, %xmm4
jbe 0xcc56
ucomisd 0x1b53(%rip), %xmm2     # 0xe740
jbe 0xcc56
ucomisd 0x1b51(%rip), %xmm0     # 0xe748
jbe 0xcc56
ucomisd %xmm4, %xmm6
jbe 0xcc56
movsd 0x88(%rsp), %xmm0
ucomisd 0x1b18(%rip), %xmm0     # 0xe728
jbe 0xcc56
ucomiss 0x1c5b(%rip), %xmm5     # 0xe874
leaq 0x3cf1(%rip), %rbx      # 0x10911
leaq 0x3cdf(%rip), %rax      # 0x10906
cmovaq %rax, %rbx
cmpl $0x0, 0x8682(%rip)      # 0x152b4
je 0xcc51
movl 0x8ace(%rip), %ecx      # 0x15708
leaq 0x3cb7(%rip), %rdi      # 0x108f8
movq %rbx, %rsi
movl %r12d, %edx
movq %r13, %r8
xorl %eax, %eax
callq 0x2030
movq %rbx, %rdi
jmp 0xcca8
ucomisd 0x1aea(%rip), %xmm2     # 0xe748
jbe 0xccb4
ucomisd %xmm1, %xmm4
jbe 0xccb4
ucomisd %xmm1, %xmm6
jbe 0xccb4
testl %r15d, %r15d
jne 0xccb4
testl %ebp, %ebp
jle 0xccb4
ucomiss 0x1bf4(%rip), %xmm3     # 0xe870
jbe 0xccb4
cmpl $0x0, 0x862f(%rip)      # 0x152b4
je 0xcca1
movl 0x8a7b(%rip), %edx      # 0x15708
leaq 0x3c91(%rip), %rdi      # 0x10925
movl %r12d, %esi
movq %r13, %rcx
xorl %eax, %eax
callq 0x2030
leaq 0x3c94(%rip), %rdi      # 0x1093c
movq %r13, %rsi
callq 0x9478
movb $0x1, %bl
jmp 0xcd09
leaq 0x3c33(%rip), %rdi      # 0x108ee
movq %r13, %rsi
xorl %edx, %edx
callq 0x91ff
leaq 0x3c12(%rip), %rdi      # 0x108de
movq %r13, %rsi
xorl %edx, %edx
callq 0x91ff
leaq 0x3c29(%rip), %rdi      # 0x10906
movq %r13, %rsi
xorl %edx, %edx
callq 0x91ff
leaq 0x3c23(%rip), %rdi      # 0x10911
movq %r13, %rsi
xorl %edx, %edx
callq 0x91ff
leaq 0x3c3d(%rip), %rdi      # 0x1093c
movq %r13, %rsi
xorl %edx, %edx
callq 0x91ff
testb %bl, %bl
je 0xce06
cmpl $0x0, 0x859c(%rip)      # 0x152b4
je 0xce06
movl 0x89e4(%rip), %edx      # 0x15708
movsd 0x100(%rsp), %xmm1
movsd 0x108(%rsp), %xmm2
movsd 0xf0(%rsp), %xmm3
movsd 0xf8(%rsp), %xmm4
movsd 0xd0(%rsp), %xmm6
movsd 0xd8(%rsp), %xmm7
movups 0xc0(%rsp), %xmm0
movups 0x120(%rsp), %xmm5
movups 0x130(%rsp), %xmm8
movsd 0xa0(%rsp), %xmm9
movsd 0xa8(%rsp), %xmm10
movsd 0x88(%rsp), %xmm11
movsd 0x90(%rsp), %xmm12
movsd 0x98(%rsp), %xmm13
movsd %xmm13, 0x58(%rsp)
movsd %xmm12, 0x50(%rsp)
movsd %xmm10, 0x48(%rsp)
movsd %xmm9, 0x40(%rsp)
movsd %xmm11, 0x38(%rsp)
movups %xmm5, 0x28(%rsp)
movups %xmm8, 0x18(%rsp)
movsd 0x70(%rsp), %xmm5
movsd %xmm5, 0x10(%rsp)
movups %xmm0, (%rsp)
leaq 0x3b5e(%rip), %rdi      # 0x10948
movl %r12d, %esi
movq %r13, %rcx
movsd 0x78(%rsp), %xmm0
movsd 0x80(%rsp), %xmm5
movb $0x8, %al
callq 0x2030
movl 0x846c(%rip), %edi      # 0x15278
callq 0x2380
leaq 0x272a(%rip), %r15      # 0xf542
leaq 0x1b6f(%rip), %rbp      # 0xe98e
jmp 0xc8b7