Apprendre à encapsuler une stratégie Python dans un fichier local

Auteur:La bonté, Créé: 2020-07-09 10:21:31, Mis à jour: 2023-10-28 15:28:00

img

Beaucoup de développeurs qui écrivent des stratégies en Python veulent mettre les fichiers de code de stratégie localement, s'inquiétant de la sécurité de la stratégie.

Sécurité stratégique

La stratégie est développée sur la plateforme FMZ, et la stratégie n'est visible que par les titulaires de compte FMZ. Et sur la plateforme FMZ, le code de la stratégie peut être complètement localisé, par exemple, la stratégie est encapsulée dans un paquet Python et chargée dans le code de la stratégie, de sorte que la localisation de la stratégie soit réalisée.

Pour plus de détails, veuillez consulter:https://www.fmz.com/api

En fait, ce genre d'inquiétude n'est pas nécessaire, mais comme il y a de tels besoins, nous allons fournir un exemple complet de mise en œuvre.

Encapsuler une stratégie

Trouvons une stratégie Python simple pour la démonstration, en utilisant le classiqueDual Thruststratégie, adresse de la stratégie:https://www.fmz.com/strategy/21856Nous nous efforçons de ne modifier aucune partie du code de stratégie, d'encapsuler la stratégie dans un fichier qui peut être appelé par le code de stratégie sur la plate-forme FMZ, et le résultat d'exécution est exactement le même que d'exécuter la stratégie directement. Le plus gros problème avec l'encapsulation est que les objets globaux, les fonctions globales et les valeurs constantes appelées par le code de stratégie sur la plate-forme FMZ ne peuvent pas être accessibles dans les fichiers que nous encapsulons, nous devons donc trouver un moyen de transmettre ces objets, fonctions, variables et constantes au fichier encapsulé. faisons-le étape par étape.

img

Coller dans le fichiertestAouverte par l'éditeur local.

img

Ajouter un peu de code, et garder la partie de code de stratégie copié et collé intact

# Function, object
exchanges = None
exchange = None
Log = None
Sleep = None
TA = None
Chart = None
LogProfitReset = None
LogStatus = None
_N = None
_C = None 
LogProfit = None  


# Strategy parameters
ContractTypeIdx = None
MarginLevelIdx = None
NPeriod = None
Ks = None
Kx = None
AmountOP = None
Interval = None
LoopInterval = None
PeriodShow = None  

# constant
ORDER_STATE_PENDING = 0
ORDER_STATE_CLOSED = 1
ORDER_STATE_CANCELED = 2
ORDER_STATE_UNKNOWN = 3
ORDER_TYPE_BUY = 0 
ORDER_TYPE_SELL = 1
PD_LONG = 0
PD_SHORT = 1  


def SetExchanges(es):
    global exchanges, exchange
    exchanges = es
    exchange = es[0]  

def SetFunc(pLog, pSleep, pTA, pChart, pLogStatus, pLogProfitReset, p_N, p_C, pLogProfit):
    global Log, Sleep, TA, Chart, LogStatus, LogProfitReset, _N, _C, LogProfit
    Log = pLog
    Sleep = pSleep
    TA = pTA
    Chart = pChart
    LogStatus = pLogStatus
    LogProfitReset = pLogProfitReset
    _N = p_N
    _C = p_C
    LogProfit = pLogProfit  

def SetParams(pContractTypeIdx, pMarginLevelIdx, pNPeriod, pKs, pKx, pAmountOP, pInterval, pLoopInterval, pPeriodShow):
    global ContractTypeIdx, MarginLevelIdx, NPeriod, Ks, Kx, AmountOP, Interval, LoopInterval, PeriodShow
    ContractTypeIdx = pContractTypeIdx
    MarginLevelIdx = pMarginLevelIdx
    NPeriod = pNPeriod
    Ks = pKs
    Kx = pKx
    AmountOP = pAmountOP
    Interval = pInterval
    LoopInterval = pLoopInterval
    PeriodShow = pPeriodShow

