Esempio n. 1
0
        private decimal _lastCoin  = -1; // non si puo' usare decimal.MinValue


        public override bool OnHeartBeat()
        {
            const decimal gain = 0M; // sellat, buyat

            // devo vendere o devo comprare?
            var action = this.SuggestedAction;

            /*
             * // mi salvo il massimo value
             * if (Market.TotValue > this.MaxValue)
             * {
             *  this.MaxValue = Market.TotValue;
             * }
             *
             * if (Market.TotCoins > this.MaxCoins)
             * {
             *  this.MaxCoins = Market.TotCoins;
             * }
             */
            /**************************************************************
            *  CHECK CONFERMA (DOPPIO COMANDO)
            **************************************************************/
            // questa parte di codice esegue l'operazione se c'è una conferma
            if (action != TradeAction.StrongBuy && action != TradeAction.StrongSell)
            {
                if (action != _lastTradeActionSuggested)
                {
                    //CUtility.Log("refused: wait confirm with 2nd command");
                    LogTrade.Motivation       = "refused: wait confirm with 2nd command";
                    _lastTradeActionSuggested = action;
                    action = TradeAction.Unknown;
                }
            }
            else
            {
                LogTrade.Motivation       = ("refused: single command");
                _lastTradeActionSuggested = TradeAction.Unknown;
            }

            LogTrade.Action = action;

            /**************************************************************
            *  BUY
            **************************************************************/
            // compro o vendo?
            string orderId = "";

            if (action == TechnicalAnalysis.TradeAction.Buy || action == TechnicalAnalysis.TradeAction.StrongBuy)
            {
                /*
                 * per comprare devo usare il valore ask
                 */
                var buyvalue = Market.Buy;

                var money = (Market.TotMoney - SavedMoney) * PercCapital; // impegno solo una percentuale del capitale

                SavedMoney += (Market.TotMoney - SavedMoney) * (1 - PercCapital);

                if (money == 0)
                {
                    LogTrade.Motivation = ("refused: no money");
                    goto exitif;
                }

                if (PercCapital < 1.0M)
                {
                    // se uso una percentuale, allora devo evitare che ripetuti comandi
                    // uguali, mi facciamo dissipare il risparmio accantonato
                    if (_lastTradeActionExecuted == CUtility.OrderType.Buy)
                    {
                        goto exitif;
                    }
                }

                if (Conservative)
                {
                    // impegno sempre non più di una certa cifra
                    // sia per vendere che per comprare
                    if (money > MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest)
                    {
                        SavedMoney += (money - MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest);
                        money       = MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest;
                    }
                }

                var amount = money / buyvalue; // coins
                if (amount > MinBitCoin)
                {
                    // compro solo se i coin risultanti sono più dei precedenti
                    var coins = (amount) * (1 - Market.Fee);

                    /* onlyIfGain attiva o disattiva il blocco delle vendite se i soldi ricavati sono inferiori rispetto alla vendita precedente */
                    var onlyIfGain = MainConfiguration.Configuration.GreedyWithCoins; // --> disabilità il blocco
                    var greedyPerc = MainConfiguration.Configuration.GreedyWithCoinsGain;


                    if (MainConfiguration.Configuration.GreedyWithLongTermTrend)
                    {
                        // diventa avido se il trend a lungo termine è in discesa
                        onlyIfGain = this.CurrentLongTermTrend == Trend.Fall;
                        var longTermCoefficienteAngolare = this.Market.CandleMaker.LongTermTrendSpeed();

                        greedyPerc = GreedyNess(longTermCoefficienteAngolare);
                    }

                    if (!onlyIfGain || action == TechnicalAnalysis.TradeAction.StrongBuy || coins > _lastCoin * greedyPerc)
                    {
                        // evito che il trading mi mandi sotto del numero iniziale di coins

                        if (MainConfiguration.Configuration.UndervalueAllowed || (coins + SavedCoins) > MainConfiguration.Configuration.StartWalletCoins * (1 - MainConfiguration.Configuration.UndervalueTolerance))
                        {
                            _lastCoin = coins;

                            var result = Market.DoOrder(CUtility.OrderType.Buy, buyvalue, amount, ref orderId, true);
                            if (result.Length > 0)
                            {
                                LogTrade.Motivation      = "BUY";
                                _lastTradeActionExecuted = CUtility.OrderType.Buy;
                                TotBid++;

                                // avvisa l'analitic che l'ultima label inserita con AnalyticsTools.Call(xxxx) è completata
                                AnalyticsTools.Confirm();

                                SellAt = (1 + gain) * (buyvalue * (1 + (2 * Market.Fee)));
                                BuyAt  = 0;
                            }
                            else
                            {
                                // c'è stato un fallimento
                                LogTrade.Motivation = "BUY FAILED";
                            }
                        }
                        else
                        {
                            LogTrade.Motivation = ("under my initial value");
                        }
                    }
                    else
                    {
                        LogTrade.Motivation = ("greedy of coins: waiting for better performance " + Math.Round(_lastCoin * greedyPerc, 4).ToString(CultureInfo.InvariantCulture));
                    }
                }
                // _stoploss.Reset();
            }


            /**************************************************************
            *  SELL
            **************************************************************/
            if (action == TechnicalAnalysis.TradeAction.Sell || action == TechnicalAnalysis.TradeAction.StrongSell)
            {
                var sellvalue = Market.Sell;

                var amount = (Market.TotCoins - SavedCoins) * PercCapital;// - SavedCoins;

                SavedCoins += (Market.TotCoins - SavedCoins) * (1 - PercCapital);

                if (amount == 0)
                {
                    LogTrade.Motivation = ("refused: no coins");
                    goto exitif;
                }

                if (PercCapital < 1.0M)
                {
                    // se uso una percentuale, allora devo evitare che ripetuti comandi
                    // uguali, mi facciamo dissipare il risparmio accantonato
                    if (_lastTradeActionExecuted == CUtility.OrderType.Sell)
                    {
                        goto exitif;
                    }
                }


                if (Conservative)
                {
                    // impegno sempre non più di una certa cifra
                    // sia per vendere che per comprare
                    var maxmoney = MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest;
                    if (amount > maxmoney / sellvalue)
                    {
                        SavedCoins += (amount - maxmoney / sellvalue);
                        if (SavedCoins > 100)
                        {
                            CUtility.Log("error");
                        }
                        amount = maxmoney / sellvalue;
                    }
                }

                if (amount > MinBitCoin)
                {
                    var money = (amount * sellvalue) * (1 - Market.Fee);

                    /* onlyIfGain attiva o disattiva il blocco delle vendite se i soldi ricavati sono inferiori rispetto alla vendita precedente */
                    var onlyIfGain = MainConfiguration.Configuration.GreedyWithMoney; //  --> disabilita il blocco
                    var greedyPerc = MainConfiguration.Configuration.GreedyWithMoneyGain;

                    if (MainConfiguration.Configuration.GreedyWithLongTermTrend)
                    {
                        // diventa avido se il trend a lungo termine è in salita
                        onlyIfGain = this.CurrentLongTermTrend == Trend.Raise;
                        var longTermCoefficienteAngolare = this.Market.CandleMaker.LongTermTrendSpeed();

                        greedyPerc = GreedyNess(longTermCoefficienteAngolare);
                    }

                    if (!onlyIfGain || action == TechnicalAnalysis.TradeAction.StrongSell || money > _lastMoney * greedyPerc)
                    {
                        // evito che il trading mi butti sotto del numero iniziale di soldi
                        if (MainConfiguration.Configuration.UndervalueAllowed || (money + SavedMoney) > MainConfiguration.Configuration.StartWalletMoney * (1 - MainConfiguration.Configuration.UndervalueTolerance))
                        {
                            // vendo solo se la vendita produce piu' soldi di prima
                            _lastMoney = money;

                            var result = Market.DoOrder(CUtility.OrderType.Sell, sellvalue, amount, ref orderId, true);
                            if (result.Length > 0)
                            {
                                TotAsk++;

                                BuyAt  = (1 - gain) * (sellvalue * (1 - (2 * Market.Fee)));
                                SellAt = 0;

                                // avvisa l'analitic che l'ultima label inserita con AnalyticsTools.Call(xxxx) è completata
                                AnalyticsTools.Confirm();

                                _lastTradeActionExecuted = CUtility.OrderType.Sell;
                                LogTrade.Motivation      = "SELL";
                            }
                            else
                            {
                                LogTrade.Motivation = "SELL FAILED";
                            }

                            /*
                             * if (action == TechnicalAnalysis.TradeAction.SellStopLoss)
                             * {
                             *  TotStopLoss++;
                             * }
                             */
                        }
                        else
                        {
                            LogTrade.Motivation = ("under my initial value");
                        }
                    }
                    else
                    {
                        LogTrade.Motivation = ("greedy of money: waiting for better performance " + Math.Round(_lastMoney * greedyPerc, 4).ToString(CultureInfo.InvariantCulture));
                    }
                }
            }


exitif:

            /**************************************************************
            *  LOG
            **************************************************************/
            Log(string.Format("B:{0} A:{1} SL:{2} Max$:{3} MaxC:{4} MaxV:{5}", TotBid, TotAsk, 0, Math.Round(Market.MaxMoney, 4).ToString(CultureInfo.InvariantCulture), Math.Round(Market.MaxCoins, 4).ToString(CultureInfo.InvariantCulture), Math.Round(Market.MaxValue, 4).ToString(CultureInfo.InvariantCulture)));
            LogTrade.BuyAt  = BuyAt;
            LogTrade.SellAt = SellAt;

            return(true);
        }
        public override TradeAction SuggestedAction(CMarket market)
        {
            /********************************************************************************
            * CONSERVATIVE DYNAMIC
            *
            ********************************************************************************/
            if (MainConfiguration.Configuration.ManagerIsConservative &&
                MainConfiguration.Configuration.ManagerConservativeTimesPerValue > 0)
            {
                MainConfiguration.Configuration.ManagerConservativeMaxMoneyToInvest = ((market.Buy + market.Sell) / 2) * MainConfiguration.Configuration.ManagerConservativeTimesPerValue;
            }

            /********************************************************************************
            * EVALUATION
            * vengono esaminati i comandi ed eseguiti uno ad uno
            ********************************************************************************/
            var result      = TradeAction.Unknown;
            var commandname = "";

            foreach (var commandName in MainConfiguration.Configuration.Commands)
            {
                commandname = commandName;
                var command = GetCommand(commandname);
                if (command == null)
                {
                    // in realtà dovrebbe incazzarsi di brutto
                    continue;
                }
                result = command(market, result);

                // se il comando è Strong o hold allora termina subito
                if (result == TradeAction.Hold)
                {
                    goto exitloop;
                }
                if (result == TradeAction.StrongBuy)
                {
                    goto exitloop;
                }
                if (result == TradeAction.StrongSell)
                {
                    goto exitloop;
                }
                //if (result == TradeAction.SellStopLoss) goto exitloop;
            }
exitloop:

            /********************************************************************************
            * LOGGING
            ********************************************************************************/
            var e = Evaluations.EvaluationManager.Instance;
            var prediction = PredictionType.Unknown;

            switch (result)
            {
            //case TradeAction.SellStopLoss:
            //    commandname += "--";
            //    prediction = PredictionType.LessThan;
            //    break;
            case TradeAction.StrongBuy:
                commandname += "++ ";
                prediction   = PredictionType.GreatherThan;
                break;

            case TradeAction.StrongSell:
                commandname += "-- ";
                prediction   = PredictionType.LessThan;
                break;

            case TradeAction.Hold:
                commandname += "=  ";
                prediction   = PredictionType.Equal;
                break;

            case TradeAction.Buy:
                commandname += "+  ";
                prediction   = PredictionType.GreatherThan;
                break;

            case TradeAction.Sell:
                commandname += "-  ";
                prediction   = PredictionType.LessThan;
                break;
            }

            AnalyticsTools.Call(commandname);

            var now       = market.CandleMaker.CurrentCandleDate;
            var candleLen = MainConfiguration.Configuration.CandleWidthInSeconds / 60;

            e.Add(commandname, new Prediction()
            {
                Date = now, Type = prediction, Value = this.CoinValue
            }, candleLen);

            if (result != TradeAction.Hold)
            {
                LogTrade.Note += " " + commandname;
            }

            return(result);
        }
        public override void Run()
        {
            var tests = new List <TestUnit>();
            var testResultFileName = @"data\output\results" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".csv";

            //TODO: caricare da configurazioni
            var testLoad = GetTestData();

            //List<TestParam> testLoad = null;

            if (testLoad == null || testLoad.Count == 0)
            {
                testLoad = new List <TestParam>()
                {
                    new TestParam(0, 0, 0, 0)
                };
            }

            var e = Evaluations.EvaluationManager.Instance;

            foreach (var testParam in testLoad)
            {
                e.Clear();

                /********************************************************************
                 * CONFIGURAZIONE
                 *******************************************************************/
                //MainConfiguration.Configuration = new Configuration(); //configuration;
                // MainConfiguration.Configuration = Configuration.BuildFromFile("global.json", "personal.json");
                MainConfiguration.Configuration = Configuration.BuildFromDirectory(@"data/configuration");
                MainConfiguration.Configuration.Init();
                Configuration.SaveToFile(MainConfiguration.Configuration, @"data/configuration/serialized.result.json");

                // chiama la configurazione
                Customize(testParam);

                /********************************************************************
                 * MANAGER
                 *******************************************************************/
                var manager = Manager.Builder.Create(MainConfiguration.Configuration.ManagerClass);

                if (manager == null)
                {
                    throw new Exception("manager not configured");
                }


                manager.Start();

                if (MainConfiguration.Configuration.RealTimeHeartBeat && testLoad.Count == 1)
                {
                    break;
                }

                System.Console.WriteLine(manager.Market.UniqueName);

                // salvo il risultato
                var test = new TestUnit()
                {
                    Coins     = manager.Market.TotCoins,
                    Money     = manager.Market.TotMoney,
                    Coinvalue = manager.Market.Buy,
                    Value     = manager.Market.TotValue,
                    Average   = manager.Market.Average,
                    MaxCoins  = manager.Market.MaxCoins,
                    MaxMoney  = manager.Market.MaxMoney,
                    MaxValue  = manager.Market.MaxValue,
                    Bids      = manager.Market.TotBids,
                    Ask       = manager.Market.TotAsks,
                    Gain      = manager.Statistics.Gain,
                    i         = testParam.I,
                    j         = testParam.J,
                    w         = testParam.W,
                    k         = testParam.K
                };


                /********************************************************************
                 * VISUALIZZAZIONE
                 *******************************************************************/
                // stampa il risultato
                test.Print();
                if (test.Average > MainConfiguration.Configuration.StartWalletMoney)
                // deve esserci stato almeno un trade
                {
                    if (test.Value > MainConfiguration.Configuration.StartWalletMoney)
                    // devo aver guadagnato piu' di quanto ho investito
                    {
                        // salva il risultato se ci sono stati risultati incoraggianti
                        CUtility.Log("*** GOOD");
                        tests.Add(test);

                        /*
                         * // scrive il risultato su csv
                         * using (var log = new StreamWriter(testResultFileName, true))
                         * {
                         *  test.Print(log);
                         *  log.Flush();
                         *  log.Close();
                         * }
                         * */
                        // scrive il risultato con codice
                        using (var log = new StreamWriter(testResultFileName + ".txt", true))
                        {
                            test.PrintCode(log);
                            log.Flush();
                            log.Close();
                        }

                        // salvo la migliore configurazione
                        var best = tests.OrderByDescending(o => o.Coins * o.Coinvalue + o.Money).FirstOrDefault();
                        if (best != null)
                        {
                            Configuration.SaveToFile(MainConfiguration.Configuration,
                                                     @"data/configuration/best.result.json");
                        }
                        var bestAvg = tests.OrderByDescending(o => o.Average).FirstOrDefault();
                        if (bestAvg != null)
                        {
                            Configuration.SaveToFile(MainConfiguration.Configuration,
                                                     @"data/configuration/bestavg.result.json");
                        }
                    }
                }

                AnalyticsTools.Print();
                e.Finalize();
            }

            /********************************************************************
             * RISULTATI
             *******************************************************************/
            if (MainConfiguration.Configuration.RealTimeHeartBeat && testLoad.Count == 1)
            {
            }
            else
            {
                // mostro la performance migliore
                CUtility.Log("*** BEST VALUE");
                var firstOrDefault = tests.OrderByDescending(o => o.Coins * o.Coinvalue + o.Money).FirstOrDefault();
                if (firstOrDefault != null)
                {
                    firstOrDefault.Print();
                }

                CUtility.Log("*** BEST AVERAGE");
                var orDefault = tests.OrderByDescending(o => o.Average).FirstOrDefault();
                if (orDefault != null)
                {
                    orDefault.Print();
                }
            }
        }