
この記事では 2 つの解決策について説明します。記事の最後に記載されているもう 1 つの解決策はよりシンプルです (推奨)。
Python を使用して戦略を記述する多くの開発者は、戦略コード ファイルをローカルに保存したいと考えていますが、戦略のセキュリティについて懸念しています。としてFMZ API文書で提案されている解決策の 1 つ:
ポリシーセキュリティ Inventor Quantitative 取引プラットフォームで戦略を開発します。戦略は Inventor Quantitative アカウント所有者にのみ表示されます。さらに、Inventor Quantitative Trading Platform では、戦略コードを完全にローカライズできます。たとえば、戦略を Python パッケージにカプセル化して戦略コードに読み込むことで、戦略のローカライズを実現できます。 https://www.fmz.com/api#%E7%AD%96%E7%95%A5%E5%AE%89%E5%85%A8%E6%80%A7
実際にはこれについて心配する必要はありませんが、そのような解決策があるため、完全な実装例が提供されています。
古典的なPythonの戦略を使って、簡単な例を見てみましょう。Dual Thrust戦略、戦略アドレス: https://www.fmz.com/strategy/21856
私たちは戦略コードのいかなる部分も変更しないように努め、戦略を FMZ プラットフォーム上の戦略コードから呼び出すことができるファイルにカプセル化します。実行結果は、戦略を直接実行した場合とまったく同じです。カプセル化の最大の問題は、FMZプラットフォーム上の戦略コードによって呼び出されるグローバルオブジェクト、グローバル関数、および定数値がカプセル化されたファイルではアクセスできないため、これらのオブジェクト、関数、変数を渡す方法を見つける必要があることです。 、定数をカプセル化されたドキュメントに追加します。それでは、段階的に対処していきます。

ローカル エディターで開いたファイル testA に貼り付けます。

# 函数、对象
exchanges = None
exchange = None
Log = None
Sleep = None
TA = None
Chart = None
LogProfitReset = None
LogStatus = None
_N = None
_C = None
LogProfit = None
# 策略参数
ContractTypeIdx = None
MarginLevelIdx = None
NPeriod = None
Ks = None
Kx = None
AmountOP = None
Interval = None
LoopInterval = None
PeriodShow = None
# 常量
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
上記のコードの主な機能は、現在のファイルで使用されるグローバル関数と変数を宣言することです。次に、これらの関数をインポートするためのインターフェースを予約しますSetExchanges,SetParams,SetFunc。 FMZ プラットフォーム上の戦略はこれらの関数を呼び出し、使用された関数やオブジェクトなどを渡します。
スタートアップ戦略は次のように非常にシンプルです。

FMZ プラットフォームに記述されているコードはほんの数行です。この起動戦略のパラメータは、カプセル化する戦略と同じであることに注意してください。Dual Thrust OKCoin Futures の Python バージョンまったく同じです。実際、「Python版Dual Thrust OKCoin Futures」戦略を直接コピーし、戦略コードをクリアして貼り付けることができます。
import sys
# 这里我写的是自己放置testA文件的路径,具体我替换为xxx了,简单说就是设置自己的testA文件路径就可以了
sys.path.append("/Users/xxx/Desktop/pythonPlayground/")
import testA
def main():
# 传递交易所对象
testA.SetExchanges(exchanges)
# 传递全局函数 SetFunc(pLog, pSleep, pTA, pChart, pLogStatus, pLogProfitReset, p_N, p_C, pLogProfit)
testA.SetFunc(Log, Sleep, TA, Chart, LogStatus, LogProfitReset, _N, _C, LogProfit)
# 传递策略参数 SetParams(pContractTypeIdx, pMarginLevelIdx, pNPeriod, pKs, pKx, pAmountOP, pInterval, pLoopInterval, pPeriodShow)
testA.SetParams(ContractTypeIdx, MarginLevelIdx, NPeriod, Ks, Kx, AmountOP, Interval, LoopInterval, PeriodShow)
# 执行封装的testA文件中的策略主函数
testA.main()
このようにして、ポリシーロジック本体をtestAファイルにカプセル化し、ホストのデバイスにローカルに配置します。FMZプラットフォームでは、スタートアップポリシーを1つ保存するだけで済みます。このスタートアップポリシーを作成するロボットは、ローカルファイルを直接読み込むことができます。ホスト上でローカルに実行します。


ファイルを直接ロードして実行します。 今回は「Python版Dual Thrust OKCoin Futures」戦略のコードを配置するtestBファイルを準備します。
import time
class Error_noSupport(BaseException):
def __init__(self):
Log("只支持OKCoin期货!#FF0000")
class Error_AtBeginHasPosition(BaseException):
def __init__(self):
Log("启动时有期货持仓! #FF0000")
ChartCfg = {
'__isStock': True,
'title': {
'text': 'Dual Thrust 上下轨图'
},
'yAxis': {
...
戦略は長すぎるため省略されており、戦略コードを変更する必要はまったくありません。 次に、FMZ プラットフォーム上の戦略である「Dual Thrust OKCoin Futures の Python バージョン (戦略を起動し、testB ファイルを直接実行)」を準備し、ロボットを作成し、testB ファイルを直接ロードして直接実行します。なお、起動戦略も「Python版Dual Thrust OKCoin Futures」のオリジナルバージョンと同じ戦略パラメータ設定(戦略インターフェースパラメータ)にする必要があります。

if __name__ == '__main__':
Log("run...")
try:
# 文件路径做了处理,可以写入自己testB文件放置的实际路径
f = open("/Users/xxx/Desktop/pythonPlayground/testB.py", "r")
code = f.read()
exec(code)
except Exception as e:
Log(e)
バックテストを実行するには:

バックテストの結果は上記のテストと一致しています。
明らかに、上記の 2 番目の方法の方が簡単で推奨されます。より良い方法がある場合は、メッセージを残してください。