La fonction principale du code ci-dessus est de déclarer les fonctions globales et les variables utilisées dans le fichier en cours.SetExchanges, SetParams, SetFuncLes stratégies sur la plateforme FMZ appellent ces fonctions et passent par-dessus certaines fonctions et objets utilisés.

Stratégie de démarrage sur la plateforme FMZ

La stratégie de démarrage est très simple, comme suit:

img

Il n'y a que quelques lignes de code écrites sur la plateforme FMZ. Il convient de noter que les paramètres de cette stratégie de démarrage sont exactement les mêmes que notre stratégie emballéeVersion Python du code de stratégie à terme OKCoin à double pousséeEn fait, vous pouvez copier directementVersion Python du code de stratégie à terme OKCoin à double pousséeStratégie, alors effacez le code de stratégie, collez-le.

import sys
# Here I wrote the path where I put the testA file myself. I replaced it with xxx. To put it simply, I set the path of my testA file.
sys.path.append("/Users/xxx/Desktop/pythonPlayground/")
import testA

def main():
    # Passing Exchange Object
    testA.SetExchanges(exchanges)
    # Pass global function SetFunc(pLog, pSleep, pTA, pChart, pLogStatus, pLogProfitReset, p_N, p_C, pLogProfit)
    testA.SetFunc(Log, Sleep, TA, Chart, LogStatus, LogProfitReset, _N, _C, LogProfit)
    # Passing strategy parameters SetParams(pContractTypeIdx, pMarginLevelIdx, pNPeriod, pKs, pKx, pAmountOP, pInterval, pLoopInterval, pPeriodShow)
    testA.SetParams(ContractTypeIdx, MarginLevelIdx, NPeriod, Ks, Kx, AmountOP, Interval, LoopInterval, PeriodShow)
    # Execute the main strategy function in the encapsulated testA file
    testA.main()

De cette façon, nous encapsulons le corps principal de la logique stratégique dans letestALe robot qui crée cette stratégie de démarrage peut directement charger notre fichier local et l'exécuter localement.

Comparaison par contre-test

  • Charge du véhiculetestAfichier local pour le backtest

img

  • Stratégie originale, backtesting sur le serveur public

img

Une autre façon plus simple

Chargez le fichier directement pour l'exécution. Cette fois, nous préparons untestBfichier avec le code de laVersion Python du code de stratégie à terme OKCoin à double poussée strategy.

import time
class Error_noSupport(BaseException):
    def __init__(self):
        Log("Only OKCoin futures are supported!#FF0000")

class Error_AtBeginHasPosition(BaseException):
    def __init__(self):
        Log("There is a futures position at startup!#FF0000")

ChartCfg = {
    '__isStock': True,
    'title': {
        'text': 'Dual Thrust Top and bottom rail map'
    },
    'yAxis': {

...

Si la stratégie est trop longue, elle est omise et le code de stratégie n'a pas besoin d'être modifié.

Alors préparez-vous.Version Python du code de stratégie à terme OKCoin à double poussée(démarrer la stratégie, exécuter directementtestBNous avons créé un robot, chargé directement letestBIl convient de noter que la stratégie de démarrage doit également avoir exactement les mêmes paramètres de paramètres de stratégie (paramètres d'interface de stratégie) que la version originale deVersion Python du code de stratégie à terme OKCoin à double poussée.

img

if __name__ == '__main__':
    Log("run...")
    try:
        # The file path is processed, you can write the actual path of your testB file
        f = open("/Users/xxx/Desktop/pythonPlayground/testB.py", "r")
        code = f.read()
        exec(code)
    except Exception as e:
        Log(e)

Effectuer un backtest:

img

Le résultat du backtest est conforme à celui du test ci-dessus.

Il est évident que la deuxième méthode ci-dessus est plus simple, elle est recommandée.


Plus de