ProRealTime
Zone de développement des applications API, des logiciels et utilitaires développés par les membres du forum

[PYTHON] Script API IG STREAM + REST

par cimourdain » 14 Sep 2015 21:50

Bonjour à tous,

J'ai pas mal galéré, mais grace au forum j'ai trouvé quelques réponses que je cherchais donc je trouve assez normal de partager mon travail.

remarque préliminaire: je ne suis pas un développeur, je suis ouvert à tout vos commentaires pour améliorer ce qui suit.

Le script ci-dessous permet de lire les cours (API STREAM) et de passer les ordres (API REST) en pyhton.


1 - Téléchargez le script de l'API Stream de FemoTrader
https://github.com/femtotrader/ig-markets-stream-api-python-library
Dézippez le
dans le fichier igls.py, remplacez (ligne 589):
Code: Tout sélectionner
def create_session(self, username, adapter_set, password=None,

par

Code: Tout sélectionner
def create_session_stream(self, username, adapter_set, password=None,


2 - Script de l'API REST
Ci-dessous le script de l'API rest (source: https://github.com/femtotrader/ig-markets-rest-api-python-library), nommez le ig_service_rest.py dans le dossier dans lequel vous avez dézippé le script de l'API STREAM à l'étape précédente

Remarque: le forum censure les insultes, remplacez "(mot censuré merci de rester poli)" par p*d* (sans les étoiles)

Code: Tout sélectionner
#!/usr/bin/env python
#-*- coding:utf-8 -*-

"""
IG Markets REST API Library for Python
http://labs.ig.com/rest-trading-api-reference
By Lewis Barber - 2014 - http://uk.linkedin.com/in/lewisbarber/
"""

import requests
import json
import logging
import traceback
import pandas as (mot censuré merci de rester poli)

class IGService:

    CLIENT_TOKEN = None
    SECURITY_TOKEN = None

    BASIC_HEADERS = None
    LOGGED_IN_HEADERS = None
    DELETE_HEADERS = None

    D_BASE_URL = {
        'live': 'https://api.ig.com/gateway/deal',
        'demo': 'https://demo-api.ig.com/gateway/deal'
    }

    API_KEY = None
    IG_USERNAME = None
    IG_PASSWORD = None

    def __init__(self, username, password, api_key, acc_type="demo"):
        """Constructor, calls the method required to connect to the API (accepts acc_type = LIVE or DEMO)"""
        self.API_KEY = api_key
        self.IG_USERNAME = username
        self.IG_PASSWORD = password

        try:
            self.BASE_URL = self.D_BASE_URL[acc_type.lower()]
        except:
            raise(Exception("Invalid account type specified, please provide LIVE or DEMO."))

        self.BASIC_HEADERS = {
            'X-IG-API-KEY': self.API_KEY,
            'Content-Type': 'application/json',
            'Accept': 'application/json; charset=UTF-8'
        }

        self.parse_response = self.parse_response_with_exception

        self.return_dataframe = True

        #self.create_session()


    ########## PARSE_RESPONSE ##########

    def parse_response_without_exception(self, *args, **kwargs):
        """Parses JSON response
        returns dict
        no exception raised when error occurs"""
        response = json.loads(*args, **kwargs)
        return(response)

    def parse_response_with_exception(self, *args, **kwargs):
        """Parses JSON response
        returns dict
        exception raised when error occurs"""
        response = json.loads(*args, **kwargs)
        if 'errorCode' in response:
            raise(Exception(response['errorCode']))
        return(response)

    ############ END ############


    ########## ACCOUNT ##########

    def fetch_accounts(self):
        """Returns a list of accounts belonging to the logged-in client"""
        response = requests.get(self.BASE_URL + '/accounts', headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['accounts'])
        return(data)

    def fetch_account_activity_by_period(self, milliseconds):
        """Returns the account activity history for the last specified period"""
        response = requests.get(self.BASE_URL + '/history/activity/%s' % milliseconds, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['activities'])
        return(data)

    def fetch_transaction_history_by_type_and_period(self, milliseconds, trans_type):
        """Returns the transaction history for the specified transaction type and period"""
        response = requests.get(self.BASE_URL + '/history/transactions/%s/%s' % (trans_type, milliseconds), headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['transactions'])
        return(data)

    ############ END ############



    ########## DEALING ##########

    def fetch_deal_by_deal_reference(self, deal_reference):
        """Returns a deal confirmation for the given deal reference"""
        response = requests.get(self.BASE_URL + '/confirms/%s' % deal_reference, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)

    def fetch_open_positions(self):
        """Returns all open positions for the active account"""
        response = requests.get(self.BASE_URL  + '/positions', headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        '''
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['positions'])
        '''
        return(data)

    def close_open_position(self, deal_id, direction, epic, expiry, level, order_type, quote_id, size):
        """Closes one or more OTC positions"""
        params = {
            'dealId': deal_id,
            'direction': direction,
            'epic': epic,
            'expiry': expiry,
            'level': level,
            'orderType': order_type,
            'quoteId': quote_id,
            'size': size
        }

        response = requests.post(self.BASE_URL + '/positions/otc', data=json.dumps(params), headers=self.DELETE_HEADERS)

        if response.status_code == 200:
            deal_reference = json.loads(response.text)['dealReference']
            return(self.fetch_deal_by_deal_reference(deal_reference))
        else:
            return(response.text)

    def create_open_position(self, currency_code, direction, epic, expiry, force_open,
        guaranteed_stop, level, limit_distance, limit_level, order_type, quote_id, size,
        stop_distance, stop_level):
        """Creates an OTC position"""
        params = {
            'currencyCode': currency_code,
            'direction': direction,
            'epic': epic,
            'expiry': expiry,
            'forceOpen': force_open,
            'guaranteedStop': guaranteed_stop,
            'level': level,
            'limitDistance': limit_distance,
            'limitLevel': limit_level,
            'orderType': order_type,
            'quoteId': quote_id,
            'size': size,
            'stopDistance': stop_distance,
            'stopLevel': stop_level
        }
        print params
        response = requests.post(self.BASE_URL + '/positions/otc', data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)
        print response
        if response.status_code == 200:
            deal_reference = json.loads(response.text)['dealReference']
            return(self.fetch_deal_by_deal_reference(deal_reference))
        else:
            return(response.text) # parse_response ?

    def update_open_position(self, limit_level, stop_level, deal_id):
        """Updates an OTC position"""
        params = {
            'limitLevel': limit_level,
            'stopLevel': stop_level
        }

        response = requests.put(self.BASE_URL + '/positions/otc/%s' % deal_id, data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)

        if response.status_code == 200:
            deal_reference = json.loads(response.text)['dealReference']
            return(self.fetch_deal_by_deal_reference(deal_reference))
        else:
            return(response.text) # parse_response ?

    def fetch_working_orders(self):
        """Returns all open working orders for the active account"""
        response = requests.get(self.BASE_URL  + '/workingorders', headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['workingOrders'])
        return(data)

    def create_working_order(self, currency_code, direction, epic, expiry, good_till_date,
        guaranteed_stop, level, limit_distance, limit_level, size, stop_distance, stop_level,
        time_in_force, order_type):
        """Creates an OTC working order"""
        params = {
            'currencyCode': currency_code,
            'direction': direction,
            'epic': epic,
            'expiry': expiry,
            'goodTillDate': good_till_date,
            'guaranteedStop': guaranteed_stop,
            'level': level,
            'limitDistance': limit_distance,
            'limitLevel': limit_level,
            'size': size,
            'stopDistance': stop_distance,
            'stopLevel': stop_level,
            'timeInForce': time_in_force,
            'type': order_type
        }

        response = requests.post(self.BASE_URL + '/workingorders/otc', data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)

        if response.status_code == 200:
            deal_reference = json.loads(response.text)['dealReference']
            return(self.fetch_deal_by_deal_reference(deal_reference))
        else:
            return(response.text) # parse_response ?

    def delete_working_order(self, deal_id):
        """Deletes an OTC working order"""
        response = requests.post(self.BASE_URL + '/workingorders/otc/%s' % deal_id, data=json.dumps({}), headers=self.DELETE_HEADERS)

        if response.status_code == 200:
            deal_reference = json.loads(response.text)['dealReference']
            return(self.fetch_deal_by_deal_reference(deal_reference))
        else:
            return(response.text) # parse_response ?

    def update_working_order(self, good_till_date, level, limit_distance, limit_level,
        stop_distance, stop_level, time_in_force, order_type, deal_id):
        """Updates an OTC working order"""
        params = {
            'goodTillDate': good_till_date,
            'limitDistance': limit_distance,
            'level': level,
            'limitLevel': limit_level,
            'stopDistance': stop_distance,
            'stopLevel': stop_level,
            'timeInForce': time_in_force,
            'type': order_type
        }

        response = requests.put(self.BASE_URL + '/workingorders/otc/%s' % deal_id, data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)

        if response.status_code == 200:
            deal_reference = json.loads(response.text)['dealReference']
            return(self.fetch_deal_by_deal_reference(deal_reference))
        else:
            return(response.text) # parse_response ?

    ############ END ############



    ########## MARKETS ##########

    def fetch_client_sentiment_by_instrument(self, market_id):
        """Returns the client sentiment for the given instrument's market"""
        response = requests.get(self.BASE_URL + '/clientsentiment/%s' % market_id, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)

    def fetch_related_client_sentiment_by_instrument(self, market_id):
        """Returns a list of related (also traded) client sentiment for the given instrument's market"""
        response = requests.get(self.BASE_URL + '/clientsentiment/related/%s' % market_id, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['clientSentiments'])
        return(data)

    def fetch_top_level_navigation_nodes(self):
        """Returns all top-level nodes (market categories) in the market navigation hierarchy."""
        response = requests.get(self.BASE_URL + '/marketnavigation', headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data['markets'] = (mot censuré merci de rester poli).DataFrame(data['markets'])
            data['nodes'] = (mot censuré merci de rester poli).DataFrame(data['nodes'])
        return(data)

    def fetch_sub_nodes_by_node(self, node):
        """Returns all sub-nodes of the given node in the market navigation hierarchy"""
        response = requests.get(self.BASE_URL + '/marketnavigation/%s' % node, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data['markets'] = (mot censuré merci de rester poli).DataFrame(data['markets'])
            data['nodes'] = (mot censuré merci de rester poli).DataFrame(data['nodes'])
        return(data)

    def fetch_market_by_epic(self, epic):
        """Returns the details of the given market"""
        response = requests.get(self.BASE_URL + '/markets/%s' % epic, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)

    def search_markets(self, search_term):
        """Returns all markets matching the search term"""
        response = requests.get(self.BASE_URL + '/markets?searchTerm=%s' % search_term, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['markets'])
        return(data)

    def fetch_historical_prices_by_epic_and_date_range(self, epic, resolution, start_date, end_date):
        """Returns a list of historical prices for the given epic, resolution, multiplier and date range"""
        response = requests.get(self.BASE_URL + "/prices/{epic}/{resolution}/?startdate={start_date}&enddate={end_date}".format(epic=epic, resolution=resolution, start_date=start_date, end_date=end_date), headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data['prices'] = (mot censuré merci de rester poli).DataFrame(data['prices'])
        return(data)

    ############ END ############



    ######### WATCHLISTS ########

    def fetch_all_watchlists(self):
        """Returns all watchlists belonging to the active account"""
        response = requests.get(self.BASE_URL + '/watchlists', headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['watchlists'])
        return(data)

    def create_watchlist(self, name, epics):
        """Creates a watchlist"""
        params = {
            'name': name,
            'epics': epics
        }

        response = requests.post(self.BASE_URL + '/watchlists', data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)

    def delete_watchlist(self, watchlist_id):
        """Deletes a watchlist"""
        response = requests.post(self.BASE_URL + '/watchlists/%s' % watchlist_id, data=json.dumps({}), headers=self.DELETE_HEADERS)
        return(response.text)


    def fetch_watchlist_markets(self, watchlist_id):
        """Returns the given watchlist's markets"""
        response = requests.get(self.BASE_URL + '/watchlists/%s' % watchlist_id, headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        if self.return_dataframe:
            data = (mot censuré merci de rester poli).DataFrame(data['markets'])
        return(data)


    def add_market_to_watchlist(self, watchlist_id, epic):
        """Adds a market to a watchlist"""
        params = {
            'epic': epic
        }

        response = requests.put(self.BASE_URL + '/watchlists/%s' % watchlist_id, data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)

    def remove_market_from_watchlist(self, watchlist_id, epic):
        """Remove an market from a watchlist"""
        response = requests.post(self.BASE_URL + '/watchlists/%s/%s' % (watchlist_id, epic), data=json.dumps({}), headers=self.DELETE_HEADERS)
        return(response.text)

    ############ END ############



    ########### LOGIN ###########

    def logout(self):
        """Log out of the current session"""
        requests.post(self.BASE_URL + '/session', data=json.dumps({}), headers=self.DELETE_HEADERS)

    def create_session(self):
        """Creates a trading session, obtaining session tokens for subsequent API access"""
        params = {
            'identifier': self.IG_USERNAME,
            'password': self.IG_PASSWORD
        }

        response = requests.post(self.BASE_URL  + '/session', data=json.dumps(params), headers=self.BASIC_HEADERS)
        self._set_headers(response.headers, True)
        data = self.parse_response(response.text)
        return(data)

    def switch_account(self, account_id, default_account):
        """Switches active accounts, optionally setting the default account"""
        params = {
            'accountId': account_id,
            'defaultAccount': default_account
        }

        response = requests.put(self.BASE_URL + '/session', data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)
        self._set_headers(response.headers, False)
        data = self.parse_response(response.text)
        return(data)

    ############ END ############



    ########## GENERAL ##########
   
    def get_client_apps(self):
        """Returns a list of client-owned applications"""
        response = requests.get(self.BASE_URL + '/operations/application', headers=self.LOGGED_IN_HEADERS)

        return self.parse_response(response.text)

    def update_client_app(self, allowance_account_overall, allowance_account_trading, api_key, status):
        """Updates an application"""
        params = {
            'allowanceAccountOverall': allowance_account_overall,
            'allowanceAccountTrading': allowance_account_trading,
            'apiKey': api_key,
            'status': status
        }

        response = requests.put(self.BASE_URL + '/operations/application', data=json.dumps(params), headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)

    def disable_client_app_key(self):
        """Disables the current application key from processing further requests.
        Disabled keys may be reenabled via the My Account section on the IG Web Dealing Platform."""
        response = requests.put(self.BASE_URL + '/operations/application/disable', data=json.dumps({}), headers=self.LOGGED_IN_HEADERS)
        data = self.parse_response(response.text)
        return(data)
       
    ############ END ############



    ########## PRIVATE ##########

    def _set_headers(self, response_headers, update_cst):
        """Sets headers"""
        if update_cst == True:
            self.CLIENT_TOKEN = response_headers['CST']

        try:
            self.SECURITY_TOKEN = response_headers['X-SECURITY-TOKEN']
        except:
            self.SECURITY_TOKEN = None

        self.LOGGED_IN_HEADERS = {
            'X-IG-API-KEY': self.API_KEY,
            'X-SECURITY-TOKEN': self.SECURITY_TOKEN,
            'CST': self.CLIENT_TOKEN,
            'Content-Type': 'application/json',
            'Accept': 'application/json; charset=UTF-8'
        }

        self.DELETE_HEADERS = {
            'X-IG-API-KEY': self.API_KEY,
            'X-SECURITY-TOKEN': self.SECURITY_TOKEN,
            'CST': self.CLIENT_TOKEN,
            'Content-Type': 'application/json',
            'Accept': 'application/json; charset=UTF-8',
            '_method': 'DELETE'
        }

    ############ END ############


3 - Editez le fichier sample.py pour y mettre le contenu suivant:
Code: Tout sélectionner
#!/usr/bin/env python
#-*- coding:utf-8 -*-

# IG API Trader

import igls,requests,json, time
from trading_ig_config import config

from ig_service_rest import IGService
#from ig_service_config import * # defines username, password, api_key, acc_type, acc_number
import pandas as (mot censuré merci de rester poli)



global position
position = {
    "epic": "IX.D.DAX.IMF.IP",
    "expiry": "-",
    "direction": "SELL",
    "size": "1",
    "orderType": "MARKET",
    "timeInForce": None,
    "level": None,
    "guaranteedStop": "false",
    "stopLevel": None,
    "stopDistance": "10",
    "trailingStop": None,
    "trailingStopIncrement": None,
    "forceOpen": "true",
    "limitLevel": None,
    "limitDistance": "10",
    "quoteId": None,
    "currencyCode": "EUR"
    }


if config.acc_type.upper() == "DEMO":
    BASEURL = 'https://demo-api.ig.com/gateway/deal'
elif config.acc_type.upper() == "LIVE":
    BASEURL = 'https://api.ig.com/gateway/deal'
else:
    raise(NotImplementedError("acc_type is %r but it should be either 'DEMO' or 'LIVE'" % config.acc_type))

headers = {
    'content-type': 'application/json; charset=UTF-8',
    'Accept': 'application/json; charset=UTF-8',
    'X-IG-API-KEY': config.api_key
}

payload = {
    'identifier': config.username,
    'password': config.password
}

# Tell the user when the Lighstreamer connection state changes
def on_state(state):
    print('New state:', state)
    igls.LOG.debug("New state: %s" % state)

   
'''
Fonction pour ajouter une forme à la liste des formes
'''
def AddShape(shape, ratio, list):
    ratio = RestricRatio(ratio)
    ratio = round(ratio, 2)
    if ratio == 99:
        print list
    if list == []:
        list.append([shape, ratio])
    elif list[-1] <> [shape, ratio]:
        list.append([shape, ratio])
    return list

'''
Fonction pour identifier le ratio de la mèche selon un découpage Fibonacci
'''
def RestricRatio(ratio):
    #23,6%, 38,2%, 50%, 61,8% et 78,6%.
    new_ratio = 0
    if ratio == 0:
        new_ratio = 0
    elif ratio > 0 and ratio <= 0.236:
        new_ratio = 1
    elif ratio > 0.236 and ratio <= 0.382:
        new_ratio = 2
    elif ratio > 0.382 and ratio <= 0.5:
        new_ratio = 3
    elif ratio > 0.5 and ratio <= 0.618:
        new_ratio = 4
    elif ratio > 0.618 and ratio <= 0.786:
        new_ratio = 5
    elif ratio > 0.786 and ratio <=1 :
        new_ratio = 10
    elif ratio > 1:
        new_ratio = 20
    else :
        new_ratio = 99
    return new_ratio
   
# Process a lighstreamer price update
def processPriceUpdate(item, myUpdateField):
    ig_service.LOGGED_IN_HEADERS['version'] = '2'
   
    #Affichage du nouveau tick
    curr_time = "2015-09-09 " + myUpdateField[0]
    curr_time = time.strptime(curr_time, "%Y-%m-%d %H:%M:%S")
    buy_price = float(myUpdateField[2])
    sell_price = float(myUpdateField[1])
    curr_price = (buy_price - sell_price)/2 + sell_price

    print 'time:', time.strftime("%H:%M:%S", curr_time),': ',  str(curr_price)

    #Ouverture d'une position SELL
    position['direction'] = "SELL"
    r2 = requests.post(ig_service.BASE_URL + '/positions/otc', data=json.dumps(position), headers=ig_service.LOGGED_IN_HEADERS)
    r3 = ig_service.fetch_open_positions()
    deal_id = r3['positions'][0]['position']['dealId']
    print "Position ouverte avec le deal ID :", deal_id
   
    #fermeture d'une position
    close_sens = "BUY"
    ig_service.close_open_position( deal_id , close_sens, None, None, None, "MARKET", None, "1")


# Process an update of the users trading account balance
def processBalanceUpdate(item, myUpdateField):
    print("balance update = %s" % myUpdateField)

if __name__ == '__main__':
    '''
    STREAM SESSION
    '''
    url = BASEURL + "/session"
    r = requests.post(url, data=json.dumps(payload), headers=headers, verify=False)
    print "r:", r
    cst = r.headers['CST']
    xsecuritytoken = r.headers['x-security-token']
    fullheaders = {
        'content-type': 'application/json; charset=UTF-8',
        'Accept': 'application/json; charset=UTF-8',
        'X-IG-API-KEY': config.api_key,
        'CST': cst,
        'X-SECURITY-TOKEN': xsecuritytoken
    }

    body = r.json()
    lightstreamerEndpoint = body[u'lightstreamerEndpoint']
    clientId = body[u'clientId']
    accounts = body[u'accounts']

    # Depending on how many accounts you have with IG the '0' may need to change to select the correct one (spread bet, cfd à risque limité account etc)
    accountId = accounts[0][u'accountId']

    client = igls.LsClient(lightstreamerEndpoint+"/lightstreamer/")
    client.on_state.listen(on_state)
    client.create_session_stream(username=accountId, password='CST-'+cst+'|XST-'+xsecuritytoken, adapter_set='')

    priceTable = igls.Table(client,
        mode=igls.MODE_MERGE,
        item_ids='L1:IX.D.DAX.IMF.IP',#'L1:CS.D.GBPUSD.cfd à risque limité.IP',
        schema='UPDATE_TIME BID OFFER CHANGE MARKET_STATE',
        item_factory=lambda row: tuple(float(v) for v in row)
    )

    priceTable.on_update.listen(processPriceUpdate)
    '''
    REST SESSION
    '''
    ig_service = IGService(config.username, config.password, config.api_key, config.acc_type)
    print ig_service.create_session()

    balanceTable = igls.Table(client,
        mode=igls.MODE_MERGE,
        item_ids='ACCOUNT:'+accountId,
        schema='AVAILABLE_CASH',
        item_factory=lambda row: tuple(string(v) for v in row))

    balanceTable.on_update.listen(processBalanceUpdate)


    while True:
        time.sleep(10)
 


Positionnez votre stratégie dans la fonction processPriceUpdate

Identifiants
Enfin, entrez vos identifants dans le fichier trading_ig_config.py

Lancez le tout avec la commande suivante:

Code: Tout sélectionner
python sample.py


Voila voila comment je m'en suis sorti, j'espère que ça pourra en aider certains.

Re: [PYTHON] Script API IG STREAM + REST

par Benoist Rousseau » 14 Sep 2015 22:13

Merci à toi juste préciser que le forum remplace des mots automatiquement pour éviter les injures donc ça a modifier le code

Il faut regarder le code et quand il y a
import pandas as (mot censuré merci de rester poli)

ce mot est sans Astérix p*d*

Re: [PYTHON] Script API IG STREAM + REST

par cimourdain » 15 Sep 2015 10:05

merci j'avais pas vu, j'ai rajouté la remarque dans mon premier post

Re: [PYTHON] Script API IG STREAM + REST

par Benoist Rousseau » 16 Sep 2015 00:11

j'ai vérifié ton code, je suis tombé dessus ;)

Re: [PYTHON] Script API IG STREAM + REST

par FemtoTrader » 30 Sep 2015 09:51

Bonjour,

ça fait toujours plaisir de savoir que mon code est utilisé par des francophones !

N'hésitez pas à contribuer sur GitHub.

Pour l'API REST
https://github.com/femtotrader/ig-markets-rest-api-python-library

Pour l'API Stream
https://github.com/femtotrader/ig-markets-stream-api-python-library

Cordialement

Re: [PYTHON] Script API IG STREAM + REST

par falex » 30 Sep 2015 10:24

Tiens te voilà !

Re: [PYTHON] Script API IG STREAM + REST

par beni » 30 Sep 2015 10:26

Salut femto !

Il est même largement utilisé ! En tout cas par moi :mrgreen:

Un grand merci à toi, sans ça je crois que je ne me serai jamais lancé :mercichinois:

Re: [PYTHON] Script API IG STREAM + REST

par falex » 30 Sep 2015 10:37

Suite à la correction d'IGLS sur le flux Ls en mode "silent", je n'ai jamais réussi avec les serveurs d'IG. Chaque fois je n'avais aucun ticks, donc soit j'ai crien compris au fonctionnement du silent, soit ...

Re: [PYTHON] Script API IG STREAM + REST

par FemtoTrader » 30 Sep 2015 10:41

N'hésitez pas à améliorer les 2 bibliothèques

Elles sont désormais dans une organisation

https://github.com/ig-python

dont le but est d'utiliser l'API REST et Stream de IG à l'aide du langage Python

https://github.com/ig-python/ig-markets-rest-api-python-library
https://github.com/ig-python/ig-markets-stream-api-python-library


Forkez, faites une branche qui permet d'améliorer ou corriger une seule chose
Faites des Pull Request pour pouvoir fusionner ces améliorations.
Une fois la modif fusionnée vous pouvez supprimer la branche.
et synchoniser votre fork.

ça sera quand même beaucoup plus clair que faire des modif dans un forum.

Si vous ne connaissez pas trop git je peux aider.

La bibliothèque Stream pour l'instant ne tourne qu'avec Python 2 pas Python 3
c'est un point qu'il faut aussi améliorer.
https://github.com/Weswit/Lightstreamer-example-StockList-client-python permet désormais de
tourner avec Python 3 (depuis quelques jours) donc on doit pouvoir identifier ce qui coince

Est-ce que ceux qui ont trouvé des choses à faire sur les 2 libs peuvent les résumer ici et me donner leur nom d'utilisateur GitHub ?

Merci

Re: [PYTHON] Script API IG STREAM + REST

par falex » 30 Sep 2015 10:53

Avec béni on a un poil changé igks pour remonter une information supplémentaire à chaque message reçu : l'epic.

Typiquement dans la L3 si tu as des positions sur plusieurs sous-jacent, il était impossible de savoir quel ticks appartient à qui.

Nouveau code :
Code: Tout sélectionner
def _dispatch_update(self, item_id, item):
        """Called by LsClient to dispatch a table update line."""
        if item == 'EOS':
            self.on_end_of_snapshot.fire()
            return
        last = dict(enumerate(self._last_item_map.get(item_id, [])))
        fields = [_decode_field(s, last.get(i)) for i, s in enumerate(item)]
        self._last_item_map[item_id] = fields
        #self.items[item_id] = self.item_factory(fields)
        #self.on_update.fire(item_id, self.items[item_id])


        self.on_update.fire(item_id, fields, self.item_ids)


Seule la dernière ligne a été modifié avec l'ajout d'un champ self.item_ids dans le retour

Articles en relation
API REST / STREAM
Fichier(s) joint(s) par FemtoTrader » 22 Sep 2014 10:35 (201 Réponses)
LS_snapshot (stream)
par swingwin » 22 Sep 2015 21:57 (12 Réponses)
REST , maj
par swingwin » 21 Aoû 2015 18:23 (3 Réponses)
IG API : Augmentation du nombre de requet REST
par falex » 04 Aoû 2016 10:31 (9 Réponses)
ig rest api - heure des ouvertures et clotures quotidiennes
par falex » 22 Avr 2015 14:50 (3 Réponses)
telechargement l3 version 2.2 ou 2.2.1 python only
par musicae » 17 Déc 2015 20:16 (0 Réponses)
Python : IDE && interface graphique
par falex » 08 Aoû 2016 22:08 (3 Réponses)
[Python] - Gestion des (flux de) données
par GTO » 14 Aoû 2016 15:20 (0 Réponses)
Récupérer les cours avec l'API IG Market et Python
par layzard » 24 Juil 2016 12:09 (54 Réponses)
IG python : distinguer working order - position en cours
Fichier(s) joint(s) par Nomade » 11 Déc 2017 19:14 (6 Réponses)

ProRealTime

Alors partagez-le 5 fois c'est bon pour la santé