Bitcoin Forum
May 05, 2024, 01:59:54 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 »  All
  Print  
Author Topic: Trading Bot en C# avec API Bittrex : "Par où commencer??" [Débutant] [Résolu]  (Read 351 times)
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 05, 2018, 05:53:58 PM
Last edit: July 08, 2018, 06:40:47 PM by PtiPoulet
Merited by Xavier59 (2)
 #1

Salut salut,

Nouveau en trading et nouveau aussi en programmation, j voudrais utiliser la nouvelle API Bittrex en c# pour me bidouiller un bot....
En mode console pas de soucis ça m'affiche bien des trucs, mais j voudrais intégrer ces trucs (:p) dans une windows form.
Un pti coup de pouce SVP pour me faire avancer?
j'me doute que cela se passe dans "static void Main(string[] args)" mais comment initialiser l'API à partir d'une windows form et y intégrer les données vers ce windows form?
 Roll Eyes
Merci par avance.

PtiPoulet
Smiley

All we are is dust in the wind !
1714917594
Hero Member
*
Offline Offline

Posts: 1714917594

View Profile Personal Message (Offline)

Ignore
1714917594
Reply with quote  #2

1714917594
Report to moderator
1714917594
Hero Member
*
Offline Offline

Posts: 1714917594

View Profile Personal Message (Offline)

Ignore
1714917594
Reply with quote  #2

1714917594
Report to moderator
TalkImg was created especially for hosting images on bitcointalk.org: try it next time you want to post an image
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 06, 2018, 12:01:25 PM
Last edit: July 08, 2018, 09:14:59 PM by PtiPoulet
 #2

Ne cherchez plus j'ai trouvé... Grin Grin

private void LoadAPISettings()
        {
            textBox1.Text = Properties.Settings.Default.APIKey;
            textBox2.Text = Properties.Settings.Default.APISecret;
        }

        public void InitializeAPI()
        {
            BittrexWebsocket.BittrexCallback CreateCallback(string name)
            {
                            
                return (info) =>
                {
                    string BittrexInfo = BittrexWebsocket.Decode(info);
                    
                    RootObject root = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(BittrexInfo);

                    dataGridView1.Invoke(new MethodInvoker(delegate
                    {
                        dataGridView1.Rows.Add(root.M,root.N,root.Z,root.S,root.f);
                    }));
                    
                };
            }

            
            Task task = Task.Run(
         async () =>
         {
             string apiKey = Properties.Settings.Default.APIKey;
             string apiSecret = Properties.Settings.Default.APISecret;
             string baseUrl = "https://beta.bittrex.com/signalr";


C'est moche mais ça marche...
Smiley

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 08, 2018, 06:38:32 PM
Last edit: July 08, 2018, 10:39:03 PM by PtiPoulet
 #3

/*Petite rectif pour les noobs comme moi qui se galèrent et qui voudraient utiliser l'"API REST"(="tu envois des requêtes au serveur et il te répond quand il peut") plutôt que le "WebSocketAPI"(="tu souscris au serveur et t'attend qui t'envois des infos en fonction de la surcharge du serveur").... : donc Premièrement créer une WindowsForm avec 1 bouton, 1 comboBox et 1 datagridview (ajoutez trois columns à cette datagridview via "click droit" sur le datagridview (click droit : "Modifier les colonnes").....(aussi n'oubliez pas d'intégrer la référence NewtonSoft.JSON au projet(click droit ds l'explorateur de solution sur la solution ...gérer les packages nugget's......puis parcourir.....Rechercher le package : "NewtonSoft.JSON" puis l'installer....Smiley voici le code pour la Form1.cs: */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;
using System.Net;
using System.Net.Http;


namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            GetMarket();
        }
        private void GetMarket()
        {
            string url = "     https://bittrex.com/api/v1.1/public/getmarkets";
            string json = new WebClient().DownloadString(url);
            var dataDeserialized = JsonConvert.DeserializeObject<Market.RootObject>(json);

            for (int n = 0; n <= dataDeserialized.result.Count - 1; n++)
            {
                comboBox1.Items.Add(dataDeserialized.result[n].BaseCurrency
                    + "-" + dataDeserialized.result[n].MarketCurrency);
            }
            comboBox1.SelectedIndex = 0;
        }
    

        private void button1_Click(object sender, EventArgs e)
        {
            string url = "https://bittrex.com/api/v1.1/public/getticker?market=" + comboBox1.SelectedItem.ToString();
            string json = new WebClient().DownloadString(url);
            var dataDeserialized = JsonConvert.DeserializeObject<Ticker.RootObject>(json);
            dataGridView1.Rows.Add(dataDeserialized.result.Bid, dataDeserialized.result.Ask,dataDeserialized.result.Last);
              
        }
    }
}


