Muitos desenvolvedores que escrevem estratégias em Python querem colocar os arquivos de código de estratégia localmente, preocupando-se com a segurança da estratégia.
Segurança estratégica
A estratégia é desenvolvida na plataforma FMZ, e a estratégia é visível apenas para os titulares de contas FMZ. E na plataforma FMZ, o código da estratégia pode ser completamente localizado, por exemplo, a estratégia é encapsulada em um pacote Python e carregada no código da estratégia, de modo que a localização da estratégia seja realizada.
Para mais informações, acesse:https://www.fmz.com/api
De facto, esse tipo de preocupação não é necessário, mas, uma vez que existem tais necessidades, daremos um exemplo completo de aplicação.
Vamos encontrar uma estratégia Python simples para demonstração, usando o clássicoDual Thrust
estratégia, endereço da estratégia:https://www.fmz.com/strategy/21856Nós nos esforçamos para não alterar qualquer parte do código da estratégia, encapsular a estratégia em um arquivo que pode ser chamado pelo código da estratégia na plataforma FMZ, e o resultado da execução é exatamente o mesmo que executar a estratégia diretamente. O maior problema com a encapsulamento é que os objetos globais, funções globais e valores constantes chamados pelo código da estratégia na plataforma FMZ não podem ser acessados nos arquivos que encapsulamos, então devemos encontrar uma maneira de passar esses objetos, funções, variáveis e constantes para o arquivo encapsulado. vamos fazer passo a passo.
testA
.Coloque no arquivotestA
foi aberta pelo editor local.
Adicionar algum código, e manter a parte de código estratégia copiado e colado intacto
# 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
A função principal do código acima é declarar as funções globais e variáveis usadas no arquivo atual.SetExchanges
, SetParams
, SetFunc
As estratégias na plataforma FMZ chamam essas funções e passam algumas funções e objetos usados.
A estratégia de arranque é muito simples, da seguinte forma:
Há apenas algumas linhas de código escritas na plataforma FMZ. Deve-se notar que os parâmetros desta estratégia de inicialização são exatamente os mesmos que a nossa estratégia embaladaVersão Python do código de estratégia de futuros OKCoin Dual ThrustNa verdade, você pode copiar diretamenteVersão Python do código de estratégia de futuros OKCoin Dual ThrustEstratégia, depois limpa o código da estratégia, pega-o.
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()
Deste modo, encapsulamos o corpo principal da lógica estratégica natestA
No FMZ, só precisamos salvar uma estratégia de inicialização. O robô que cria essa estratégia de inicialização pode carregar diretamente nosso arquivo local e executá-lo localmente.
testA
arquivo local para backtestCarregue o arquivo diretamente para execução.
Desta vez preparamos umtestB
Ficheiro com o código para oVersão Python do código de estratégia de futuros OKCoin Dual Thrust 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': {
...
Se a estratégia for demasiado longa, é omitida e o código de estratégia não precisa de ser alterado.
Então, prepare-se.Versão Python do código de estratégia de futuros OKCoin Dual Thrust(iniciar estratégia, executar directamentetestB
Ficheiro), que é a nossa estratégia na plataforma FMZ, criar um robô, carregar diretamente otestB
Ficheiro, e executá-lo diretamente. Deve-se notar que a estratégia de inicialização também deve ter exatamente as mesmas configurações de parâmetros de estratégia (parâmetros de interface de estratégia) que a versão original deVersão Python do código de estratégia de futuros OKCoin Dual Thrust.
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)
Realizar um backtest:
O resultado do backtest é consistente com o teste anterior.
Obviamente, o segundo método acima é mais simples, é recomendado usar.