/*et Deuxièmement Smiley tu crées une class (click droit dans l'explorateur de solution sur "le projet en question(WindowsFormApp1)" .....puis "ajouter" ......"class"....>>>la renomer en "Bittrex.cs"....voici le code à coller : */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WindowsFormsApp1
{
    public class Market
    {
        public class Result
        {
            public string MarketCurrency { get; set; }
            public string BaseCurrency { get; set; }
            public string MarketCurrencyLong { get; set; }
            public string BaseCurrencyLong { get; set; }
            public double MinTradeSize { get; set; }
            public string MarketName { get; set; }
            public bool IsActive { get; set; }
            public DateTime Created { get; set; }
            public string Notice { get; set; }
            public bool? IsSponsored { get; set; }
            public string LogoUrl { get; set; }
        }

        public class RootObject
        {
            public bool success { get; set; }
            public string message { get; set; }
            public List<Result> result { get; set; }
        }
    }
    public class Ticker
    {
        public class Result
        {
            public double Bid { get; set; }
            public double Ask { get; set; }
            public double Last { get; set; }
        }

        public class RootObject
        {
            public bool success { get; set; }
            public string message { get; set; }
            public Result result { get; set; }
        }
    }
      
}

//Fin

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 09, 2018, 03:56:37 PM
Last edit: July 09, 2018, 08:28:33 PM by PtiPoulet
 #4

J'me disais que j'allais mettre une alarme sur MACD et/ou RSi pour lancer un achat...mais ça va pas être possible si l'appli du bot ne tourne pas H24 sur le PC sur lequel l'appli est lancée....il aura pas les données antérieur à 24H. Sad

Alors j pense que j vais me servir de mes MiningRigs pour enregistrer les requêtes API dans une base de données (SQL?) et puis lorsque j'ouvre l'appli de mon Bot sur mon pc de "tous les jours",l'appli récupère les info enregistrées par le/les miningrigs sur la période voulu pour faire mon calcul MACD/RSI...
c'est pas con??
Sous quelle forme c'est mieux de stocker toutes ces données? XML, Txt, MySQL, c'est tout pareil, autre???

Merci par avance.

PtiPoulet

P.S: question : quelle fréquence pour les requêtes API REST de Bittrex via un "Timer_tick"? là j'suis à 4 requêtes différentes toutes les 5 secondes ! c'est trop?pas assez, sans avis Smiley?




All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 09, 2018, 08:34:56 PM
Last edit: July 09, 2018, 09:00:32 PM by PtiPoulet
 #5

okay..... pas de ban du serveur à 4 requêtes toutes les 5 secondes depuis le dernier thread......poussons le plus bas.....4 requêtes toutes les 500ms : let' see .... Shocked
Mémoire du procesus à 37 Mo (on sait pas ce que ça veut dire ) Waouuuuuu ! ?
 Musique bien : https://www.youtube.com/watch?v=AOBpBOZD8gg

Smiley

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 10, 2018, 08:19:44 PM
Last edit: July 10, 2018, 10:29:55 PM by PtiPoulet
 #6

J'ai une idée pour l'algo d'achat lol....en résumé j achètes les plus gros supports et j revends sur les plus grosses resistances!!! :p

on "trie" les 100 dernières valeurs de l'"order book" par volume les plus élevés dans une datatable (l index 0 aura donc le volume d'achat le plus élevé) , on choisi le "risque management"genre :

    -risque [r] = 1 : on cherche depuis l'index avec n=0(via numericupdown selecteur) (visant la datatable)avec une boucle "for (int i=0....) jusqu'à n = r-1 alors on boucle on cherche le prix du volume correspondant jusqu'à ce que l'index le plus élevée soit i=r-1 de l'"order book sorted by volume" et la mise sera(1/[r]+(i)), genre on investit notre capital à hauteur de 1/1 sur l'index i = 0 de la datatable de l'"order bouk sorted by volume" Résultat cas [1]=>investissement 100% sur la première mise à l'index 0.

    -risque [r] = 2 : on cherche depuis l'index avec n=1(via numericupdown selecteur) (de la datatable)avec une boucle "for (int i=0....) jusqu'à n = r-1 alors on boucle on cherche le prix du volume correspondant jusqu'à ce que l'index le plus élevée soit i=r-1 de l'"order book sorted by volume" et la mise sera(1/[r]+(i)), genre on investit notre capital à hauteur de 1*n(1/[r]+(i)) sur l'index i[0] et 2*n(1/[r]+(i)) sur l'index i[1] Résultat cas [2]==>investissement 1/3 sur l'index 1 et 2/3 sur l'index 0.

    -risque [r] = 3 : on cherche depuis l'index avec n=2(via numericupdown selecteur) (de la datatable)avec une boucle "for (int i=0....) jusqu'à n = r-1 alors on boucle on cherche le prix du volume correspondant jusqu'à ce que l'index le plus élevée soit i=r-1 de l'"order book sorted by volume" et la mise sera(1/[r]+(i)), genre on investit notre capital à hauteur de 1*n(1/[r]+(i)) sur l'index i[0], 2*n*(1/[r]+(i)) sur l'index i[1] et 3*n*(1/[r]+(i)) sur l'indexi[1] ......................Résultat cas [3]==>investissement 1/6 sur l'index 2, 2/6 sur l'index 1 et 3/6 sur l'index 0


...et ainsi de suite!!!.....bref z'avez compris le principe!!........elle est ou l'erreur SVP dans la formule?Huh Shocked Shocked Cry j'ai jamais été bon en maths et j'le regrette Sad

J'offre toute ma considération à celui qui me trouvera la formule unique et résultante des résultats précédemment attendus! :p

Merci par avance

PtiPoulet ! Smiley

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 11, 2018, 12:00:25 PM
 #7

ah! c'est bon j 'ai trouvé  Tongue
        double A_Buy = 1;
        double B_Buy = 0;
        double Ratio_Buy = 0;

        private void button3_Click(object sender, EventArgs e)
        {
            double balance = Convert.ToDouble(label6.Text);
            double pending_Buy = 0;
            double pending_bill = 0;
            double Buy_Order_Id = Convert.ToDouble(numericUpDown1.Value.ToString());
            for (double Id_B = Buy_Order_Id; Id_B >= 0; Id_B--)
            {
                B_Buy = B_Buy + dataGridView6.Rows[Convert.ToInt32(Id_B)+1].Index;
            }
            for (double Id_B = Buy_Order_Id; Id_B >= 0 ; Id_B--)
            {               
                Ratio_Buy = A_Buy / B_Buy;
                pending_Buy = Ratio_Buy * balance;
                pending_bill = pending_bill + pending_Buy;
                dataGridView8.Rows.Add(
               (Ratio_Buy)*(balance/Convert.ToDouble(dataGridView6.Rows[Convert.ToInt32(Id_B)].Cells[1].Value)),
                dataGridView6.Rows[Convert.ToInt32(Id_B)].Cells[1].Value.ToString(),
                "OPEN_ORDER");
                A_Buy = A_Buy + 1;
            }
            balance = balance - pending_bill;
            label6.Text = balance.ToString();
            A_Buy = 1;
            B_Buy = 0;
            dataGridView8.Sort(dataGridView8.Columns[0], ListSortDirection.Descending);
        }
 Roll Eyes

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 11, 2018, 10:01:59 PM
Last edit: July 11, 2018, 10:47:11 PM by PtiPoulet
 #8

Yop ! Y a quoi de mieux que MSChart en version gratos pour mettre en forme les graphes sur une appli C# SVP ? on va pas s'attarder sur les details mais ce serait plus léger sans backgroundworker tout ça....Sad

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 12, 2018, 07:09:02 PM
 #9

ça donne vraiment mal au crâne ce MSChart ! Sad (j'ai l'impression de me transformer en spéléologue professionnel quant il s'agit d'aller changer la couleur d'un truc dans ce chart.... Shocked)

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 13, 2018, 03:06:15 PM
 #10

Bittrex : "We are currently restricting orders to 500 open orders and 200,000 orders a day."

Question : Je lance 500 "Open order" en achat à midi, puis à 18H00 je les "Cancel"....j'ai encore droit à 500 jusqu'à minuit Roll Eyes? où c'est grillé??? Cry

Merci d'avance

PtiPoulet

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 13, 2018, 04:17:29 PM
Last edit: July 13, 2018, 04:30:41 PM by PtiPoulet
 #11

J'ai rajouté une condition sur achat : j'achète que les supports(rafraichissement des supports d'achats toutes les 5 minutes et annulation des anciens "OpenOrder" "non-filled" au bout de 5 min toujours => TimeLapse à définir)(cf.plus gros volumes voir code précédent avec calcul du ratio sur la quantité à acheter en fonction du risquemanagement) et si et seulement si ils(ces ordres triés par volumes descndants) ont une rentabilité de plus * de 1% (différences des "Rate" entres les support d'achats/vente par index "tout simplement"(<< à cogiter) sur chacun des 100 derniers Index des carnets d'ordre achat/vente respectifs)(pour test....car possible que j 'm'oriente vers du 3%)....il a mis un peu moins de 5 heures à acheter ....Alleluia !!!!  Grin

private void Profitability()
        {
            dataGridView12.Rows.Clear();
            double Profit_Mini = 1.00;
            for (int Id = 0; Id <= dataGridView6.Rows.Count-1; Id++)
            {
                double Buy_Rate = Convert.ToDouble(dataGridView6.Rows[Id].Cells[1].Value);
                double Sell_Rate = Convert.ToDouble(dataGridView7.Rows[Id].Cells[0].Value);
                if ((Sell_Rate - Buy_Rate) / (Buy_Rate / 100) >= Profit_Mini)
                {
                    dataGridView12.Rows.Add(
                        Id,
                        dataGridView6.Rows[Id].Cells[1].Value,
                        (Sell_Rate - Buy_Rate) / (Buy_Rate / 100),
                        dataGridView7.Rows[Id].Cells[0].Value);
                }
            }
            dataGridView12.Sort(dataGridView12.Columns[2], ListSortDirection.Descending);
            dataGridView12.ClearSelection();
            dataGridView12.Rows[0].Selected = true;

            button3.Enabled = true;
        }
        private void Rate_To_Buy()
        {
            dataGridView8.Rows.Clear();
            for (int Id = 0; Id <= dataGridView12.Rows.Count - 2; Id++)
            {
                dataGridView8.Rows.Add(
                    dataGridView12.Rows[Id].Cells[0].Value,
                    dataGridView12.Rows[Id].Cells[1].Value);
            }
            dataGridView8.Sort(dataGridView8.Columns[0], ListSortDirection.Ascending);
            dataGridView8.ClearSelection();
            dataGridView8.Rows[0].Selected = true;
        }


Maintenant, faut qu'il vende et continue à acheter LOL! Smiley

Smiley

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 14, 2018, 06:04:42 PM
 #12

J'ai un bug c'est cheloux! Sad J'manque de RAM dans mon cerveau pour comprendre.... :/

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 15, 2018, 10:25:56 AM
Last edit: July 15, 2018, 02:07:37 PM by PtiPoulet
 #13

Voili voilou la Bête : https://github.com/PtiPoulet/PtiPoulet

 Smiley (pas d'entourloupe ou de truc bizarre genre méchant virus caché....100% PtiPoulet garanti Juillet 2018)
(Pas de Setup, simplement un .exe (sous Windows10) .......en mode simulation uniquement avec la paire USDT-BTC avec mise de départ 500 USDT et paramètré avec profit mini >= 1% et il annule les buy orders et sell orders non-filled toutes les 5 * 5000ms et les relance tout seul en fonction du nouveau carnet d'ordre rafraîchit au bout de ce timelapse> en résumé il émet un son (le célèbre "blaouuumm" de windows10)quand il achète ou revend et les enregistredans les deux tableaux du bas , y faut juste regarder la balance pour voir si ça monte où si j'me suis complètement planté lol Grin Roll Eyes)

Let's see... Cry

P.S: y a moyen?de récupérer les infos de "Cointelegraphe" ou autre via une API puis dé-concaténer les phrases des gros titres avec un split.string et récupérer les mots et les comparer dans une BDD pré-établie, genre deux listbox : une bullish et une bearish.....si les mots sontbearish (genre bitcoin + crash) alors le bot diminue sont risque management et vis et versa... Shocked !! Roll Eyes Huh ;)j'suis sûr que oui ! Grin Wink
...ça devrait pouvoir se faire, même pour un débutant ça ! Smiley.... Grin...dans le prochain épisode ! Smiley

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 16, 2018, 06:59:11 PM
Last edit: July 16, 2018, 07:58:14 PM by PtiPoulet
 #14

Revue du code complet!!!
....après quelques figeages de screen et quelques B.O.S.D (genre OS non reconnu après restart! Fichtre !!!! I'm Damned !!!! Grin).... on revoit l'affaire >Shocked
  On passe toutes les requêtes bittrex avec tu "Try..Catch", on mets tout dans des datatables sur du background workers "RunAsynchWork", et on migre les données des datatables vers des datagridviews sur "backgroundworker_RunWorker_Completed"
...ba ça va tout de suite mieux  ! Smiley lol
C'est là : https://github.com/PtiPoulet/PtiPoulet
Merci Bill Gates pour ces "BackGroundWorkers"magiques !!! Smiley
P.S.: Faut Zappuyer sur le bouton "Test" en haut à droite..j ai oublié de mettre la fonction sur la "Form Load"! Smiley

All we are is dust in the wind !
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 17, 2018, 04:52:18 PM
Last edit: July 17, 2018, 05:06:11 PM by PtiPoulet
 #15

tordu le cou au MSChart...+ d'autres trucs mineurs :
téléchargeable ici :
https://github.com/PtiPoulet/PtiPoulet
Fichier .exe dans dossier "Zip" nommé "ByZeDeep.zip" (j'ai pas déposé le nom mais il se pourrait que j'le fasse  Grin)
Smiley

PtiPoulet

All we are is dust in the wind !
baba0000000000
Sr. Member
****
Offline Offline

Activity: 812
Merit: 388


View Profile
July 17, 2018, 05:00:30 PM
 #16

Franchement j'aimerai bien t'aider mais j'y capte rien à ce que tu racontes. Ca me donne un mal de crane.
J'espère qu'une personne pourra t'aider ici, tu n'aurais pas plus de réponse sur un forum informatique ou programmation.
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 17, 2018, 05:01:29 PM
Last edit: July 17, 2018, 05:54:53 PM by PtiPoulet
 #17

Merci j m'en sors plutôt pas mal....enfin j'arrive à ce que je veux ....(heureusement qu'on a "StackOverFlow")... Smiley
P.S: désolé pour le mal au crâne  Tongue

All we are is dust in the wind !
baba0000000000
Sr. Member
****
Offline Offline

Activity: 812
Merit: 388


View Profile
July 17, 2018, 05:07:11 PM
 #18

Moi c'est du chinois, j'y pige que dalle.
Je m'arrête à du bash en programmation et ça me donne déjà pas mal de difficulté.
Alors j'admire ton acharnement Wink
PtiPoulet (OP)
Jr. Member
*
Offline Offline

Activity: 42
Merit: 2

Nothing Really Matters... :)


View Profile
July 18, 2018, 03:52:11 PM
Last edit: July 18, 2018, 04:30:04 PM by PtiPoulet
 #19

Version épurée sans bug de la balance USDT ...bref comme l'ancienne version mais en version mieux  Tongue:

https://github.com/PtiPoulet/PtiPoulet

 Smiley

All we are is dust in the wind !
JollyHash
Full Member
***
Offline Offline

Activity: 322
Merit: 117



View Profile
July 18, 2018, 04:40:08 PM
 #20

Tiens c'est la première fois que je vois un sujet résolu, marqué dans le titre.
Ca pourrait être un amélioration. Surtout pour les demandes d'aide, quand pensez vous ?

◆  ◆  ◆  ◇      P L A Z A      ◇  ◆  ◆  ◆            The Intersection of Lifestyle & Technology
[ WHITEPAPER ]     PRE-SALE Starts  │  March 15th, 2018     [ ANN THREAD ]
TELEGRAM        GITHUB       MEDIUM        YOUTUBE        TWITTER        FLIPBOARD        REDDIT        LINKEDIN        FACEBOOK        EMAIL
Pages: [1] 2 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!